enhance conditionals & switches (#4058)

This commit is contained in:
Alex Lam S.L
2020-08-20 17:35:39 +01:00
committed by GitHub
parent 1c6384b6a5
commit a153176469
3 changed files with 189 additions and 24 deletions

View File

@@ -5916,28 +5916,57 @@ merge(Compressor.prototype, {
}
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) {
if (has_break
|| node instanceof AST_Lambda
|| node instanceof AST_SimpleStatement) return true;
if (is_break(node, tw)) has_break = true;
if (compressor.option("conditionals")) switch (body.length) {
case 1:
if (!no_break(self)) break;
var exp = body[0].expression;
var statements = body[0].body.slice();
if (body[0] !== default_branch && body[0] !== exact_match) return make_node(AST_If, self, {
condition: make_node(AST_Binary, self, {
operator: "===",
left: self.expression,
right: exp,
}),
body: make_node(AST_BlockStatement, self, {
body: statements,
}),
alternative: null,
}).optimize(compressor);
if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, {
body: exp,
}));
statements.unshift(make_node(AST_SimpleStatement, self.expression, {
body:self.expression,
}));
return make_node(AST_BlockStatement, self, {
body: statements,
}).optimize(compressor);
case 2:
if (!member(default_branch, body)) break;
var statements = body[0].body.slice();
var exclusive = statements.length && is_break(statements[statements.length - 1], compressor);
if (exclusive) statements.pop();
if (!all(statements, no_break)) break;
var alternative = body[1].body.length && make_node(AST_BlockStatement, body[1], body[1]);
var node = make_node(AST_If, self, {
condition: make_node(AST_Binary, self, body[0] === default_branch ? {
operator: "!==",
left: self.expression,
right: body[1].expression,
} : {
operator: "===",
left: self.expression,
right: body[0].expression,
}),
body: make_node(AST_BlockStatement, body[0], {
body: statements,
}),
alternative: exclusive && alternative || null,
});
self.walk(tw);
if (!has_break) {
var statements = body[0].body.slice();
var exp = body[0].expression;
if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, {
body: exp
}));
statements.unshift(make_node(AST_SimpleStatement, self.expression, {
body:self.expression
}));
return make_node(AST_BlockStatement, self, {
body: statements
}).optimize(compressor);
}
if (!exclusive && alternative) node = make_node(AST_BlockStatement, self, {
body: [ node, alternative ],
});
return node.optimize(compressor);
}
return self;
@@ -5945,6 +5974,18 @@ merge(Compressor.prototype, {
return node instanceof AST_Break && tw.loopcontrol_target(node) === self;
}
function no_break(node) {
var found = false;
var tw = new TreeWalker(function(node) {
if (found
|| node instanceof AST_Lambda
|| node instanceof AST_SimpleStatement) return true;
if (is_break(node, tw)) found = true;
});
node.walk(tw);
return !found;
}
function eliminate_branch(branch, prev) {
if (prev && !aborts(prev)) {
prev.body = prev.body.concat(branch.body);