diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-06-15 11:27:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-15 18:27:55 +0800 |
commit | bf76e357723daa4fc00004a10b2b3de82a2bf33e (patch) | |
tree | 02bfcdaf727adf43a6abf70b3fb92f08f547df96 | |
parent | ac1262dc9708db36721349f1d3d03fc2113f2add (diff) | |
download | tracifyjs-bf76e357723daa4fc00004a10b2b3de82a2bf33e.tar.gz tracifyjs-bf76e357723daa4fc00004a10b2b3de82a2bf33e.zip |
fix corner case in `switches` (#5009)
fixes #5008
-rw-r--r-- | lib/compress.js | 39 | ||||
-rw-r--r-- | test/compress/switches.js | 115 |
2 files changed, 128 insertions, 26 deletions
diff --git a/lib/compress.js b/lib/compress.js index 675dc96c..44098d74 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8108,10 +8108,6 @@ merge(Compressor.prototype, { cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true); } else if (cond) { self.condition = null; - } else if (!compressor.option("dead_code")) { - var orig = self.condition; - self.condition = make_node_from_constant(cond, self.condition); - self.condition = best_of_expression(self.condition.transform(compressor), orig); } if (!cond) { if (compressor.option("dead_code")) { @@ -8226,13 +8222,8 @@ merge(Compressor.prototype, { // one of the blocks. note, statically determined implies // “has no side effects”; also it doesn't work for cases like // `x && true`, though it probably should. - var cond = self.condition.evaluate(compressor); - if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) { - var orig = self.condition; - self.condition = make_node_from_constant(cond, orig); - self.condition = best_of_expression(self.condition.transform(compressor), orig); - } if (compressor.option("dead_code")) { + var cond = self.condition.evaluate(compressor); if (cond instanceof AST_Node) { cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true); } @@ -8424,16 +8415,7 @@ merge(Compressor.prototype, { OPT(AST_Switch, function(self, compressor) { if (!compressor.option("switches")) return self; - var value = self.expression.evaluate(compressor); - if (!(value instanceof AST_Node)) { - var orig = self.expression; - self.expression = make_node_from_constant(value, orig); - self.expression = best_of_expression(self.expression.transform(compressor), orig); - } if (!compressor.option("dead_code")) return self; - if (value instanceof AST_Node) { - value = self.expression.evaluate(compressor, true); - } var body = []; var branch; var decl = []; @@ -8450,10 +8432,19 @@ merge(Compressor.prototype, { } else { default_branch = branch; } - } else if (!(value instanceof AST_Node)) { + } else { var exp = branch.expression; - var val = exp.evaluate(compressor, true); - if (val === value) { + var equals = make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: exp, + }).evaluate(compressor, true); + if (!equals) { + if (exp.has_side_effects(compressor)) side_effects.push(exp); + eliminate_branch(branch, body[body.length - 1]); + continue; + } + if (!(equals instanceof AST_Node)) { exact_match = branch; if (default_branch) { var default_index = body.indexOf(default_branch); @@ -8461,10 +8452,6 @@ merge(Compressor.prototype, { eliminate_branch(default_branch, body[default_index - 1]); default_branch = null; } - } else if (!(val instanceof AST_Node)) { - if (exp.has_side_effects(compressor)) side_effects.push(exp); - eliminate_branch(branch, body[body.length - 1]); - continue; } } if (exact_match || i == len - 1 || aborts(branch)) { diff --git a/test/compress/switches.js b/test/compress/switches.js index 955fd68a..cbaa0644 100644 --- a/test/compress/switches.js +++ b/test/compress/switches.js @@ -1441,3 +1441,118 @@ issue_4059: { } expect_stdout: "PASS" } + +issue_5008_1: { + options = { + dead_code: true, + evaluate: true, + reduce_vars: true, + switches: true, + unsafe: true, + } + input: { + console.log(function f() { + switch (f) { + case f: + return "PASS"; + default: + return "FAIL"; + } + }()); + } + expect: { + console.log(function f() { + switch (f) { + case f: + return "PASS"; + } + }()); + } + expect_stdout: "PASS" +} + +issue_5008_2: { + options = { + dead_code: true, + evaluate: true, + reduce_vars: true, + switches: true, + unsafe: true, + } + input: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + default: + return "FAIL"; + } + }([])); + } + expect: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + } + }([])); + } + expect_stdout: "PASS" +} + +issue_5008_3: { + options = { + dead_code: true, + evaluate: true, + reduce_vars: true, + switches: true, + unsafe: true, + } + input: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + default: + return "FAIL"; + } + }({})); + } + expect: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + } + }({})); + } + expect_stdout: "PASS" +} + +issue_5008_4: { + options = { + dead_code: true, + evaluate: true, + reduce_vars: true, + switches: true, + } + input: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + default: + return "FAIL"; + } + }(/foo/)); + } + expect: { + console.log(function(a) { + switch (a) { + case a: + return "PASS"; + } + }(/foo/)); + } + expect_stdout: "PASS" +} |