fix corner case in `unused` (#5225)
[UglifyJS.git] / test / compress / drop-unused.js
1 unused_funarg_1: {
2     options = {
3         keep_fargs: false,
4         unused: true,
5     }
6     input: {
7         console.log(function f(a, b, c, d, e) {
8             return a + b;
9         }(14, 28));
10     }
11     expect: {
12         console.log(function(a, b) {
13             return a + b;
14         }(14, 28));
15     }
16     expect_stdout: "42"
17 }
18
19 unused_funarg_2: {
20     options = {
21         keep_fargs: false,
22         unused: true,
23     }
24     input: {
25         console.log(function f(a, b, c, d, e) {
26             return a + c;
27         }(14, 21, 28));
28     }
29     expect: {
30         console.log(function(a, c) {
31             return a + c;
32         }(14, 28));
33     }
34     expect_stdout: "42"
35 }
36
37 unused_nested_function: {
38     options = {
39         unused: true,
40     }
41     input: {
42         function f(x, y) {
43             function g() {
44                 something();
45             }
46             return x + y;
47         }
48     };
49     expect: {
50         function f(x, y) {
51             return x + y;
52         }
53     }
54 }
55
56 unused_circular_references_1: {
57     options = {
58         unused: true,
59     }
60     input: {
61         function f(x, y) {
62             // circular reference
63             function g() {
64                 return h();
65             }
66             function h() {
67                 return g();
68             }
69             return x + y;
70         }
71     };
72     expect: {
73         function f(x, y) {
74             return x + y;
75         }
76     }
77 }
78
79 unused_circular_references_2: {
80     options = {
81         unused: true,
82     }
83     input: {
84         function f(x, y) {
85             var foo = 1, bar = baz, baz = foo + bar, qwe = moo();
86             return x + y;
87         }
88     };
89     expect: {
90         function f(x, y) {
91             moo();              // keeps side effect
92             return x + y;
93         }
94     }
95 }
96
97 unused_circular_references_3: {
98     options = {
99         unused: true,
100     }
101     input: {
102         function f(x, y) {
103             var g = function() { return h() };
104             var h = function() { return g() };
105             return x + y;
106         }
107     };
108     expect: {
109         function f(x, y) {
110             return x + y;
111         }
112     }
113 }
114
115 unused_keep_setter_arg: {
116     options = {
117         unused: true,
118     }
119     input: {
120         var x = {
121             _foo: null,
122             set foo(val) {
123             },
124             get foo() {
125                 return this._foo;
126             }
127         }
128     }
129     expect: {
130         var x = {
131             _foo: null,
132             set foo(val) {
133             },
134             get foo() {
135                 return this._foo;
136             }
137         }
138     }
139 }
140
141 unused_var_in_catch: {
142     options = {
143         unused: true,
144     }
145     input: {
146         function foo() {
147             try {
148                 foo();
149             } catch (ex) {
150                 var x = 10;
151             }
152         }
153     }
154     expect: {
155         function foo() {
156             try {
157                 foo();
158             } catch (ex) {}
159         }
160     }
161 }
162
163 used_var_in_catch: {
164     options = {
165         unused: true,
166     }
167     input: {
168         function foo() {
169             try {
170                 foo();
171             } catch (ex) {
172                 var x = 10;
173             }
174             return x;
175         }
176     }
177     expect: {
178         function foo() {
179             try {
180                 foo();
181             } catch (ex) {
182                 var x = 10;
183             }
184             return x;
185         }
186     }
187 }
188
189 keep_fnames: {
190     options = {
191         keep_fnames: true,
192         unsafe: true,
193         unused: true,
194     }
195     input: {
196         function foo() {
197             return function bar(baz) {};
198         }
199     }
200     expect: {
201         function foo() {
202             return function bar(baz) {};
203         }
204     }
205 }
206
207 drop_assign: {
208     options = {
209         unused: true,
210     }
211     input: {
212         function f1() {
213             var a;
214             a = 1;
215         }
216         function f2() {
217             var a = 1;
218             a = 2;
219         }
220         function f3(a) {
221             a = 1;
222         }
223         function f4() {
224             var a;
225             return a = 1;
226         }
227         function f5() {
228             var a;
229             return function() {
230                 a = 1;
231             };
232         }
233     }
234     expect: {
235         function f1() {
236             1;
237         }
238         function f2() {
239             2;
240         }
241         function f3(a) {
242             1;
243         }
244         function f4() {
245             return 1;
246         }
247         function f5() {
248             return function() {
249                 1;
250             };
251         }
252     }
253 }
254
255 keep_assign: {
256     options = {
257         unused: "keep_assign",
258     }
259     input: {
260         function f1() {
261             var a;
262             a = 1;
263         }
264         function f2() {
265             var a = 1;
266             a = 2;
267         }
268         function f3(a) {
269             a = 1;
270         }
271         function f4() {
272             var a;
273             return a = 1;
274         }
275         function f5() {
276             var a;
277             return function() {
278                 a = 1;
279             };
280         }
281     }
282     expect: {
283         function f1() {
284             var a;
285             a = 1;
286         }
287         function f2() {
288             var a = 1;
289             a = 2;
290         }
291         function f3(a) {
292             a = 1;
293         }
294         function f4() {
295             var a;
296             return a = 1;
297         }
298         function f5() {
299             var a;
300             return function() {
301                 a = 1;
302             };
303         }
304     }
305 }
306
307 drop_toplevel_funcs: {
308     options = {
309         toplevel: "funcs",
310         unused: true,
311     }
312     input: {
313         var a, b = 1, c = g;
314         function f(d) {
315             return function() {
316                 c = 2;
317             };
318         }
319         a = 2;
320         function g() {}
321         function h() {}
322         console.log(b = 3);
323     }
324     expect: {
325         var a, b = 1, c = g;
326         a = 2;
327         function g() {}
328         console.log(b = 3);
329     }
330 }
331
332 drop_toplevel_vars: {
333     options = {
334         toplevel: "vars",
335         unused: true,
336     }
337     input: {
338         var a, b = 1, c = g;
339         function f(d) {
340             return function() {
341                 c = 2;
342             };
343         }
344         a = 2;
345         function g() {}
346         function h() {}
347         console.log(b = 3);
348     }
349     expect: {
350         function f(d) {
351             return function() {
352                 2;
353             };
354         }
355         2;
356         function g() {}
357         function h() {}
358         console.log(3);
359     }
360 }
361
362 drop_toplevel_all: {
363     options = {
364         toplevel: true,
365         unused: true,
366     }
367     input: {
368         var a, b = 1, c = g;
369         function f(d) {
370             return function() {
371                 c = 2;
372             };
373         }
374         a = 2;
375         function g() {}
376         function h() {}
377         console.log(b = 3);
378     }
379     expect: {
380         2;
381         console.log(3);
382     }
383 }
384
385 drop_toplevel_retain: {
386     options = {
387         top_retain: "f,a,o",
388         unused: true,
389     }
390     input: {
391         var a, b = 1, c = g;
392         function f(d) {
393             return function() {
394                 c = 2;
395             };
396         }
397         a = 2;
398         function g() {}
399         function h() {}
400         console.log(b = 3);
401     }
402     expect: {
403         var a;
404         function f(d) {
405             return function() {
406                 2;
407             };
408         }
409         a = 2;
410         console.log(3);
411     }
412 }
413
414 drop_toplevel_retain_array: {
415     options = {
416         top_retain: [
417             "f",
418             "a",
419             "o"
420         ],
421         unused: true,
422     }
423     input: {
424         var a, b = 1, c = g;
425         function f(d) {
426             return function() {
427                 c = 2;
428             };
429         }
430         a = 2;
431         function g() {}
432         function h() {}
433         console.log(b = 3);
434     }
435     expect: {
436         var a;
437         function f(d) {
438             return function() {
439                 2;
440             };
441         }
442         a = 2;
443         console.log(3);
444     }
445 }
446
447 drop_toplevel_retain_regex: {
448     options = {
449         top_retain: /^[fao]$/,
450         unused: true,
451     }
452     input: {
453         var a, b = 1, c = g;
454         function f(d) {
455             return function() {
456                 c = 2;
457             };
458         }
459         a = 2;
460         function g() {}
461         function h() {}
462         console.log(b = 3);
463     }
464     expect: {
465         var a;
466         function f(d) {
467             return function() {
468                 2;
469             };
470         }
471         a = 2;
472         console.log(3);
473     }
474 }
475
476 drop_toplevel_all_retain: {
477     options = {
478         top_retain: "f,a,o",
479         toplevel: true,
480         unused: true,
481     }
482     input: {
483         var a, b = 1, c = g;
484         function f(d) {
485             return function() {
486                 c = 2;
487             };
488         }
489         a = 2;
490         function g() {}
491         function h() {}
492         console.log(b = 3);
493     }
494     expect: {
495         var a;
496         function f(d) {
497             return function() {
498                 2;
499             };
500         }
501         a = 2;
502         console.log(3);
503     }
504 }
505
506 drop_toplevel_funcs_retain: {
507     options = {
508         top_retain: "f,a,o",
509         toplevel: "funcs",
510         unused: true,
511     }
512     input: {
513         var a, b = 1, c = g;
514         function f(d) {
515             return function() {
516                 c = 2;
517             };
518         }
519         a = 2;
520         function g() {}
521         function h() {}
522         console.log(b = 3);
523     }
524     expect: {
525         var a, b = 1, c = g;
526         function f(d) {
527             return function() {
528                 c = 2;
529             };
530         }
531         a = 2;
532         function g() {}
533         console.log(b = 3);
534     }
535 }
536
537 drop_toplevel_vars_retain: {
538     options = {
539         top_retain: "f,a,o",
540         toplevel: "vars",
541         unused: true,
542     }
543     input: {
544         var a, b = 1, c = g;
545         function f(d) {
546             return function() {
547                 c = 2;
548             };
549         }
550         a = 2;
551         function g() {}
552         function h() {}
553         console.log(b = 3);
554     }
555     expect: {
556         var a;
557         function f(d) {
558             return function() {
559                 2;
560             };
561         }
562         a = 2;
563         function g() {}
564         function h() {}
565         console.log(3);
566     }
567 }
568
569 drop_toplevel_keep_assign: {
570     options = {
571         toplevel: true,
572         unused: "keep_assign",
573     }
574     input: {
575         var a, b = 1, c = g;
576         function f(d) {
577             return function() {
578                 c = 2;
579             };
580         }
581         a = 2;
582         function g() {}
583         function h() {}
584         console.log(b = 3);
585     }
586     expect: {
587         var a, b = 1;
588         a = 2;
589         console.log(b = 3);
590     }
591 }
592
593 drop_fargs: {
594     options = {
595         keep_fargs: false,
596         unused: true,
597     }
598     input: {
599         console.log(function f(a) {
600             var b = a;
601         }());
602     }
603     expect: {
604         console.log(function() {}());
605     }
606     expect_stdout: "undefined"
607 }
608
609 drop_fnames: {
610     options = {
611         keep_fnames: false,
612         unused: true,
613     }
614     input: {
615         function f() {
616             return function g() {
617                 var a = g;
618             };
619         }
620     }
621     expect: {
622         function f() {
623             return function() {};
624         }
625     }
626 }
627
628 global_var: {
629     options = {
630         side_effects: true,
631         unused: true,
632     }
633     input: {
634         var a;
635         function foo(b) {
636             a;
637             b;
638             c;
639             typeof c === "undefined";
640             c + b + a;
641             b && b.ar();
642             return b;
643         }
644     }
645     expect: {
646         var a;
647         function foo(b) {
648             c;
649             c;
650             b && b.ar();
651             return b;
652         }
653     }
654 }
655
656 iife: {
657     options = {
658         side_effects: true,
659         unused: true,
660     }
661     input: {
662         function f() {
663             var a;
664             ~function() {}(b);
665         }
666     }
667     expect: {
668         function f() {
669             b;
670         }
671     }
672 }
673
674 issue_1539: {
675     options = {
676         collapse_vars: true,
677         sequences: true,
678         side_effects: true,
679         unused: true,
680     }
681     input: {
682         function f() {
683             var a, b;
684             a = b = 42;
685             return a;
686         }
687     }
688     expect: {
689         function f() {
690             return 42;
691         }
692     }
693 }
694
695 vardef_value: {
696     options = {
697         keep_fnames: false,
698         reduce_funcs: true,
699         reduce_vars: true,
700         unused: true,
701     }
702     input: {
703         function f() {
704             function g(){
705                 return x();
706             }
707             var a = g();
708             return a(42);
709         }
710     }
711     expect: {
712         function f() {
713             var a = function(){
714                 return x();
715             }();
716             return a(42);
717         }
718     }
719 }
720
721 assign_binding: {
722     options = {
723         collapse_vars: true,
724         side_effects: true,
725         unused: true,
726     }
727     input: {
728         function f() {
729             var a;
730             a = f.g, a();
731         }
732     }
733     expect: {
734         function f() {
735             (0, f.g)();
736         }
737     }
738 }
739
740 assign_chain: {
741     options = {
742         unused: true,
743     }
744     input: {
745         function f() {
746             var a, b;
747             x = a = y = b = 42;
748         }
749     }
750     expect: {
751         function f() {
752             x = y = 42;
753         }
754     }
755 }
756
757 issue_1583: {
758     options = {
759         keep_fargs: true,
760         passes: 2,
761         reduce_funcs: true,
762         reduce_vars: true,
763         unused: true,
764     }
765     input: {
766         function m(t) {
767             (function(e) {
768                 t = e();
769             })(function() {
770                 return (function(a) {
771                     return a;
772                 })(function(a) {});
773             });
774         }
775     }
776     expect: {
777         function m(t) {
778             (function(e) {
779                 (function() {
780                     return (function(a) {
781                         return function(a) {};
782                     })();
783                 })();
784             })();
785         }
786     }
787 }
788
789 issue_1656: {
790     options = {
791         toplevel: true,
792         unused: true,
793     }
794     beautify = {
795         beautify: true,
796     }
797     input: {
798         for (var a=0;;);
799     }
800     expect_exact: "for (;;);"
801 }
802
803 issue_1709: {
804     options = {
805         unused: true,
806     }
807     input: {
808         console.log(
809             function x() {
810                 var x = 1;
811                 return x;
812             }(),
813             function z() {
814                 function z() {}
815                 return z;
816             }()
817         );
818     }
819     expect: {
820         console.log(
821             function() {
822                 var x = 1;
823                 return x;
824             }(),
825             function() {
826                 function z() {}
827                 return z;
828             }()
829         );
830     }
831     expect_stdout: true
832 }
833
834 issue_1715_1: {
835     options = {
836         unused: true,
837     }
838     input: {
839         var a = 1;
840         function f() {
841             a++;
842             try {
843                 x();
844             } catch (a) {
845                 var a;
846             }
847         }
848         f();
849         console.log(a);
850     }
851     expect: {
852         var a = 1;
853         function f() {
854             a++;
855             try {
856                 x();
857             } catch (a) {
858                 var a;
859             }
860         }
861         f();
862         console.log(a);
863     }
864     expect_stdout: "1"
865 }
866
867 issue_1715_2: {
868     options = {
869         unused: true,
870     }
871     input: {
872         var a = 1;
873         function f() {
874             a++;
875             try {
876                 x();
877             } catch (a) {
878                 var a = 2;
879             }
880         }
881         f();
882         console.log(a);
883     }
884     expect: {
885         var a = 1;
886         function f() {
887             a++;
888             try {
889                 x();
890             } catch (a) {
891                 var a;
892             }
893         }
894         f();
895         console.log(a);
896     }
897     expect_stdout: "1"
898 }
899
900 issue_1715_3: {
901     options = {
902         unused: true,
903     }
904     input: {
905         var a = 1;
906         function f() {
907             a++;
908             try {
909                 console;
910             } catch (a) {
911                 var a = 2 + x();
912             }
913         }
914         f();
915         console.log(a);
916     }
917     expect: {
918         var a = 1;
919         function f() {
920             a++;
921             try {
922                 console;
923             } catch (a) {
924                 var a;
925                 x();
926             }
927         }
928         f();
929         console.log(a);
930     }
931     expect_stdout: "1"
932 }
933
934 issue_1715_4: {
935     options = {
936         unused: true,
937     }
938     input: {
939         var a = 1;
940         !function a() {
941             a++;
942             try {
943                 x();
944             } catch (a) {
945                 var a;
946             }
947         }();
948         console.log(a);
949     }
950     expect: {
951         var a = 1;
952         !function() {
953             a++;
954             try {
955                 x();
956             } catch (a) {
957                 var a;
958             }
959         }();
960         console.log(a);
961     }
962     expect_stdout: "1"
963 }
964
965 delete_assign_1: {
966     options = {
967         booleans: true,
968         evaluate: true,
969         toplevel: true,
970         unused: true,
971     }
972     input: {
973         var a;
974         console.log(delete (a = undefined));
975         console.log(delete (a = void 0));
976         console.log(delete (a = Infinity));
977         console.log(delete (a = 1 / 0));
978         console.log(delete (a = NaN));
979         console.log(delete (a = 0 / 0));
980     }
981     expect: {
982         console.log(!0);
983         console.log(!0);
984         console.log(!0);
985         console.log(!0);
986         console.log(!0);
987         console.log(!0);
988     }
989     expect_stdout: [
990         "true",
991         "true",
992         "true",
993         "true",
994         "true",
995         "true",
996     ]
997 }
998
999 delete_assign_2: {
1000     options = {
1001         booleans: true,
1002         evaluate: true,
1003         keep_infinity: true,
1004         toplevel: true,
1005         unused: true,
1006     }
1007     input: {
1008         var a;
1009         console.log(delete (a = undefined));
1010         console.log(delete (a = void 0));
1011         console.log(delete (a = Infinity));
1012         console.log(delete (a = 1 / 0));
1013         console.log(delete (a = NaN));
1014         console.log(delete (a = 0 / 0));
1015     }
1016     expect: {
1017         console.log(!0);
1018         console.log(!0);
1019         console.log(!0);
1020         console.log(!0);
1021         console.log(!0);
1022         console.log(!0);
1023     }
1024     expect_stdout: [
1025         "true",
1026         "true",
1027         "true",
1028         "true",
1029         "true",
1030         "true",
1031     ]
1032 }
1033
1034 drop_var: {
1035     options = {
1036         toplevel: true,
1037         unused: true,
1038     }
1039     input: {
1040         var a;
1041         console.log(a, b);
1042         var a = 1, b = 2;
1043         console.log(a, b);
1044         var a = 3;
1045         console.log(a, b);
1046     }
1047     expect: {
1048         console.log(a, b);
1049         var a = 1, b = 2;
1050         console.log(a, b);
1051         a = 3;
1052         console.log(a, b);
1053     }
1054     expect_stdout: [
1055         "undefined undefined",
1056         "1 2",
1057         "3 2",
1058     ]
1059 }
1060
1061 issue_1830_1: {
1062     options = {
1063         unused: true,
1064     }
1065     input: {
1066         !function() {
1067             L: for (var b = console.log(1); !1;) continue L;
1068         }();
1069     }
1070     expect: {
1071         !function() {
1072             L: for (console.log(1); !1;) continue L;
1073         }();
1074     }
1075     expect_stdout: "1"
1076 }
1077
1078 issue_1830_2: {
1079     options = {
1080         unused: true,
1081     }
1082     input: {
1083         !function() {
1084             L: for (var a = 1, b = console.log(a); --a;) continue L;
1085         }();
1086     }
1087     expect: {
1088         !function() {
1089             var a = 1;
1090             L: for (console.log(a); --a;) continue L;
1091         }();
1092     }
1093     expect_stdout: "1"
1094 }
1095
1096 issue_1838: {
1097     options = {
1098         join_vars: true,
1099         loops: true,
1100         unused: true,
1101     }
1102     beautify = {
1103         beautify: true,
1104     }
1105     input: {
1106         function f() {
1107             var b = a;
1108             while (c);
1109         }
1110     }
1111     expect_exact: [
1112         "function f() {",
1113         "    for (a; c; );",
1114         "}",
1115     ]
1116 }
1117
1118 var_catch_toplevel: {
1119     options = {
1120         conditionals: true,
1121         negate_iife: true,
1122         passes: 2,
1123         reduce_funcs: true,
1124         reduce_vars: true,
1125         side_effects: true,
1126         toplevel: true,
1127         unused: true,
1128     }
1129     input: {
1130         function f() {
1131             a--;
1132             try {
1133                 a++;
1134                 x();
1135             } catch (a) {
1136                 if (a) var a;
1137                 var a = 10;
1138             }
1139         }
1140         f();
1141     }
1142     expect: {
1143         !function() {
1144             try {
1145                 x();
1146             } catch (a) {
1147                 var a;
1148             }
1149         }();
1150     }
1151 }
1152
1153 issue_2105_1: {
1154     options = {
1155         collapse_vars: true,
1156         inline: true,
1157         passes: 3,
1158         reduce_funcs: true,
1159         reduce_vars: true,
1160         side_effects: true,
1161         unused: true,
1162     }
1163     input: {
1164         !function(factory) {
1165             factory();
1166         }(function() {
1167             return function(fn) {
1168                 fn()().prop();
1169             }(function() {
1170                 function bar() {
1171                     var quux = function() {
1172                         console.log("PASS");
1173                     }, foo = function() {
1174                         console.log;
1175                         quux();
1176                     };
1177                     return { prop: foo };
1178                 }
1179                 return bar;
1180             });
1181         });
1182     }
1183     expect: {
1184         ({
1185             prop: function() {
1186                 console.log;
1187                 console.log("PASS");
1188             }
1189         }).prop();
1190     }
1191     expect_stdout: "PASS"
1192 }
1193
1194 issue_2105_2: {
1195     options = {
1196         collapse_vars: true,
1197         inline: true,
1198         passes: 3,
1199         properties: true,
1200         pure_getters: "strict",
1201         reduce_funcs: true,
1202         reduce_vars: true,
1203         side_effects: true,
1204         unsafe: true,
1205         unused: true,
1206     }
1207     input: {
1208         !function(factory) {
1209             factory();
1210         }(function() {
1211             return function(fn) {
1212                 fn()().prop();
1213             }(function() {
1214                 function bar() {
1215                     var quux = function() {
1216                         console.log("PASS");
1217                     }, foo = function() {
1218                         console.log;
1219                         quux();
1220                     };
1221                     return { prop: foo };
1222                 }
1223                 return bar;
1224             });
1225         });
1226     }
1227     expect: {
1228         console.log("PASS");
1229     }
1230     expect_stdout: "PASS"
1231 }
1232
1233 issue_2105_3: {
1234     options = {
1235         inline: true,
1236         passes: 2,
1237         reduce_vars: true,
1238         unused: true,
1239     }
1240     input: {
1241         !function(factory) {
1242             factory();
1243         }(function() {
1244             return function(fn) {
1245                 fn()().prop();
1246             }(function() {
1247                 function bar() {
1248                     var quux = function() {
1249                         console.log("PASS");
1250                     }, foo = function() {
1251                         console.log;
1252                         quux();
1253                     };
1254                     return { prop: foo };
1255                 }
1256                 return bar;
1257             });
1258         });
1259     }
1260     expect: {
1261         !void void {
1262             prop: function() {
1263                 console.log;
1264                 void console.log("PASS");
1265             }
1266         }.prop();
1267     }
1268     expect_stdout: "PASS"
1269 }
1270
1271 issue_2226_1: {
1272     options = {
1273         side_effects: true,
1274         unused: true,
1275     }
1276     input: {
1277         function f1() {
1278             var a = b;
1279             a += c;
1280         }
1281         function f2(a) {
1282             a <<= b;
1283         }
1284         function f3(a) {
1285             --a;
1286         }
1287         function f4() {
1288             var a = b;
1289             return a *= c;
1290         }
1291         function f5(a) {
1292             x(a /= b);
1293         }
1294     }
1295     expect: {
1296         function f1() {
1297             b;
1298             c;
1299         }
1300         function f2(a) {
1301             b;
1302         }
1303         function f3(a) {
1304             0;
1305         }
1306         function f4() {
1307             var a = b;
1308             return a *= c;
1309         }
1310         function f5(a) {
1311             x(a /= b);
1312         }
1313     }
1314 }
1315
1316 issue_2226_2: {
1317     options = {
1318         collapse_vars: true,
1319         sequences: true,
1320         side_effects: true,
1321         unused: true,
1322     }
1323     input: {
1324         console.log(function(a, b) {
1325             a += b;
1326             return a;
1327         }(1, 2));
1328     }
1329     expect: {
1330         console.log(function(a, b) {
1331             return a += 2;
1332         }(1));
1333     }
1334     expect_stdout: "3"
1335 }
1336
1337 issue_2226_3: {
1338     options = {
1339         collapse_vars: true,
1340         side_effects: true,
1341         unused: true,
1342     }
1343     input: {
1344         console.log(function(a, b) {
1345             a += b;
1346             return a;
1347         }(1, 2));
1348     }
1349     expect: {
1350         console.log(function(a, b) {
1351             return a += 2;
1352         }(1));
1353     }
1354     expect_stdout: "3"
1355 }
1356
1357 issue_2288: {
1358     options = {
1359         unused: true,
1360     }
1361     beautify = {
1362         beautify: true,
1363     }
1364     input: {
1365         function foo(o) {
1366             for (var j = o.a, i = 0; i < 0; i++);
1367             for (var i = 0; i < 0; i++);
1368         }
1369     }
1370     expect: {
1371         function foo(o) {
1372             o.a;
1373             for (var i = 0; i < 0; i++);
1374             for (i = 0; i < 0; i++);
1375         }
1376     }
1377 }
1378
1379 issue_2516_1: {
1380     options = {
1381         collapse_vars: true,
1382         reduce_funcs: true,
1383         reduce_vars: true,
1384         unused: true,
1385     }
1386     input: {
1387         function foo() {
1388             function qux(x) {
1389                 bar.call(null, x);
1390             }
1391             function bar(x) {
1392                 var FOUR = 4;
1393                 var trouble = x || never_called();
1394                 var value = (FOUR - 1) * trouble;
1395                 console.log(value == 6 ? "PASS" : value);
1396             }
1397             Baz = qux;
1398         }
1399         var Baz;
1400         foo();
1401         Baz(2);
1402     }
1403     expect: {
1404         function foo() {
1405             Baz = function(x) {
1406                 (function(x) {
1407                     var trouble = x || never_called();
1408                     var value = (4 - 1) * trouble;
1409                     console.log(6 == value ? "PASS" : value);
1410                 }).call(null, x);
1411             };
1412         }
1413         var Baz;
1414         foo();
1415         Baz(2);
1416     }
1417 }
1418
1419 issue_2516_2: {
1420     options = {
1421         collapse_vars: true,
1422         passes: 2,
1423         reduce_funcs: true,
1424         reduce_vars: true,
1425         unused: true,
1426     }
1427     input: {
1428         function foo() {
1429             function qux(x) {
1430                 bar.call(null, x);
1431             }
1432             function bar(x) {
1433                 var FOUR = 4;
1434                 var trouble = x || never_called();
1435                 var value = (FOUR - 1) * trouble;
1436                 console.log(value == 6 ? "PASS" : value);
1437             }
1438             Baz = qux;
1439         }
1440         var Baz;
1441         foo();
1442         Baz(2);
1443     }
1444     expect: {
1445         function foo() {
1446             Baz = function(x) {
1447                 (function(x) {
1448                     var value = (4 - 1) * (x || never_called());
1449                     console.log(6 == value ? "PASS" : value);
1450                 }).call(null, x);
1451             };
1452         }
1453         var Baz;
1454         foo();
1455         Baz(2);
1456     }
1457 }
1458
1459 defun_lambda_same_name: {
1460     options = {
1461         toplevel: true,
1462         unused: true,
1463     }
1464     input: {
1465         function f(n) {
1466             return n ? n * f(n - 1) : 1;
1467         }
1468         console.log(function f(n) {
1469             return n ? n * f(n - 1) : 1;
1470         }(5));
1471     }
1472     expect: {
1473         console.log(function f(n) {
1474             return n ? n * f(n - 1) : 1;
1475         }(5));
1476     }
1477     expect_stdout: "120"
1478 }
1479
1480 issue_2660_1: {
1481     options = {
1482         reduce_vars: true,
1483         side_effects: true,
1484         toplevel: true,
1485         unused: true,
1486     }
1487     input: {
1488         var a = 2;
1489         function f(b) {
1490             return b && f() || a--;
1491         }
1492         f(1);
1493         console.log(a);
1494     }
1495     expect: {
1496         var a = 2;
1497         (function f(b) {
1498             return b && f() || a--;
1499         })(1);
1500         console.log(a);
1501     }
1502     expect_stdout: "1"
1503 }
1504
1505 issue_2660_2: {
1506     options = {
1507         collapse_vars: true,
1508         reduce_vars: true,
1509         sequences: true,
1510         side_effects: true,
1511         toplevel: true,
1512         unused: true,
1513     }
1514     input: {
1515         var a = 1;
1516         function f(b) {
1517             b && f();
1518             --a, a.toString();
1519         }
1520         f();
1521         console.log(a);
1522     }
1523     expect: {
1524         var a = 1;
1525         (function f(b) {
1526             b && f(),
1527             (--a).toString();
1528         })(),
1529         console.log(a);
1530     }
1531     expect_stdout: "0"
1532 }
1533
1534 issue_2665: {
1535     options = {
1536         evaluate: true,
1537         inline: true,
1538         keep_fargs: false,
1539         passes: 2,
1540         reduce_funcs: true,
1541         reduce_vars: true,
1542         side_effects: true,
1543         toplevel: true,
1544         typeofs: true,
1545         unused: true,
1546     }
1547     input: {
1548         var a = 1;
1549         function g() {
1550             a-- && g();
1551         }
1552         typeof h == "function" && h();
1553         function h() {
1554             typeof g == "function" && g();
1555         }
1556         console.log(a);
1557     }
1558     expect: {
1559         var a = 1;
1560         (function g() {
1561             a-- && g();
1562         })();
1563         console.log(a);
1564     }
1565     expect_stdout: "-1"
1566 }
1567
1568 double_assign_1: {
1569     options = {
1570         passes: 2,
1571         reduce_vars: true,
1572         side_effects: true,
1573         unused: true,
1574     }
1575     input: {
1576         function f1() {
1577             var a = {};
1578             var a = [];
1579             return a;
1580         }
1581         function f2() {
1582             var a = {};
1583             a = [];
1584             return a;
1585         }
1586         function f3() {
1587             a = {};
1588             var a = [];
1589             return a;
1590         }
1591         function f4(a) {
1592             a = {};
1593             a = [];
1594             return a;
1595         }
1596         function f5(a) {
1597             var a = {};
1598             a = [];
1599             return a;
1600         }
1601         function f6(a) {
1602             a = {};
1603             var a = [];
1604             return a;
1605         }
1606         console.log(f1(), f2(), f3(), f4(), f5(), f6());
1607     }
1608     expect: {
1609         function f1() {
1610             return [];
1611         }
1612         function f2() {
1613             var a;
1614             a = [];
1615             return a;
1616         }
1617         function f3() {
1618             return [];
1619         }
1620         function f4(a) {
1621             a = [];
1622             return a;
1623         }
1624         function f5(a) {
1625             a = [];
1626             return a;
1627         }
1628         function f6(a) {
1629             a = [];
1630             return a;
1631         }
1632         console.log(f1(), f2(), f3(), f4(), f5(), f6());
1633     }
1634     expect_stdout: true
1635 }
1636
1637 double_assign_2: {
1638     options = {
1639         reduce_vars: true,
1640         toplevel: true,
1641         unused: true,
1642     }
1643     input: {
1644         for (var i = 0; i < 2; i++)
1645             a = void 0, a = {}, console.log(a);
1646         var a;
1647     }
1648     expect: {
1649         for (var i = 0; i < 2; i++)
1650             a = {}, console.log(a);
1651         var a;
1652     }
1653 }
1654
1655 double_assign_3: {
1656     options = {
1657         reduce_vars: true,
1658         toplevel: true,
1659         unused: true,
1660     }
1661     input: {
1662         for (var i = 0; i < 2; i++)
1663             a = void 0, a = { a: a }, console.log(a);
1664         var a;
1665     }
1666     expect: {
1667         for (var i = 0; i < 2; i++)
1668             a = void 0, a = { a: a }, console.log(a);
1669         var a;
1670     }
1671 }
1672
1673 cascade_drop_assign: {
1674     options = {
1675         reduce_vars: true,
1676         toplevel: true,
1677         unused: true,
1678     }
1679     input: {
1680         var a, b = a = "PASS";
1681         console.log(b);
1682     }
1683     expect: {
1684         var b = "PASS";
1685         console.log(b);
1686     }
1687     expect_stdout: "PASS"
1688 }
1689
1690 chained_3: {
1691     options = {
1692         reduce_vars: true,
1693         unused: true,
1694     }
1695     input: {
1696         console.log(function(a, b) {
1697             var c = a, c = b;
1698             b++;
1699             return c;
1700         }(1, 2));
1701     }
1702     expect: {
1703         console.log(function(a, b) {
1704             var c = b;
1705             +b;
1706             return c;
1707         }(0, 2));
1708     }
1709     expect_stdout: "2"
1710 }
1711
1712 issue_2768: {
1713     options = {
1714         inline: true,
1715         reduce_vars: true,
1716         sequences: true,
1717         side_effects: true,
1718         toplevel: true,
1719         unused: true,
1720     }
1721     input: {
1722         var a = "FAIL", c = 1;
1723         var c = function(b) {
1724             var d = b = a;
1725             var e = --b + (d && (a = "PASS"));
1726         }();
1727         console.log(a, typeof c);
1728     }
1729     expect: {
1730         var a = "FAIL";
1731         var c = (d = a, void (d && (a = "PASS")));
1732         var d;
1733         console.log(a, typeof c);
1734     }
1735     expect_stdout: "PASS undefined"
1736 }
1737
1738 issue_2846: {
1739     options = {
1740         collapse_vars: true,
1741         reduce_vars: true,
1742         toplevel: true,
1743         unused: true,
1744     }
1745     input: {
1746         function f(a, b) {
1747             var a = 0;
1748             b && b(a);
1749             return a++;
1750         }
1751         var c = f();
1752         console.log(c);
1753     }
1754     expect: {
1755         var c = function(a, b) {
1756             a = 0;
1757             b && b(a);
1758             return a++;
1759         }();
1760         console.log(c);
1761     }
1762     expect_stdout: "0"
1763 }
1764
1765 issue_805_1: {
1766     options = {
1767         inline: true,
1768         passes: 3,
1769         pure_getters: "strict",
1770         reduce_vars: true,
1771         sequences: true,
1772         side_effects: true,
1773         unused: true,
1774     }
1775     input: {
1776         (function(a) {
1777             var unused = function() {};
1778             unused.prototype[a()] = 42;
1779             (unused.prototype.bar = function() {
1780                 console.log("bar");
1781             })();
1782             return unused;
1783         })(function() {
1784             console.log("foo");
1785             return "foo";
1786         });
1787     }
1788     expect: {
1789         console.log("foo"),
1790         console.log("bar");
1791     }
1792     expect_stdout: [
1793         "foo",
1794         "bar",
1795     ]
1796 }
1797
1798 issue_805_2: {
1799     options = {
1800         inline: true,
1801         passes: 3,
1802         pure_getters: "strict",
1803         reduce_vars: true,
1804         sequences: true,
1805         side_effects: true,
1806         unused: true,
1807     }
1808     input: {
1809         (function(a) {
1810             function unused() {}
1811             unused.prototype[a()] = 42;
1812             (unused.prototype.bar = function() {
1813                 console.log("bar");
1814             })();
1815             return unused;
1816         })(function() {
1817             console.log("foo");
1818             return "foo";
1819         });
1820     }
1821     expect: {
1822         console.log("foo"),
1823         console.log("bar");
1824     }
1825     expect_stdout: [
1826         "foo",
1827         "bar",
1828     ]
1829 }
1830
1831 issue_2995: {
1832     options = {
1833         pure_getters: "strict",
1834         reduce_vars: true,
1835         unused: true,
1836     }
1837     input: {
1838         function f(a) {
1839             var b;
1840             a.b = b = function() {};
1841             b.c = "PASS";
1842         }
1843         var o = {};
1844         f(o);
1845         console.log(o.b.c);
1846     }
1847     expect: {
1848         function f(a) {
1849             var b;
1850             a.b = b = function() {};
1851             b.c = "PASS";
1852         }
1853         var o = {};
1854         f(o);
1855         console.log(o.b.c);
1856     }
1857     expect_stdout: "PASS"
1858 }
1859
1860 issue_3146_1: {
1861     options = {
1862         collapse_vars: true,
1863         unused: true,
1864     }
1865     input: {
1866         (function(f) {
1867             f("g()");
1868         })(function(a) {
1869             eval(a);
1870             function g(b) {
1871                 if (!b) b = "PASS";
1872                 console.log(b);
1873             }
1874         });
1875     }
1876     expect: {
1877         (function(f) {
1878             f("g()");
1879         })(function(a) {
1880             eval(a);
1881             function g(b) {
1882                 if (!b) b = "PASS";
1883                 console.log(b);
1884             }
1885         });
1886     }
1887     expect_stdout: "PASS"
1888 }
1889
1890 issue_3146_2: {
1891     options = {
1892         reduce_vars: true,
1893         unused: true,
1894     }
1895     input: {
1896         (function(f) {
1897             f("g()");
1898         })(function(a) {
1899             eval(a);
1900             function g(b) {
1901                 if (!b) b = "PASS";
1902                 console.log(b);
1903             }
1904         });
1905     }
1906     expect: {
1907         (function(f) {
1908             f("g()");
1909         })(function(a) {
1910             eval(a);
1911             function g(b) {
1912                 if (!b) b = "PASS";
1913                 console.log(b);
1914             }
1915         });
1916     }
1917     expect_stdout: "PASS"
1918 }
1919
1920 issue_3146_3: {
1921     options = {
1922         collapse_vars: true,
1923         unused: true,
1924     }
1925     input: {
1926         var g = "PASS";
1927         (function(f) {
1928             var g = "FAIL";
1929             f("console.log(g)", g[g]);
1930         })(function(a) {
1931             eval(a);
1932         });
1933     }
1934     expect: {
1935         var g = "PASS";
1936         (function(f) {
1937             var g = "FAIL";
1938             f("console.log(g)", g[g]);
1939         })(function(a) {
1940             eval(a);
1941         });
1942     }
1943     expect_stdout: "PASS"
1944 }
1945
1946 issue_3146_4: {
1947     options = {
1948         reduce_vars: true,
1949         unused: true,
1950     }
1951     input: {
1952         var g = "PASS";
1953         (function(f) {
1954             var g = "FAIL";
1955             f("console.log(g)", g[g]);
1956         })(function(a) {
1957             eval(a);
1958         });
1959     }
1960     expect: {
1961         var g = "PASS";
1962         (function(f) {
1963             var g = "FAIL";
1964             f("console.log(g)", g[g]);
1965         })(function(a) {
1966             eval(a);
1967         });
1968     }
1969     expect_stdout: "PASS"
1970 }
1971
1972 issue_3192_1: {
1973     options = {
1974         unused: true,
1975     }
1976     input: {
1977         (function(a) {
1978             console.log(a = "foo", arguments[0]);
1979         })("bar");
1980         (function(a) {
1981             "use strict";
1982             console.log(a = "foo", arguments[0]);
1983         })("bar");
1984     }
1985     expect: {
1986         (function(a) {
1987             console.log(a = "foo", arguments[0]);
1988         })("bar");
1989         (function(a) {
1990             "use strict";
1991             console.log("foo", arguments[0]);
1992         })("bar");
1993     }
1994     expect_stdout: [
1995         "foo foo",
1996         "foo bar",
1997     ]
1998 }
1999
2000 issue_3192_2: {
2001     options = {
2002         keep_fargs: false,
2003         unused: true,
2004     }
2005     input: {
2006         "use strict";
2007         (function(a) {
2008             console.log(a = "foo", arguments[0]);
2009         })("bar");
2010     }
2011     expect: {
2012         "use strict";
2013         (function() {
2014             console.log("foo", arguments[0]);
2015         })("bar");
2016     }
2017     expect_stdout: "foo bar"
2018 }
2019
2020 issue_3233: {
2021     options = {
2022         pure_getters: "strict",
2023         side_effects: true,
2024         unused: true,
2025     }
2026     input: {
2027         var a = function b() {
2028             b.c = "PASS";
2029         };
2030         a();
2031         console.log(a.c);
2032     }
2033     expect: {
2034         var a = function b() {
2035             b.c = "PASS";
2036         };
2037         a();
2038         console.log(a.c);
2039     }
2040     expect_stdout: "PASS"
2041 }
2042
2043 issue_3375: {
2044     options = {
2045         reduce_vars: true,
2046         toplevel: true,
2047         unused: true,
2048     }
2049     input: {
2050         var b = 1;
2051         var a = c = [], c = --b + ("function" == typeof f && f());
2052         var a = c && c[a];
2053         console.log(a, b);
2054     }
2055     expect: {
2056         var b = 1;
2057         var a = [], c = --b + ("function" == typeof f && f());
2058         a = c && c[a];
2059         console.log(a, b);
2060     }
2061     expect_stdout: "0 0"
2062 }
2063
2064 issue_3427_1: {
2065     options = {
2066         sequences: true,
2067         side_effects: true,
2068         unused: true,
2069     }
2070     input: {
2071         (function() {
2072             var a;
2073             a = a || {};
2074         })();
2075     }
2076     expect: {}
2077 }
2078
2079 issue_3427_2: {
2080     options = {
2081         unused: true,
2082     }
2083     input: {
2084         (function() {
2085             var s = "PASS";
2086             console.log(s = s || "FAIL");
2087         })();
2088     }
2089     expect: {
2090         (function() {
2091             var s = "PASS";
2092             console.log(s = s || "FAIL");
2093         })();
2094     }
2095     expect_stdout: "PASS"
2096 }
2097
2098 issue_3495: {
2099     options = {
2100         dead_code: true,
2101         pure_getters: "strict",
2102         side_effects: true,
2103         unused: true,
2104     }
2105     input: {
2106         console.log(function f() {
2107             f = 0;
2108             var a = f.p;
2109         }());
2110     }
2111     expect: {
2112         console.log(void 0);
2113     }
2114     expect_stdout: "undefined"
2115 }
2116
2117 issue_3497: {
2118     options = {
2119         pure_getters: "strict",
2120         side_effects: true,
2121         unused: true,
2122     }
2123     input: {
2124         var a;
2125         console.log(function(b) {
2126             (b += a).p = 0;
2127         }());
2128     }
2129     expect: {
2130         var a;
2131         console.log(function(b) {
2132             (b += a).p = 0;
2133         }());
2134     }
2135     expect_stdout: "undefined"
2136 }
2137
2138 issue_3515_1: {
2139     options = {
2140         collapse_vars: true,
2141         evaluate: true,
2142         reduce_vars: true,
2143         unused: true,
2144     }
2145     input: {
2146         var c = 0;
2147         (function() {
2148             this[c++] = 0;
2149             var expr20 = !0;
2150             for (var key20 in expr20);
2151         })();
2152         console.log(c);
2153     }
2154     expect: {
2155         var c = 0;
2156         (function() {
2157             for (var key20 in !(this[c++] = 0));
2158         })();
2159         console.log(c);
2160     }
2161     expect_stdout: "1"
2162 }
2163
2164 issue_3515_2: {
2165     options = {
2166         side_effects: true,
2167         toplevel: true,
2168         unused: true,
2169     }
2170     input: {
2171         var a = "FAIL";
2172         function f() {
2173             typeof b === "number";
2174             delete a;
2175         }
2176         var b = f(a = "PASS");
2177         console.log(a);
2178     }
2179     expect: {
2180         var a = "FAIL";
2181         function f() {
2182             delete a;
2183         }
2184         f(a = "PASS");
2185         console.log(a);
2186     }
2187     expect_stdout: "PASS"
2188 }
2189
2190 issue_3515_3: {
2191     options = {
2192         collapse_vars: true,
2193         evaluate: true,
2194         unused: true,
2195     }
2196     input: {
2197         var c = "FAIL";
2198         (function() {
2199             function f() {
2200                 c = "PASS";
2201             }
2202             var a = f();
2203             var a = function g(b) {
2204                 b && (b.p = this);
2205             }(a);
2206         })();
2207         console.log(c);
2208     }
2209     expect: {
2210         var c = "FAIL";
2211         (function() {
2212             function f() {
2213                 c = "PASS";
2214             }
2215             (function(b) {
2216                 b && (b.p = this);
2217             })(f());
2218         })();
2219         console.log(c);
2220     }
2221     expect_stdout: "PASS"
2222 }
2223
2224 function_assign: {
2225     options = {
2226         pure_getters: "strict",
2227         reduce_vars: true,
2228         side_effects: true,
2229         unused: true,
2230     }
2231     input: {
2232         console.log(function() {
2233             var a = "PASS";
2234             function g(b) {
2235                 return b;
2236             }
2237             g.p = a;
2238             function h(c) {
2239                 return c;
2240             }
2241             h.p = a;
2242             return h;
2243         }().p);
2244     }
2245     expect: {
2246         console.log(function() {
2247             var a = "PASS";
2248             function h(c) {
2249                 return c;
2250             }
2251             h.p = a;
2252             return h;
2253         }().p);
2254     }
2255     expect_stdout: "PASS"
2256 }
2257
2258 issue_3598: {
2259     options = {
2260         collapse_vars: true,
2261         evaluate: true,
2262         reduce_vars: true,
2263         unused: true,
2264     }
2265     input: {
2266         var a = "FAIL";
2267         try {
2268             (function() {
2269                 var b = void 0;
2270                 a = "PASS";
2271                 c.p = 0;
2272                 var c = b[!1];
2273             })();
2274         } catch (e) {}
2275         console.log(a);
2276     }
2277     expect: {
2278         var a = "FAIL";
2279         try {
2280             (function() {
2281                 a = "PASS";
2282                 (void ((void 0).p = 0))[!1];
2283             })();
2284         } catch (e) {}
2285         console.log(a);
2286     }
2287     expect_stdout: "PASS"
2288 }
2289
2290 self_assign: {
2291     options = {
2292         passes: 2,
2293         side_effects: true,
2294         unused: true,
2295     }
2296     input: {
2297         function d(a) {
2298             a = a;
2299         }
2300         function e(a, b) {
2301             a = b;
2302             b = a;
2303         }
2304         function f(a, b, c) {
2305             a = b;
2306             b = c;
2307             c = a;
2308         }
2309         function g(a, b, c) {
2310             a = a * b + c;
2311         }
2312     }
2313     expect: {
2314         function d(a) {}
2315         function e(a, b) {}
2316         function f(a, b, c) {}
2317         function g(a, b, c) {}
2318     }
2319 }
2320
2321 function_argument_reference: {
2322     options = {
2323         keep_fargs: false,
2324         side_effects: true,
2325         unused: true,
2326     }
2327     input: {
2328         var a = 1, b = 42;
2329         function f(a) {
2330             b <<= a;
2331         }
2332         f();
2333         console.log(a, b);
2334     }
2335     expect: {
2336         var a = 1, b = 42;
2337         function f(a) {
2338             b <<= a;
2339         }
2340         f();
2341         console.log(a, b);
2342     }
2343     expect_stdout: "1 42"
2344 }
2345
2346 function_parameter_ie8: {
2347     options = {
2348         ie: true,
2349         reduce_vars: true,
2350         unused: true,
2351     }
2352     input: {
2353         (function() {
2354             var a;
2355             function f() {
2356                 console.log("PASS");
2357             }
2358             f(a = 1 + a);
2359         })();
2360     }
2361     expect: {
2362         (function() {
2363             (function() {
2364                 console.log("PASS");
2365             })();
2366         })();
2367     }
2368     expect_stdout: "PASS"
2369 }
2370
2371 issue_3664: {
2372     options = {
2373         pure_getters: "strict",
2374         side_effects: true,
2375         unused: true,
2376     }
2377     input: {
2378         console.log(function() {
2379             var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
2380             return "PASS";
2381         }());
2382     }
2383     expect: {
2384         console.log(function() {
2385             var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
2386             return "PASS";
2387         }());
2388     }
2389     expect_stdout: "PASS"
2390 }
2391
2392 issue_3673: {
2393     options = {
2394         pure_getters: "strict",
2395         sequences: true,
2396         side_effects: true,
2397         toplevel: true,
2398         unused: true,
2399     }
2400     input: {
2401         var a;
2402         (a = [ a ]).p = 42;
2403         console.log("PASS");
2404     }
2405     expect: {
2406         console.log("PASS");
2407     }
2408     expect_stdout: "PASS"
2409 }
2410
2411 issue_3746: {
2412     options = {
2413         keep_fargs: false,
2414         side_effects: true,
2415         unused: true,
2416     }
2417     input: {
2418         try {
2419             A;
2420         } catch (e) {
2421             var e;
2422         }
2423         (function f(a) {
2424             e = a;
2425         })();
2426         console.log("PASS");
2427     }
2428     expect: {
2429         try {
2430             A;
2431         } catch (e) {
2432             var e;
2433         }
2434         (function(a) {
2435             e = a;
2436         })();
2437         console.log("PASS");
2438     }
2439     expect_stdout: "PASS"
2440 }
2441
2442 drop_duplicated_side_effects: {
2443     options = {
2444         toplevel: true,
2445         unused: true,
2446     }
2447     input: {
2448         var a = 0;
2449         for (var i = 1; i--;)
2450             var a = 0, b = ++a;
2451         console.log(a);
2452     }
2453     expect: {
2454         var a = 0;
2455         for (var i = 1; i--;)
2456             a = 0, ++a;
2457         console.log(a);
2458     }
2459     expect_stdout: "1"
2460 }
2461
2462 drop_duplicated_var_catch: {
2463     options = {
2464         unused: true,
2465     }
2466     input: {
2467         function f() {
2468             try {
2469                 x();
2470             } catch (a) {
2471                 var a, a;
2472             }
2473         }
2474     }
2475     expect: {
2476         function f() {
2477             try {
2478                 x();
2479             } catch (a) {
2480                 var a;
2481             }
2482         }
2483     }
2484 }
2485
2486 issue_3802_1: {
2487     options = {
2488         functions: true,
2489         reduce_vars: true,
2490         toplevel: true,
2491         unused: true,
2492     }
2493     input: {
2494         var a = 0;
2495         a += 0;
2496         var a = function() {};
2497         console.log(typeof a);
2498     }
2499     expect: {
2500         var a = 0;
2501         a += 0;
2502         a = function() {};
2503         console.log(typeof a);
2504     }
2505     expect_stdout: "function"
2506 }
2507
2508 issue_3802_2: {
2509     options = {
2510         functions: true,
2511         reduce_vars: true,
2512         side_effects: true,
2513         toplevel: true,
2514         unused: true,
2515     }
2516     input: {
2517         var a = 0;
2518         a += 0;
2519         var a = function() {};
2520         console.log(typeof a);
2521     }
2522     expect: {
2523         0;
2524         var a = function() {};
2525         console.log(typeof a);
2526     }
2527     expect_stdout: "function"
2528 }
2529
2530 issue_3899: {
2531     options = {
2532         assignments: true,
2533         evaluate: true,
2534         functions: true,
2535         inline: true,
2536         join_vars: true,
2537         passes: 2,
2538         reduce_vars: true,
2539         side_effects: true,
2540         toplevel: true,
2541         unused: true,
2542     }
2543     input: {
2544         var a = 0;
2545         a = a + 1;
2546         var a = function f(b) {
2547             return function() {
2548                 return b;
2549             };
2550         }(2);
2551         console.log(typeof a);
2552     }
2553     expect: {
2554         function a() {
2555             return 2;
2556         }
2557         console.log(typeof a);
2558     }
2559     expect_stdout: "function"
2560 }
2561
2562 cross_scope_assign_chain: {
2563     options = {
2564         reduce_vars: true,
2565         side_effects: true,
2566         toplevel: true,
2567         unused: true,
2568     }
2569     input: {
2570         var a, b = 0;
2571         (function() {
2572             a = b;
2573             a++;
2574             while (b++);
2575         })();
2576         console.log(a ? "PASS" : "FAIL");
2577     }
2578     expect: {
2579         var a, b = 0;
2580         (function() {
2581             a = b;
2582             a++;
2583             while (b++);
2584         })();
2585         console.log(a ? "PASS" : "FAIL");
2586     }
2587     expect_stdout: "PASS"
2588 }
2589
2590 assign_if_assign_read: {
2591     options = {
2592         reduce_vars: true,
2593         unused: true,
2594     }
2595     input: {
2596         (function(a) {
2597             var b;
2598             do {
2599                 b = "FAIL";
2600                 if (Array.isArray(a)) {
2601                     b = a[0];
2602                     console.log(b);
2603                 }
2604             } while (!console);
2605         })([ "PASS" ]);
2606     }
2607     expect: {
2608         (function(a) {
2609             var b;
2610             do {
2611                 "FAIL";
2612                 if (Array.isArray(a)) {
2613                     b = a[0];
2614                     console.log(b);
2615                 }
2616             } while (!console);
2617         })([ "PASS" ]);
2618     }
2619     expect_stdout: "PASS"
2620 }
2621
2622 issue_3951: {
2623     options = {
2624         pure_getters: "strict",
2625         reduce_vars: true,
2626         side_effects: true,
2627         toplevel: true,
2628         unused: true,
2629     }
2630     input: {
2631         var a = console.log("PASS");
2632         console.log(a);
2633         a = "0";
2634         console.log(a.p = 0);
2635         a && a;
2636     }
2637     expect: {
2638         var a = console.log("PASS");
2639         console.log(a);
2640         a = "0";
2641         console.log(a.p = 0);
2642     }
2643     expect_stdout: [
2644         "PASS",
2645         "undefined",
2646         "0",
2647     ]
2648 }
2649
2650 issue_3956: {
2651     options = {
2652         collapse_vars: true,
2653         evaluate: true,
2654         inline: true,
2655         passes: 2,
2656         reduce_vars: true,
2657         sequences: true,
2658         side_effects: true,
2659         toplevel: true,
2660         unused: true,
2661     }
2662     input: {
2663         (function(a) {
2664             function f(b) {
2665                 console.log(b);
2666                 a = 1;
2667             }
2668             var c = f(c += 0);
2669             (function(d) {
2670                 console.log(d);
2671             })(console.log(a) ^ 1, c);
2672         })();
2673     }
2674     expect: {
2675         var d;
2676         console.log(NaN),
2677         d = 1 ^ console.log(1),
2678         console.log(d);
2679     }
2680     expect_stdout: [
2681         "NaN",
2682         "1",
2683         "1",
2684     ]
2685 }
2686
2687 issue_3962_1: {
2688     options = {
2689         evaluate: true,
2690         keep_fargs: false,
2691         reduce_vars: true,
2692         toplevel: true,
2693         unused: true,
2694     }
2695     input: {
2696         var a = 0;
2697         function f(b, c) {
2698             do {
2699                 var d = console + e, e = 0..toString() === b;
2700             } while (0);
2701             if (c) console.log("PASS");
2702         }
2703         var a = f(a--, 1);
2704         a;
2705     }
2706     expect: {
2707         var a = 0;
2708         (function(c) {
2709             do {
2710                 console;
2711                 0..toString();
2712             } while (0);
2713             if (c) console.log("PASS");
2714         })(1);
2715         void 0;
2716     }
2717     expect_stdout: "PASS"
2718 }
2719
2720 issue_3962_2: {
2721     options = {
2722         keep_fargs: false,
2723         reduce_vars: true,
2724         side_effects: true,
2725         toplevel: true,
2726         unused: true,
2727     }
2728     input: {
2729         var a = 0;
2730         function f(b, c) {
2731             do {
2732                 var d = console + e, e = 0..toString() === b;
2733             } while (0);
2734             if (c) console.log("PASS");
2735         }
2736         var a = f(a--, 1);
2737         a;
2738     }
2739     expect: {
2740         var a = 0;
2741         (function(c) {
2742             do {
2743                 console;
2744                 0..toString();
2745             } while (0);
2746             if (c) console.log("PASS");
2747         })(1);
2748     }
2749     expect_stdout: "PASS"
2750 }
2751
2752 issue_3986: {
2753     options = {
2754         reduce_vars: true,
2755         side_effects: true,
2756         toplevel: true,
2757         unused: true,
2758     }
2759     input: {
2760         var a = 0, b = 0;
2761         (function() {
2762             try {
2763                 throw 42;
2764             } catch (e) {
2765                 a++;
2766             }
2767             b = b && 0;
2768         })(b *= a);
2769         console.log(b);
2770     }
2771     expect: {
2772         var a = 0, b = 0;
2773         (function() {
2774             try {
2775                 throw 42;
2776             } catch (e) {
2777                 a++;
2778             }
2779             b = b && 0;
2780         })(b *= a);
2781         console.log(b);
2782     }
2783     expect_stdout: "0"
2784 }
2785
2786 issue_4017: {
2787     options = {
2788         pure_getters: "strict",
2789         reduce_vars: true,
2790         unused: true,
2791     }
2792     input: {
2793         var a = 0;
2794         console.log(function f() {
2795             var b = c &= 0;
2796             var c = a++ + (A = a);
2797             var d = c && c[f];
2798         }());
2799     }
2800     expect: {
2801         var a = 0;
2802         console.log(function() {
2803             c &= 0;
2804             var c;
2805             a++,
2806             A = a;
2807         }());
2808     }
2809     expect_stdout: "undefined"
2810 }
2811
2812 issue_4025: {
2813     options = {
2814         collapse_vars: true,
2815         evaluate: true,
2816         passes: 2,
2817         reduce_vars: true,
2818         toplevel: true,
2819         unused: true,
2820     }
2821     input: {
2822         var a = 0, b = 0, c = 0, d = a++;
2823         try {
2824             var e = console.log(c), f = b;
2825         } finally {
2826             var d = b = 1, d = c + 1;
2827             c = 0;
2828         }
2829         console.log(a, b, d);
2830     }
2831     expect: {
2832         var c = 0;
2833         try {
2834             console.log(c);
2835         } finally {
2836             var d = c + 1;
2837             c = 0;
2838         }
2839         console.log(1, 1, d);
2840     }
2841     expect_stdout: [
2842         "0",
2843         "1 1 1",
2844     ]
2845 }
2846
2847 forin_var_1: {
2848     options = {
2849         unused: true,
2850     }
2851     input: {
2852         var k;
2853         for (k in [ 1, 2 ])
2854             console.log(k);
2855         for (k in { PASS: 3 })
2856             console.log(k);
2857         console.log(k);
2858     }
2859     expect: {
2860         for (var k in [ 1, 2 ])
2861             console.log(k);
2862         for (k in { PASS: 3 })
2863             console.log(k);
2864         console.log(k);
2865     }
2866     expect_stdout: [
2867         "0",
2868         "1",
2869         "PASS",
2870         "PASS",
2871     ]
2872 }
2873
2874 forin_var_2: {
2875     options = {
2876         unused: true,
2877     }
2878     input: {
2879         console.log(function() {
2880             switch (0) {
2881               case function() {
2882                     for (a in 0);
2883                 }:
2884                 var b = 0;
2885             }
2886             for (var c = 0; a;);
2887             var a;
2888         }());
2889     }
2890     expect: {
2891         console.log(function() {
2892             switch (0) {
2893               case function() {
2894                     for (a in 0);
2895                 }:
2896             }
2897             for (; a;);
2898             var a;
2899         }());
2900     }
2901     expect_stdout: "undefined"
2902 }
2903
2904 issue_4133: {
2905     options = {
2906         evaluate: true,
2907         merge_vars: true,
2908         pure_getters: "strict",
2909         reduce_vars: true,
2910         toplevel: true,
2911         unused: true,
2912     }
2913     input: {
2914         var a = 1;
2915         var b = [ a-- ], c = b && b[c];
2916         console.log(a);
2917     }
2918     expect: {
2919         var a = 1;
2920         console.log(0);
2921     }
2922     expect_stdout: "0"
2923 }
2924
2925 issue_4144: {
2926     options = {
2927         keep_fargs: false,
2928         reduce_vars: true,
2929         unused: true,
2930     }
2931     input: {
2932         (function(a, b) {
2933             var b = console, c = ++b;
2934         })(console.log("PASS"), 0);
2935     }
2936     expect: {
2937         (function(b) {
2938             b = console,
2939             ++b;
2940         })(console.log("PASS"));
2941     }
2942     expect_stdout: "PASS"
2943 }
2944
2945 issue_4146: {
2946     options = {
2947         reduce_vars: true,
2948         toplevel: true,
2949         unused: true,
2950     }
2951     input: {
2952         function f(a, b) {
2953             function g() {}
2954             var a = g;
2955             var c = b;
2956             c.p;
2957             console.log(typeof a);
2958         }
2959         f("FAIL", 42);
2960     }
2961     expect: {
2962         (function(a, b) {
2963             a = function () {};
2964             var c = b;
2965             c.p;
2966             console.log(typeof a);
2967         })(0, 42);
2968     }
2969     expect_stdout: "function"
2970 }
2971
2972 var_catch_redefined: {
2973     options = {
2974         toplevel: true,
2975         unused: true,
2976     }
2977     input: {
2978         var a = "FAIL";
2979         try {
2980             throw "PASS";
2981         } catch (a) {
2982             function f() {
2983                 return a;
2984             }
2985             console.log(a);
2986         }
2987         f();
2988     }
2989     expect: {
2990         var a = "FAIL";
2991         try {
2992             throw "PASS";
2993         } catch (a) {
2994             function f() {
2995                 return a;
2996             }
2997             console.log(a);
2998         }
2999         f();
3000     }
3001     expect_stdout: "PASS"
3002 }
3003
3004 single_use_catch_redefined: {
3005     options = {
3006         reduce_vars: true,
3007         toplevel: true,
3008         unused: true,
3009     }
3010     input: {
3011         var a = 1;
3012         try {
3013             throw 2;
3014         } catch (a) {
3015             function g() {
3016                 return a;
3017             }
3018         }
3019         console.log(g());
3020     }
3021     expect: {
3022         var a = 1;
3023         try {
3024             throw 2;
3025         } catch (a) {
3026             function g() {
3027                 return a;
3028             }
3029         }
3030         console.log(g());
3031     }
3032     expect_stdout: true
3033 }
3034
3035 issue_4184: {
3036     options = {
3037         reduce_vars: true,
3038         unused: true,
3039     }
3040     input: {
3041         (function() {
3042             var a = function() {}, b = [ a, 1 && b, a = {} ];
3043             try {
3044                 throw 42;
3045             } catch (a) {
3046                 {
3047                     console.log(a);
3048                 }
3049             }
3050         })();
3051     }
3052     expect: {
3053         (function() {
3054             var b = [ function() {}, 1 && b, {} ];
3055             try {
3056                 throw 42;
3057             } catch (a) {
3058                 console.log(a);
3059             }
3060         })();
3061     }
3062     expect_stdout: "42"
3063 }
3064
3065 issue_4235_1: {
3066     options = {
3067         inline: true,
3068         reduce_vars: true,
3069         unused: true,
3070         varify: true,
3071     }
3072     input: {
3073         (function() {
3074             {
3075                 const f = 0;
3076             }
3077             (function f() {
3078                 var f = console.log(f);
3079             })();
3080         })();
3081     }
3082     expect: {
3083         void function() {
3084             var f = console.log(f);
3085         }();
3086     }
3087     expect_stdout: "undefined"
3088 }
3089
3090 issue_4235_2: {
3091     options = {
3092         inline: true,
3093         passes: 2,
3094         reduce_vars: true,
3095         side_effects: true,
3096         unused: true,
3097         varify: true,
3098     }
3099     input: {
3100         (function() {
3101             {
3102                 const f = 0;
3103             }
3104             (function f() {
3105                 var f = console.log(f);
3106             })();
3107         })();
3108     }
3109     expect: {
3110         console.log(void 0);
3111     }
3112     expect_stdout: "undefined"
3113 }
3114
3115 issue_4404: {
3116     options = {
3117         pure_getters: "strict",
3118         unused: true,
3119     }
3120     input: {
3121         function f(a) {
3122             arguments[0] = "PASS";
3123             console.log(a);
3124         }
3125         f("FAIL");
3126     }
3127     expect: {
3128         function f(a) {
3129             arguments[0] = "PASS";
3130             console.log(a);
3131         }
3132         f("FAIL");
3133     }
3134     expect_stdout: "PASS"
3135 }
3136
3137 issue_4413: {
3138     options = {
3139         reduce_vars: true,
3140         unused: true,
3141     }
3142     input: {
3143         console.log(function f(arguments) {
3144             var arguments = function() {};
3145             return arguments.length;
3146         }());
3147     }
3148     expect: {
3149         console.log(function(arguments) {
3150             return function() {}.length;
3151         }());
3152     }
3153     expect_stdout: "0"
3154 }
3155
3156 issue_4464_1: {
3157     options = {
3158         reduce_vars: true,
3159         unused: true,
3160     }
3161     input: {
3162         function f(a) {
3163             var a = function() {};
3164             return [ arguments, a ];
3165         }
3166         console.log(typeof f()[1]);
3167     }
3168     expect: {
3169         function f(a) {
3170             a = function() {};
3171             return [ arguments, a ];
3172         }
3173         console.log(typeof f()[1]);
3174     }
3175     expect_stdout: "function"
3176 }
3177
3178 issue_4464_2: {
3179     options = {
3180         reduce_vars: true,
3181         unused: true,
3182     }
3183     input: {
3184         function f(a) {
3185             var a = function() {};
3186             return [ arguments, a ];
3187         }
3188         console.log(typeof f(42)[0][0]);
3189     }
3190     expect: {
3191         function f(a) {
3192             a = function() {};
3193             return [ arguments, a ];
3194         }
3195         console.log(typeof f(42)[0][0]);
3196     }
3197     expect_stdout: "function"
3198 }
3199
3200 issue_4464_3: {
3201     options = {
3202         reduce_vars: true,
3203         unused: true,
3204     }
3205     input: {
3206         (function a(a) {
3207             var a = function() {};
3208             return [ arguments[0], a ];
3209         })(42).forEach(function(b) {
3210             console.log(typeof b);
3211         });
3212     }
3213     expect: {
3214         (function(a) {
3215             a = function() {};
3216             return [ arguments[0], a ];
3217         })(42).forEach(function(b) {
3218             console.log(typeof b);
3219         });
3220     }
3221     expect_stdout: [
3222         "function",
3223         "function",
3224     ]
3225 }
3226
3227 issue_4558_1: {
3228     options = {
3229         evaluate: true,
3230         pure_getters: true,
3231         reduce_vars: true,
3232         sequences: true,
3233         side_effects: true,
3234         toplevel: true,
3235         unused: true,
3236     }
3237     input: {
3238         var a = 0;
3239         var b = 1, b = c >>>= a;
3240         var c = 0;
3241         b && 0[a++],
3242         console.log(a);
3243     }
3244     expect: {
3245         var a = 0;
3246         var b = c >>>= a;
3247         var c;
3248         b && a++,
3249         console.log(a);
3250     }
3251     expect_stdout: "0"
3252 }
3253
3254 issue_4558_2: {
3255     options = {
3256         evaluate: true,
3257         ie: true,
3258         reduce_vars: true,
3259         unused: true,
3260     }
3261     input: {
3262         (function() {
3263             var a = 1;
3264             var b = (a = NaN) || (console.log("PASS"), 2);
3265             return a;
3266         })();
3267     }
3268     expect: {
3269         (function() {
3270             var a;
3271             (a = NaN) || console.log("PASS");
3272             return a;
3273         })();
3274     }
3275     expect_stdout: "PASS"
3276 }
3277
3278 issue_4662: {
3279     options = {
3280         evaluate: true,
3281         reduce_vars: true,
3282         toplevel: true,
3283         unused: true,
3284     }
3285     input: {
3286         var a = 0;
3287         function f(b, c) {
3288             console.log(b, c);
3289         }
3290         f(++a, a = a, a);
3291     }
3292     expect: {
3293         var a = 0;
3294         (function(b, c) {
3295             console.log(b, c);
3296         })(++a, a = 1);
3297     }
3298     expect_stdout: "1 1"
3299 }
3300
3301 issue_4806_1: {
3302     options = {
3303         evaluate: true,
3304         reduce_vars: true,
3305         toplevel: true,
3306         unused: true,
3307     }
3308     input: {
3309         O = {
3310             f: function() {
3311                 console.log(this === O ? "FAIL" : "PASS");
3312             },
3313         };
3314         var a;
3315         (a = 42, O.f)();
3316         a;
3317     }
3318     expect: {
3319         O = {
3320             f: function() {
3321                 console.log(this === O ? "FAIL" : "PASS");
3322             },
3323         };
3324         (0, O.f)();
3325         42;
3326     }
3327     expect_stdout: "PASS"
3328 }
3329
3330 issue_4806_2: {
3331     options = {
3332         sequences: true,
3333         toplevel: true,
3334         unused: true,
3335     }
3336     input: {
3337         O = {
3338             f: function() {
3339                 console.log(this === O ? "FAIL" : "PASS");
3340             },
3341         };
3342         var a;
3343         (a = 42, O.f)();
3344         a;
3345     }
3346     expect: {
3347         O = {
3348             f: function() {
3349                 console.log(this === O ? "FAIL" : "PASS");
3350             },
3351         },
3352         (0, O.f)();
3353     }
3354     expect_stdout: "PASS"
3355 }
3356
3357 issue_4806_3: {
3358     options = {
3359         side_effects: true,
3360         toplevel: true,
3361         unused: true,
3362     }
3363     input: {
3364         O = {
3365             f: function() {
3366                 console.log(this === O ? "FAIL" : "PASS");
3367             },
3368         };
3369         var a;
3370         (a = 42, O.f)();
3371         a;
3372     }
3373     expect: {
3374         O = {
3375             f: function() {
3376                 console.log(this === O ? "FAIL" : "PASS");
3377             },
3378         };
3379         (0, O.f)();
3380     }
3381     expect_stdout: "PASS"
3382 }
3383
3384 issue_4834: {
3385     options = {
3386         inline: true,
3387         keep_fargs: false,
3388         pure_getters: "strict",
3389         reduce_vars: true,
3390         side_effects: true,
3391         toplevel: true,
3392         unused: true,
3393     }
3394     input: {
3395         try {
3396             new function(a, b) {
3397                 b;
3398                 b.p;
3399             }(42);
3400         } catch (e) {
3401             console.log("PASS");
3402         }
3403     }
3404     expect: {
3405         try {
3406             b.p;
3407         } catch (e) {
3408             console.log("PASS");
3409         }
3410         var b;
3411     }
3412     expect_stdout: "PASS"
3413 }
3414
3415 issue_4912_1: {
3416     options = {
3417         pure_getters: "strict",
3418         reduce_vars: true,
3419         toplevel: true,
3420         unused: true,
3421     }
3422     input: {
3423         var a = A = function() {};
3424         A;
3425         a.prototype = {
3426             f: function() {
3427                 console.log("PASS");
3428             },
3429         };
3430         new A().f();
3431     }
3432     expect: {
3433         var a = A = function() {};
3434         A;
3435         a.prototype = {
3436             f: function() {
3437                 console.log("PASS");
3438             },
3439         };
3440         new A().f();
3441     }
3442     expect_stdout: "PASS"
3443 }
3444
3445 issue_4912_2: {
3446     options = {
3447         pure_getters: "strict",
3448         unused: true,
3449     }
3450     input: {
3451         console.log(function() {
3452             var g, f = function() {};
3453             f.p = {};
3454             (g = f.p.q = function() {}).r = "PASS";
3455             return f;
3456         }().p.q.r);
3457     }
3458     expect: {
3459         console.log(function() {
3460             var g, f = function() {};
3461             f.p = {};
3462             (f.p.q = function() {}).r = "PASS";
3463             return f;
3464         }().p.q.r);
3465     }
3466     expect_stdout: "PASS"
3467 }
3468
3469 issue_4912_3: {
3470     options = {
3471         pure_getters: "strict",
3472         reduce_vars: true,
3473         side_effects: true,
3474         unused: true,
3475     }
3476     input: {
3477         console.log(function(f, g) {
3478             f = function() {};
3479             f.p = {};
3480             g = f.p.q = function() {};
3481             g.r = "PASS";
3482             return f;
3483         }().p.q.r);
3484     }
3485     expect: {
3486         console.log(function(f, g) {
3487             f = function() {};
3488             f.p = {};
3489             g = f.p.q = function() {};
3490             g.r = "PASS";
3491             return f;
3492         }().p.q.r);
3493     }
3494     expect_stdout: "PASS"
3495 }
3496
3497 issue_5079: {
3498     options = {
3499         collapse_vars: true,
3500         pure_getters: "strict",
3501         reduce_vars: true,
3502         toplevel: true,
3503         unused: true,
3504     }
3505     input: {
3506         var a;
3507         do {
3508             (a = 123456).p = a;
3509             a.q = null;
3510         } while (console.log("PASS"));
3511     }
3512     expect: {
3513         do {
3514             0, 0, null;
3515         } while (console.log("PASS"));
3516     }
3517     expect_stdout: "PASS"
3518 }
3519
3520 issue_5224: {
3521     options = {
3522         evaluate: true,
3523         keep_fargs: false,
3524         reduce_vars: true,
3525         toplevel: true,
3526         unused: true,
3527     }
3528     input: {
3529         function f() {
3530             try {
3531                 var b = function() {
3532                     var a = "FAIL 1";
3533                     null && a;
3534                     a = console.log(a);
3535                 }(new function(c, d) {
3536                     console.log(d);
3537                     a;
3538                 }("FAIL 2", Infinity));
3539             } finally {
3540                 return f;
3541             }
3542         }
3543         f();
3544     }
3545     expect: {
3546         (function f() {
3547             try {
3548                 (function() {
3549                     var a = "FAIL 1";
3550                     null;
3551                     a = console.log(a);
3552                 })(function() {
3553                     console.log(1 / 0);
3554                     a;
3555                 }());
3556             } finally {
3557                 return f;
3558             }
3559         })();
3560     }
3561     expect_stdout: "Infinity"
3562 }