diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-06-15 16:51:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-15 23:51:53 +0800 |
commit | 7880568d157fcd1c15c0f392e4646e01de363afd (patch) | |
tree | 83167c0baafa2dc84ac0e0abdc5c986d55b74bba | |
parent | 21fc8f4630bccdb8b0a33747c2de8fd377e83138 (diff) | |
download | tracifyjs-7880568d157fcd1c15c0f392e4646e01de363afd.tar.gz tracifyjs-7880568d157fcd1c15c0f392e4646e01de363afd.zip |
fix corner case in `switches` (#5013)
fixes #5012
-rw-r--r-- | lib/compress.js | 38 | ||||
-rw-r--r-- | test/compress/merge_vars.js | 2 | ||||
-rw-r--r-- | test/compress/switches.js | 46 |
3 files changed, 55 insertions, 31 deletions
diff --git a/lib/compress.js b/lib/compress.js index ed3b5a39..22434f62 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8422,7 +8422,7 @@ merge(Compressor.prototype, { var default_branch; var exact_match; var side_effects = []; - for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { + for (var i = 0, len = self.body.length; i < len; i++) { branch = self.body[i]; if (branch instanceof AST_Default) { var prev = body[body.length - 1]; @@ -8445,16 +8445,21 @@ merge(Compressor.prototype, { continue; } if (!(equals instanceof AST_Node)) { - exact_match = branch; if (default_branch) { var default_index = body.indexOf(default_branch); body.splice(default_index, 1); eliminate_branch(default_branch, body[default_index - 1]); default_branch = null; } + if (exp.has_side_effects(compressor)) { + exact_match = branch; + } else { + default_branch = branch = make_node(AST_Default, branch, branch); + } + while (++i < len) eliminate_branch(self.body[i], branch); } } - if (exact_match || i == len - 1 || aborts(branch)) { + if (i + 1 >= len || aborts(branch)) { var prev = body[body.length - 1]; var statements = branch.body; if (aborts(prev)) switch (prev.body.length - statements.length) { @@ -8479,7 +8484,6 @@ merge(Compressor.prototype, { } body.push(branch); } - while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]); if (side_effects.length && !exact_match) { body.push(make_node(AST_Case, self, { expression: make_sequence(self, side_effects), body: [] })); } @@ -8506,23 +8510,17 @@ merge(Compressor.prototype, { })); return make_node(AST_BlockStatement, self, { body: decl }).optimize(compressor); } - if (branch === default_branch || branch === exact_match && !branch.expression.has_side_effects(compressor)) { - while (branch = body[body.length - 2]) { - if (branch instanceof AST_Default) break; - if (!has_declarations_only(branch)) break; - var exp = branch.expression; - if (exp.has_side_effects(compressor)) { - var prev = body[body.length - 3]; - if (prev && !aborts(prev)) break; - if (exact_match) { - exact_match.expression = make_sequence(self, [ exp, exact_match.expression ]); - } else { - default_branch.body.unshift(make_node(AST_SimpleStatement, self, { body: exp })); - } - } - eliminate_branch(branch); - body.splice(-2, 1); + if (branch === default_branch) while (branch = body[body.length - 2]) { + if (branch instanceof AST_Default) break; + if (!has_declarations_only(branch)) break; + var exp = branch.expression; + if (exp.has_side_effects(compressor)) { + var prev = body[body.length - 3]; + if (prev && !aborts(prev)) break; + default_branch.body.unshift(make_node(AST_SimpleStatement, self, { body: exp })); } + eliminate_branch(branch); + body.splice(-2, 1); } body[0].body = decl.concat(body[0].body); self.body = body; diff --git a/test/compress/merge_vars.js b/test/compress/merge_vars.js index dc526c5f..e29298ed 100644 --- a/test/compress/merge_vars.js +++ b/test/compress/merge_vars.js @@ -3075,7 +3075,7 @@ issue_4237_2: { console.log(function(a) { do { switch (0) { - case 0: + default: var b = a++; if (b) return "FAIL"; diff --git a/test/compress/switches.js b/test/compress/switches.js index af81b54c..3c43612e 100644 --- a/test/compress/switches.js +++ b/test/compress/switches.js @@ -113,7 +113,7 @@ constant_switch_5: { // the break inside the if ruins our job // we can still get rid of irrelevant cases. switch (1) { - case 1: + default: x(); if (foo) break; y(); @@ -501,7 +501,8 @@ drop_case_5: { } expect: { switch (42) { - case (void console.log("PASS 1"), 42): + default: + void console.log("PASS 1"); console.log("PASS 2"); } } @@ -554,7 +555,8 @@ drop_case_7: { } expect: { switch (2) { - case (console.log("PASS 1"), 1, 2): + default: + console.log("PASS 1"), 1; console.log("PASS 2"); } } @@ -920,7 +922,7 @@ issue_1680_1: { case f(0): case f(1): f(2); - case 2: + default: f(5); } } @@ -1183,7 +1185,6 @@ issue_2535: { } expect: { w(), 42; - 42; y(); z(); } @@ -1209,7 +1210,6 @@ issue_1750: { expect: { var a = 0, b = 1; true; - a, true; b = 2; console.log(a, b); } @@ -1463,7 +1463,7 @@ issue_5008_1: { expect: { console.log(function f() { switch (f) { - case f: + default: return "PASS"; } }()); @@ -1492,7 +1492,7 @@ issue_5008_2: { expect: { console.log(function(a) { switch (a) { - case a: + default: return "PASS"; } }([])); @@ -1521,7 +1521,7 @@ issue_5008_3: { expect: { console.log(function(a) { switch (a) { - case a: + default: return "PASS"; } }({})); @@ -1549,7 +1549,7 @@ issue_5008_4: { expect: { console.log(function(a) { switch (a) { - case a: + default: return "PASS"; } }(/foo/)); @@ -1582,3 +1582,29 @@ issue_5010: { } expect_stdout: "PASS" } + +issue_5012: { + options = { + dead_code: true, + evaluate: true, + switches: true, + } + input: { + switch (void 0) { + case console.log("PASS"): + break; + case void 0: + case 42: + console.log("FAIL"); + } + } + expect: { + switch (void 0) { + case console.log("PASS"): + break; + default: + console.log("FAIL"); + } + } + expect_stdout: "PASS" +} |