@@ -8424,7 +8424,6 @@ merge(Compressor.prototype, {
|
||||
|
||||
OPT(AST_Switch, function(self, compressor) {
|
||||
if (!compressor.option("switches")) return self;
|
||||
var branch;
|
||||
var value = self.expression.evaluate(compressor);
|
||||
if (!(value instanceof AST_Node)) {
|
||||
var orig = self.expression;
|
||||
@@ -8435,10 +8434,12 @@ merge(Compressor.prototype, {
|
||||
if (value instanceof AST_Node) {
|
||||
value = self.expression.evaluate(compressor, true);
|
||||
}
|
||||
var decl = [];
|
||||
var body = [];
|
||||
var branch;
|
||||
var decl = [];
|
||||
var default_branch;
|
||||
var exact_match;
|
||||
var side_effects = [];
|
||||
for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
|
||||
branch = self.body[i];
|
||||
if (branch instanceof AST_Default) {
|
||||
@@ -8450,13 +8451,9 @@ merge(Compressor.prototype, {
|
||||
default_branch = branch;
|
||||
}
|
||||
} else if (!(value instanceof AST_Node)) {
|
||||
var exp = branch.expression.evaluate(compressor);
|
||||
if (!(exp instanceof AST_Node) && exp !== value) {
|
||||
eliminate_branch(branch, body[body.length - 1]);
|
||||
continue;
|
||||
}
|
||||
if (exp instanceof AST_Node) exp = branch.expression.evaluate(compressor, true);
|
||||
if (exp === value) {
|
||||
var exp = branch.expression;
|
||||
var val = exp.evaluate(compressor, true);
|
||||
if (val === value) {
|
||||
exact_match = branch;
|
||||
if (default_branch) {
|
||||
var default_index = body.indexOf(default_branch);
|
||||
@@ -8464,18 +8461,41 @@ 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 (aborts(branch)) {
|
||||
if (exact_match || i == len - 1 || aborts(branch)) {
|
||||
var prev = body[body.length - 1];
|
||||
if (aborts(prev) && prev.body.length == branch.body.length
|
||||
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
|
||||
prev.body = [];
|
||||
var statements = branch.body;
|
||||
if (aborts(prev)) switch (prev.body.length - statements.length) {
|
||||
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);
|
||||
}
|
||||
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]) {
|
||||
var stat = branch.body[branch.body.length - 1];
|
||||
if (is_break(stat, compressor)) branch.body.pop();
|
||||
@@ -8492,12 +8512,30 @@ merge(Compressor.prototype, {
|
||||
eliminate_branch(branch);
|
||||
if (body.pop() === default_branch) default_branch = null;
|
||||
}
|
||||
if (body.length == 0) {
|
||||
return make_node(AST_BlockStatement, self, {
|
||||
body: decl.concat(make_node(AST_SimpleStatement, self.expression, {
|
||||
body: self.expression
|
||||
}))
|
||||
}).optimize(compressor);
|
||||
if (!branch) {
|
||||
decl.push(make_node(AST_SimpleStatement, self.expression, { body: self.expression }));
|
||||
if (side_effects.length) decl.push(make_node(AST_SimpleStatement, self, {
|
||||
body: make_sequence(self, side_effects),
|
||||
}));
|
||||
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);
|
||||
self.body = body;
|
||||
|
||||
Reference in New Issue
Block a user