parent
6fc7a2ab6a
commit
498ac83541
|
|
@ -8424,7 +8424,6 @@ merge(Compressor.prototype, {
|
||||||
|
|
||||||
OPT(AST_Switch, function(self, compressor) {
|
OPT(AST_Switch, function(self, compressor) {
|
||||||
if (!compressor.option("switches")) return self;
|
if (!compressor.option("switches")) return self;
|
||||||
var branch;
|
|
||||||
var value = self.expression.evaluate(compressor);
|
var value = self.expression.evaluate(compressor);
|
||||||
if (!(value instanceof AST_Node)) {
|
if (!(value instanceof AST_Node)) {
|
||||||
var orig = self.expression;
|
var orig = self.expression;
|
||||||
|
|
@ -8435,10 +8434,12 @@ merge(Compressor.prototype, {
|
||||||
if (value instanceof AST_Node) {
|
if (value instanceof AST_Node) {
|
||||||
value = self.expression.evaluate(compressor, true);
|
value = self.expression.evaluate(compressor, true);
|
||||||
}
|
}
|
||||||
var decl = [];
|
|
||||||
var body = [];
|
var body = [];
|
||||||
|
var branch;
|
||||||
|
var decl = [];
|
||||||
var default_branch;
|
var default_branch;
|
||||||
var exact_match;
|
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 && !exact_match; i++) {
|
||||||
branch = self.body[i];
|
branch = self.body[i];
|
||||||
if (branch instanceof AST_Default) {
|
if (branch instanceof AST_Default) {
|
||||||
|
|
@ -8450,13 +8451,9 @@ merge(Compressor.prototype, {
|
||||||
default_branch = branch;
|
default_branch = branch;
|
||||||
}
|
}
|
||||||
} else if (!(value instanceof AST_Node)) {
|
} else if (!(value instanceof AST_Node)) {
|
||||||
var exp = branch.expression.evaluate(compressor);
|
var exp = branch.expression;
|
||||||
if (!(exp instanceof AST_Node) && exp !== value) {
|
var val = exp.evaluate(compressor, true);
|
||||||
eliminate_branch(branch, body[body.length - 1]);
|
if (val === value) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (exp instanceof AST_Node) exp = branch.expression.evaluate(compressor, true);
|
|
||||||
if (exp === value) {
|
|
||||||
exact_match = branch;
|
exact_match = branch;
|
||||||
if (default_branch) {
|
if (default_branch) {
|
||||||
var default_index = body.indexOf(default_branch);
|
var default_index = body.indexOf(default_branch);
|
||||||
|
|
@ -8464,18 +8461,41 @@ merge(Compressor.prototype, {
|
||||||
eliminate_branch(default_branch, body[default_index - 1]);
|
eliminate_branch(default_branch, body[default_index - 1]);
|
||||||
default_branch = null;
|
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 (aborts(branch)) {
|
if (exact_match || i == len - 1 || aborts(branch)) {
|
||||||
var prev = body[body.length - 1];
|
var prev = body[body.length - 1];
|
||||||
if (aborts(prev) && prev.body.length == branch.body.length
|
var statements = branch.body;
|
||||||
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
|
if (aborts(prev)) switch (prev.body.length - statements.length) {
|
||||||
prev.body = [];
|
case 1:
|
||||||
|
var stat = prev.body[prev.body.length - 1];
|
||||||
|
if (!is_break(stat, compressor)) break;
|
||||||
|
statements = statements.concat(stat);
|
||||||
|
case 0:
|
||||||
|
var prev_block = make_node(AST_BlockStatement, prev, prev);
|
||||||
|
var next_block = make_node(AST_BlockStatement, branch, { body: statements });
|
||||||
|
if (prev_block.equivalent_to(next_block)) prev.body = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (side_effects.length) {
|
||||||
|
if (branch instanceof AST_Default) {
|
||||||
|
body.push(make_node(AST_Case, self, { expression: make_sequence(self, side_effects), body: [] }));
|
||||||
|
} else {
|
||||||
|
side_effects.push(branch.expression);
|
||||||
|
branch.expression = make_sequence(self, side_effects);
|
||||||
|
}
|
||||||
|
side_effects = [];
|
||||||
|
}
|
||||||
body.push(branch);
|
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 (side_effects.length && !exact_match) {
|
||||||
|
body.push(make_node(AST_Case, self, { expression: make_sequence(self, side_effects), 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();
|
||||||
|
|
@ -8492,12 +8512,30 @@ merge(Compressor.prototype, {
|
||||||
eliminate_branch(branch);
|
eliminate_branch(branch);
|
||||||
if (body.pop() === default_branch) default_branch = null;
|
if (body.pop() === default_branch) default_branch = null;
|
||||||
}
|
}
|
||||||
if (body.length == 0) {
|
if (!branch) {
|
||||||
return make_node(AST_BlockStatement, self, {
|
decl.push(make_node(AST_SimpleStatement, self.expression, { body: self.expression }));
|
||||||
body: decl.concat(make_node(AST_SimpleStatement, self.expression, {
|
if (side_effects.length) decl.push(make_node(AST_SimpleStatement, self, {
|
||||||
body: self.expression
|
body: make_sequence(self, side_effects),
|
||||||
}))
|
}));
|
||||||
}).optimize(compressor);
|
return make_node(AST_BlockStatement, self, { body: decl }).optimize(compressor);
|
||||||
|
}
|
||||||
|
if (exact_match ? !branch.expression.has_side_effects(compressor) : 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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
body[0].body = decl.concat(body[0].body);
|
body[0].body = decl.concat(body[0].body);
|
||||||
self.body = body;
|
self.body = body;
|
||||||
|
|
|
||||||
|
|
@ -2071,72 +2071,6 @@ issue_1670_2: {
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1670_3: {
|
issue_1670_3: {
|
||||||
options = {
|
|
||||||
comparisons: true,
|
|
||||||
conditionals: true,
|
|
||||||
dead_code: true,
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
switches: true,
|
|
||||||
typeofs: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function f() {
|
|
||||||
switch (1) {
|
|
||||||
case 0:
|
|
||||||
var a = true;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (typeof a === "undefined") console.log("PASS");
|
|
||||||
else console.log("FAIL");
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function() {
|
|
||||||
var a;
|
|
||||||
void 0 === a ? console.log("PASS") : console.log("FAIL");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1670_4: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
dead_code: true,
|
|
||||||
evaluate: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
switches: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function f() {
|
|
||||||
switch (1) {
|
|
||||||
case 0:
|
|
||||||
var a = true;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (typeof a === "undefined") console.log("PASS");
|
|
||||||
else console.log("FAIL");
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function() {
|
|
||||||
console.log("PASS");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1670_5: {
|
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
|
@ -2168,7 +2102,7 @@ issue_1670_5: {
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1670_6: {
|
issue_1670_4: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,37 @@ drop_default_2: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_default_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
switch (42) {
|
||||||
|
case f():
|
||||||
|
break;
|
||||||
|
case void console.log("FAIL"):
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
switch (42) {
|
||||||
|
case f():
|
||||||
|
case void console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
keep_default: {
|
keep_default: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
|
@ -423,7 +454,6 @@ drop_case_3: {
|
||||||
switch ({}.p) {
|
switch ({}.p) {
|
||||||
default:
|
default:
|
||||||
case void 0:
|
case void 0:
|
||||||
break;
|
|
||||||
case c = "FAIL":
|
case c = "FAIL":
|
||||||
}
|
}
|
||||||
console.log(c);
|
console.log(c);
|
||||||
|
|
@ -454,7 +484,166 @@ drop_case_4: {
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
keep_case: {
|
drop_case_5: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (42) {
|
||||||
|
case void console.log("PASS 1"):
|
||||||
|
console.log("FAIL 1");
|
||||||
|
case 42:
|
||||||
|
case console.log("FAIL 2"):
|
||||||
|
console.log("PASS 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
switch (42) {
|
||||||
|
case (void console.log("PASS 1"), 42):
|
||||||
|
console.log("PASS 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS 1",
|
||||||
|
"PASS 2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_case_6: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (console.log("PASS 1"), 2) {
|
||||||
|
case 0:
|
||||||
|
console.log("FAIL 1");
|
||||||
|
case (console.log("PASS 2"), 1):
|
||||||
|
console.log("FAIL 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
switch (console.log("PASS 1"), 2) {
|
||||||
|
case (console.log("PASS 2"), 1):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS 1",
|
||||||
|
"PASS 2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_case_7: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (2) {
|
||||||
|
case 0:
|
||||||
|
console.log("FAIL 1");
|
||||||
|
case (console.log("PASS 1"), 1):
|
||||||
|
console.log("FAIL 2");
|
||||||
|
case 2:
|
||||||
|
console.log("PASS 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
switch (2) {
|
||||||
|
case (console.log("PASS 1"), 1, 2):
|
||||||
|
console.log("PASS 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS 1",
|
||||||
|
"PASS 2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_case_8: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
switch (log("foo")) {
|
||||||
|
case "bar":
|
||||||
|
log("moo");
|
||||||
|
break;
|
||||||
|
case log("baz"):
|
||||||
|
log("moo");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log("moo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
switch (log("foo")) {
|
||||||
|
case "bar":
|
||||||
|
case log("baz"):
|
||||||
|
default:
|
||||||
|
log("moo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"moo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_case_9: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
switch (log("foo")) {
|
||||||
|
case log("bar"):
|
||||||
|
log("moo");
|
||||||
|
break;
|
||||||
|
case "baz":
|
||||||
|
log("moo");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log("moo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
switch (log("foo")) {
|
||||||
|
default:
|
||||||
|
log("bar");
|
||||||
|
log("moo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"moo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_case_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
|
|
@ -474,6 +663,76 @@ keep_case: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keep_case_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch ("foo") {
|
||||||
|
case console.log("bar"):
|
||||||
|
case console.log("baz"), "moo":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
switch ("foo") {
|
||||||
|
case console.log("bar"):
|
||||||
|
case console.log("baz"), "moo":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_case_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
switch (void console.log("PASS")) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"), 42:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
switch (void console.log("PASS")) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"), 42:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_case_4: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
switch (void console.log("PASS")) {
|
||||||
|
case a:
|
||||||
|
case void console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
switch (void console.log("PASS")) {
|
||||||
|
case a:
|
||||||
|
case void console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_376: {
|
issue_376: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
|
@ -1088,7 +1347,8 @@ drop_switch_6: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
A === B;
|
A;
|
||||||
|
B;
|
||||||
x();
|
x();
|
||||||
C !== D;
|
C !== D;
|
||||||
y();
|
y();
|
||||||
Loading…
Reference in New Issue
Block a user