aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-11-14 02:29:55 +0800
committerGitHub <noreply@github.com>2019-11-14 02:29:55 +0800
commit910799ca9921ed435df3fd149a1fb2ab77dedbc5 (patch)
tree9197b7f7f2249962483aae6ac8fe0322a08fb3a1
parent4bd36dc8da23ad31eba45376e861784ba8568379 (diff)
downloadtracifyjs-910799ca9921ed435df3fd149a1fb2ab77dedbc5.tar.gz
tracifyjs-910799ca9921ed435df3fd149a1fb2ab77dedbc5.zip
fix corner case in `switches` (#3585)
-rw-r--r--lib/compress.js38
-rw-r--r--test/compress/switch.js122
2 files changed, 100 insertions, 60 deletions
diff --git a/lib/compress.js b/lib/compress.js
index e97427bc..668293d2 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4872,25 +4872,23 @@ merge(Compressor.prototype, {
prev.body = [];
}
}
- if (default_branch
- && default_branch.body.length == 0
- && body[body.length - 1] === default_branch
- && !branch.expression.has_side_effects(compressor)) {
- default_branch.body = branch.body.slice();
- } else {
- body.push(branch);
- }
+ body.push(branch);
}
while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
- if (body.length > 0) {
- body[0].body = decl.concat(body[0].body);
- }
- self.body = body;
while (branch = body[body.length - 1]) {
var stat = branch.body[branch.body.length - 1];
if (is_break(stat, compressor)) branch.body.pop();
- if (branch.body.length || branch instanceof AST_Case
- && (default_branch || branch.expression.has_side_effects(compressor))) break;
+ if (branch === default_branch) {
+ if (!is_body_empty(branch)) break;
+ } else if (branch.expression.has_side_effects(compressor)) {
+ break;
+ } else if (default_branch) {
+ if (!is_body_empty(default_branch)) break;
+ if (body[body.length - 2] !== default_branch) break;
+ default_branch.body = default_branch.body.concat(branch.body);
+ branch.body = [];
+ } else if (!is_body_empty(branch)) break;
+ eliminate_branch(branch);
if (body.pop() === default_branch) default_branch = null;
}
if (body.length == 0) {
@@ -4900,6 +4898,8 @@ merge(Compressor.prototype, {
}))
}).optimize(compressor);
}
+ body[0].body = decl.concat(body[0].body);
+ self.body = body;
if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
var has_break = false;
var tw = new TreeWalker(function(node) {
@@ -4929,6 +4929,16 @@ merge(Compressor.prototype, {
return node instanceof AST_Break && tw.loopcontrol_target(node) === self;
}
+ function is_body_empty(branch) {
+ return all(branch.body, function(stat) {
+ return is_empty(stat)
+ || stat instanceof AST_Defun
+ || stat instanceof AST_Var && all(stat.definitions, function(var_def) {
+ return !var_def.value;
+ });
+ });
+ }
+
function eliminate_branch(branch, prev) {
if (prev && !aborts(prev)) {
prev.body = prev.body.concat(branch.body);
diff --git a/test/compress/switch.js b/test/compress/switch.js
index b41247b4..1de676e3 100644
--- a/test/compress/switch.js
+++ b/test/compress/switch.js
@@ -393,6 +393,57 @@ drop_case_2: {
}
}
+drop_case_3: {
+ options = {
+ dead_code: true,
+ switches: true,
+ }
+ input: {
+ var c = "PASS";
+ switch ({}.p) {
+ default:
+ case void 0:
+ break;
+ case c = "FAIL":
+ }
+ console.log(c);
+ }
+ expect: {
+ var c = "PASS";
+ switch ({}.p) {
+ default:
+ case void 0:
+ break;
+ case c = "FAIL":
+ }
+ console.log(c);
+ }
+ expect_stdout: "PASS"
+}
+
+drop_case_4: {
+ options = {
+ dead_code: true,
+ switches: true,
+ }
+ input: {
+ switch (0) {
+ case [ a, typeof b ]:
+ default:
+ var a;
+ }
+ console.log("PASS");
+ }
+ expect: {
+ switch (0) {
+ case [ a, typeof b ]:
+ var a;
+ }
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+}
+
keep_case: {
options = {
dead_code: true,
@@ -521,7 +572,7 @@ issue_1674: {
expect_stdout: "PASS"
}
-issue_1679_1: {
+issue_1679: {
options = {
dead_code: true,
evaluate: true,
@@ -552,34 +603,6 @@ issue_1679_1: {
function f() {
switch (--b) {
default:
- break;
- case b--:
- switch (0) {
- default:
- case a--:
- }
- break;
- case (a++):
- }
- }
- f();
- console.log(a, b);
- }
- expect_stdout: "99 8"
-}
-
-issue_1679_2: {
- options = {
- dead_code: true,
- evaluate: true,
- passes: 2,
- switches: true,
- }
- input: {
- var a = 100, b = 10;
- function f() {
- switch (--b) {
- default:
case !function x() {}:
break;
case b--:
@@ -589,23 +612,6 @@ issue_1679_2: {
}
break;
case (a++):
- break;
- }
- }
- f();
- console.log(a, b);
- }
- expect: {
- var a = 100, b = 10;
- function f() {
- switch (--b) {
- case b--:
- switch (0) {
- default:
- case a--:
- }
- break;
- case (a++):
}
}
f();
@@ -998,3 +1004,27 @@ drop_switch_3: {
}
expect_stdout: "PASS"
}
+
+drop_switch_4: {
+ options = {
+ dead_code: true,
+ switches: true,
+ }
+ input: {
+ var a = "FAIL";
+ switch (0) {
+ default:
+ case a:
+ var b = a = "PASS";
+ break;
+ }
+ console.log(a);
+ }
+ expect: {
+ var a = "FAIL";
+ 0;
+ var b = a = "PASS";
+ console.log(a);
+ }
+ expect_stdout: "PASS"
+}