fix corner case in switches (#3585)
This commit is contained in:
@@ -4872,25 +4872,23 @@ merge(Compressor.prototype, {
|
|||||||
prev.body = [];
|
prev.body = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (default_branch
|
body.push(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
|
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]) {
|
while (branch = body[body.length - 1]) {
|
||||||
var stat = branch.body[branch.body.length - 1];
|
var stat = branch.body[branch.body.length - 1];
|
||||||
if (is_break(stat, compressor)) branch.body.pop();
|
if (is_break(stat, compressor)) branch.body.pop();
|
||||||
if (branch.body.length || branch instanceof AST_Case
|
if (branch === default_branch) {
|
||||||
&& (default_branch || branch.expression.has_side_effects(compressor))) break;
|
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.pop() === default_branch) default_branch = null;
|
||||||
}
|
}
|
||||||
if (body.length == 0) {
|
if (body.length == 0) {
|
||||||
@@ -4900,6 +4898,8 @@ merge(Compressor.prototype, {
|
|||||||
}))
|
}))
|
||||||
}).optimize(compressor);
|
}).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)) {
|
if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
|
||||||
var has_break = false;
|
var has_break = false;
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
@@ -4929,6 +4929,16 @@ merge(Compressor.prototype, {
|
|||||||
return node instanceof AST_Break && tw.loopcontrol_target(node) === self;
|
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) {
|
function eliminate_branch(branch, prev) {
|
||||||
if (prev && !aborts(prev)) {
|
if (prev && !aborts(prev)) {
|
||||||
prev.body = prev.body.concat(branch.body);
|
prev.body = prev.body.concat(branch.body);
|
||||||
|
|||||||
@@ -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: {
|
keep_case: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
@@ -521,7 +572,7 @@ issue_1674: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1679_1: {
|
issue_1679: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -548,34 +599,6 @@ issue_1679_1: {
|
|||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 100, b = 10;
|
|
||||||
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;
|
var a = 100, b = 10;
|
||||||
function f() {
|
function f() {
|
||||||
switch (--b) {
|
switch (--b) {
|
||||||
@@ -589,23 +612,6 @@ issue_1679_2: {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (a++):
|
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();
|
f();
|
||||||
@@ -998,3 +1004,27 @@ drop_switch_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user