From: Alex Lam S.L Date: Sun, 2 Apr 2017 06:52:25 +0000 (+0800) Subject: fix corner cases in switch and undefined (#1762) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f7ca4f229795f87674d32e2df3de3cf1f8367a39;p=UglifyJS.git fix corner cases in switch and undefined (#1762) - fix side effects in switch condition for singular blocks - fix `undefined` confusion with local variable - gate `OPT(AST_Switch)` with `switches` fixes #1758 fixes #1759 --- diff --git a/lib/compress.js b/lib/compress.js index fc11840d..5776fb88 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -77,6 +77,7 @@ function Compressor(options, false_by_default) { screw_ie8 : true, sequences : !false_by_default, side_effects : !false_by_default, + switches : !false_by_default, top_retain : null, toplevel : !!(options && options["top_retain"]), unsafe : false, @@ -1054,7 +1055,7 @@ merge(Compressor.prototype, { stat.value = cons_seq(stat.value); } else if (stat instanceof AST_Exit) { - stat.value = cons_seq(make_node(AST_Undefined, stat)); + stat.value = cons_seq(make_node(AST_Undefined, stat).transform(compressor)); } else if (stat instanceof AST_Switch) { stat.expression = cons_seq(stat.expression); @@ -2526,6 +2527,7 @@ merge(Compressor.prototype, { }); OPT(AST_Switch, function(self, compressor){ + if (!compressor.option("switches")) return self; var branch; var value = self.expression.evaluate(compressor); if (value !== self.expression) { @@ -2599,7 +2601,15 @@ merge(Compressor.prototype, { has_break = true; }); self.walk(tw); - if (!has_break) return make_node(AST_BlockStatement, self, body[0]).optimize(compressor); + if (!has_break) { + body = body[0].body.slice(); + body.unshift(make_node(AST_SimpleStatement, self.expression, { + body: self.expression + })); + return make_node(AST_BlockStatement, self, { + body: body + }).optimize(compressor); + } } return self; @@ -2904,7 +2914,7 @@ merge(Compressor.prototype, { if (name instanceof AST_SymbolRef && name.name == "console" && name.undeclared()) { - return make_node(AST_Undefined, self).transform(compressor); + return make_node(AST_Undefined, self).optimize(compressor); } } } diff --git a/test/compress/issue-1750.js b/test/compress/issue-1750.js index 53a78e65..c1448afe 100644 --- a/test/compress/issue-1750.js +++ b/test/compress/issue-1750.js @@ -2,6 +2,7 @@ case_1: { options = { dead_code: true, evaluate: true, + switches: true, } input: { var a = 0, b = 1; diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index 87942ab9..cdc4ef20 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1399,6 +1399,8 @@ issue_1670_1: { evaluate: true, dead_code: true, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { @@ -1429,6 +1431,8 @@ issue_1670_2: { dead_code: true, passes: 2, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { @@ -1458,6 +1462,8 @@ issue_1670_3: { evaluate: true, dead_code: true, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { @@ -1488,6 +1494,8 @@ issue_1670_4: { dead_code: true, passes: 2, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { @@ -1516,6 +1524,8 @@ issue_1670_5: { evaluate: true, keep_fargs: false, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { @@ -1544,6 +1554,8 @@ issue_1670_6: { evaluate: true, keep_fargs: false, reduce_vars: true, + side_effects: true, + switches: true, unused: true, } input: { diff --git a/test/compress/sequences.js b/test/compress/sequences.js index f1fa0e87..b3c54635 100644 --- a/test/compress/sequences.js +++ b/test/compress/sequences.js @@ -440,3 +440,29 @@ func_def_5: { } expect_stdout: "true" } + +issue_1758: { + options = { + sequences: true, + side_effects: true, + } + input: { + console.log(function(c) { + var undefined = 42; + return function() { + c--; + c--, c.toString(); + return; + }(); + }()); + } + expect: { + console.log(function(c) { + var undefined = 42; + return function() { + return c--, c--, c.toString(), void 0; + }(); + }()); + } + expect_stdout: "undefined" +} diff --git a/test/compress/switch.js b/test/compress/switch.js index 82d725f2..03c1e00a 100644 --- a/test/compress/switch.js +++ b/test/compress/switch.js @@ -1,5 +1,10 @@ constant_switch_1: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { switch (1+1) { case 1: foo(); break; @@ -13,7 +18,12 @@ constant_switch_1: { } constant_switch_2: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { switch (1) { case 1: foo(); @@ -28,7 +38,12 @@ constant_switch_2: { } constant_switch_3: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { switch (10) { case 1: foo(); @@ -44,7 +59,12 @@ constant_switch_3: { } constant_switch_4: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { switch (2) { case 1: @@ -65,7 +85,12 @@ constant_switch_4: { } constant_switch_5: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { switch (1) { case 1: @@ -94,7 +119,12 @@ constant_switch_5: { } constant_switch_6: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { OUT: { foo(); @@ -123,7 +153,12 @@ constant_switch_6: { } constant_switch_7: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { OUT: { foo(); @@ -161,7 +196,12 @@ constant_switch_7: { } constant_switch_8: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { OUT: switch (1) { case 1: @@ -185,7 +225,12 @@ constant_switch_8: { } constant_switch_9: { - options = { dead_code: true, evaluate: true }; + options = { + dead_code: true, + evaluate: true, + side_effects: true, + switches: true, + } input: { OUT: switch (1) { case 1: @@ -210,7 +255,10 @@ constant_switch_9: { } drop_default_1: { - options = { dead_code: true }; + options = { + dead_code: true, + switches: true, + } input: { switch (foo) { case 'bar': baz(); @@ -225,7 +273,10 @@ drop_default_1: { } drop_default_2: { - options = { dead_code: true }; + options = { + dead_code: true, + switches: true, + } input: { switch (foo) { case 'bar': baz(); break; @@ -241,7 +292,10 @@ drop_default_2: { } keep_default: { - options = { dead_code: true }; + options = { + dead_code: true, + switches: true, + } input: { switch (foo) { case 'bar': baz(); @@ -263,6 +317,8 @@ issue_1663: { options = { dead_code: true, evaluate: true, + side_effects: true, + switches: true, } input: { var a = 100, b = 10; @@ -294,6 +350,7 @@ issue_1663: { drop_case: { options = { dead_code: true, + switches: true, } input: { switch (foo) { @@ -312,6 +369,7 @@ drop_case: { keep_case: { options = { dead_code: true, + switches: true, } input: { switch (foo) { @@ -332,6 +390,7 @@ issue_376: { options = { dead_code: true, evaluate: true, + switches: true, } input: { switch (true) { @@ -354,6 +413,7 @@ issue_376: { issue_441_1: { options = { dead_code: true, + switches: true, } input: { switch (foo) { @@ -381,6 +441,7 @@ issue_441_1: { issue_441_2: { options = { dead_code: true, + switches: true, } input: { switch (foo) { @@ -414,6 +475,8 @@ issue_1674: { options = { dead_code: true, evaluate: true, + side_effects: true, + switches: true, } input: { switch (0) { @@ -435,6 +498,7 @@ issue_1679: { options = { dead_code: true, evaluate: true, + switches: true, } input: { var a = 100, b = 10; @@ -482,6 +546,7 @@ issue_1680_1: { options = { dead_code: true, evaluate: true, + switches: true, } input: { function f(x) { @@ -522,6 +587,7 @@ issue_1680_1: { issue_1680_2: { options = { dead_code: true, + switches: true, } input: { var a = 100, b = 10; @@ -557,6 +623,7 @@ issue_1680_2: { issue_1690_1: { options = { dead_code: true, + switches: true, } input: { switch (console.log("PASS")) {} @@ -570,6 +637,7 @@ issue_1690_1: { issue_1690_2: { options = { dead_code: false, + switches: true, } input: { switch (console.log("PASS")) {} @@ -585,6 +653,7 @@ if_switch_typeof: { conditionals: true, dead_code: true, side_effects: true, + switches: true, } input: { if (a) switch(typeof b) {} @@ -597,6 +666,7 @@ if_switch_typeof: { issue_1698: { options = { side_effects: true, + switches: true, } input: { var a = 1; @@ -618,6 +688,7 @@ issue_1698: { issue_1705_1: { options = { dead_code: true, + switches: true, } input: { var a = 0; @@ -646,6 +717,7 @@ issue_1705_2: { reduce_vars: true, sequences: true, side_effects: true, + switches: true, toplevel: true, unused: true, } @@ -666,6 +738,7 @@ issue_1705_2: { issue_1705_3: { options = { dead_code: true, + switches: true, } input: { switch (a) { @@ -721,3 +794,25 @@ beautify: { "}", ] } + +issue_1758: { + options = { + dead_code: true, + switches: true, + } + input: { + var a = 1, b = 2; + switch (a--) { + default: + b++; + } + console.log(a, b); + } + expect: { + var a = 1, b = 2; + a--; + b++; + console.log(a, b); + } + expect_stdout: "0 3" +}