aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-06-15 11:27:55 +0100
committerGitHub <noreply@github.com>2021-06-15 18:27:55 +0800
commitbf76e357723daa4fc00004a10b2b3de82a2bf33e (patch)
tree02bfcdaf727adf43a6abf70b3fb92f08f547df96
parentac1262dc9708db36721349f1d3d03fc2113f2add (diff)
downloadtracifyjs-bf76e357723daa4fc00004a10b2b3de82a2bf33e.tar.gz
tracifyjs-bf76e357723daa4fc00004a10b2b3de82a2bf33e.zip
fix corner case in `switches` (#5009)
fixes #5008
-rw-r--r--lib/compress.js39
-rw-r--r--test/compress/switches.js115
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"
+}