enhance conditionals & switches (#4058)
This commit is contained in:
@@ -5916,28 +5916,57 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
body[0].body = decl.concat(body[0].body);
|
body[0].body = decl.concat(body[0].body);
|
||||||
self.body = body;
|
self.body = body;
|
||||||
if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
|
if (compressor.option("conditionals")) switch (body.length) {
|
||||||
var has_break = false;
|
case 1:
|
||||||
var tw = new TreeWalker(function(node) {
|
if (!no_break(self)) break;
|
||||||
if (has_break
|
var exp = body[0].expression;
|
||||||
|| node instanceof AST_Lambda
|
var statements = body[0].body.slice();
|
||||||
|| node instanceof AST_SimpleStatement) return true;
|
if (body[0] !== default_branch && body[0] !== exact_match) return make_node(AST_If, self, {
|
||||||
if (is_break(node, tw)) has_break = true;
|
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 (!exclusive && alternative) node = make_node(AST_BlockStatement, self, {
|
||||||
if (!has_break) {
|
body: [ node, alternative ],
|
||||||
var statements = body[0].body.slice();
|
});
|
||||||
var exp = body[0].expression;
|
return node.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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
@@ -5945,6 +5974,18 @@ merge(Compressor.prototype, {
|
|||||||
return node instanceof AST_Break && tw.loopcontrol_target(node) === self;
|
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) {
|
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);
|
||||||
|
|||||||
@@ -2031,6 +2031,7 @@ issue_1670_4: {
|
|||||||
|
|
||||||
issue_1670_5: {
|
issue_1670_5: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
@@ -2062,6 +2063,7 @@ issue_1670_5: {
|
|||||||
|
|
||||||
issue_1670_6: {
|
issue_1670_6: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
constant_switch_1: {
|
constant_switch_1: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -19,6 +20,7 @@ constant_switch_1: {
|
|||||||
|
|
||||||
constant_switch_2: {
|
constant_switch_2: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -39,6 +41,7 @@ constant_switch_2: {
|
|||||||
|
|
||||||
constant_switch_3: {
|
constant_switch_3: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -60,6 +63,7 @@ constant_switch_3: {
|
|||||||
|
|
||||||
constant_switch_4: {
|
constant_switch_4: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -86,6 +90,7 @@ constant_switch_4: {
|
|||||||
|
|
||||||
constant_switch_5: {
|
constant_switch_5: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -120,6 +125,7 @@ constant_switch_5: {
|
|||||||
|
|
||||||
constant_switch_6: {
|
constant_switch_6: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -154,6 +160,7 @@ constant_switch_6: {
|
|||||||
|
|
||||||
constant_switch_7: {
|
constant_switch_7: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -197,6 +204,7 @@ constant_switch_7: {
|
|||||||
|
|
||||||
constant_switch_8: {
|
constant_switch_8: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -226,6 +234,7 @@ constant_switch_8: {
|
|||||||
|
|
||||||
constant_switch_9: {
|
constant_switch_9: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -315,6 +324,7 @@ keep_default: {
|
|||||||
|
|
||||||
issue_1663: {
|
issue_1663: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -551,6 +561,7 @@ issue_441_2: {
|
|||||||
|
|
||||||
issue_1674: {
|
issue_1674: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -876,6 +887,7 @@ beautify: {
|
|||||||
|
|
||||||
issue_1758: {
|
issue_1758: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
}
|
}
|
||||||
@@ -898,15 +910,16 @@ issue_1758: {
|
|||||||
|
|
||||||
issue_2535: {
|
issue_2535: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch(w(), 42) {
|
switch(w(), 42) {
|
||||||
case 13: x();
|
case 13: x();
|
||||||
case 42: y();
|
case 42: y();
|
||||||
default: z();
|
default: z();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -919,6 +932,7 @@ issue_2535: {
|
|||||||
|
|
||||||
issue_1750: {
|
issue_1750: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
@@ -963,6 +977,7 @@ drop_switch_1: {
|
|||||||
|
|
||||||
drop_switch_2: {
|
drop_switch_2: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
}
|
}
|
||||||
@@ -1007,6 +1022,7 @@ drop_switch_3: {
|
|||||||
|
|
||||||
drop_switch_4: {
|
drop_switch_4: {
|
||||||
options = {
|
options = {
|
||||||
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
}
|
}
|
||||||
@@ -1028,3 +1044,109 @@ drop_switch_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_switch_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (A) {
|
||||||
|
case B:
|
||||||
|
x();
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
switch (C) {
|
||||||
|
default:
|
||||||
|
y();
|
||||||
|
case D:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A === B && x();
|
||||||
|
C !== D && y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_switch_6: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (A) {
|
||||||
|
case B:
|
||||||
|
default:
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
switch (C) {
|
||||||
|
default:
|
||||||
|
case D:
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A === B;
|
||||||
|
x();
|
||||||
|
C !== D;
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_switch_7: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (A) {
|
||||||
|
case B:
|
||||||
|
w();
|
||||||
|
default:
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
switch (C) {
|
||||||
|
default:
|
||||||
|
y();
|
||||||
|
case D:
|
||||||
|
z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A === B && w();
|
||||||
|
x();
|
||||||
|
C !== D && y();
|
||||||
|
z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_switch_8: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (A) {
|
||||||
|
case B:
|
||||||
|
w();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
switch (C) {
|
||||||
|
default:
|
||||||
|
y();
|
||||||
|
break;
|
||||||
|
case D:
|
||||||
|
z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(A === B ? w : x)();
|
||||||
|
(C !== D ? y : z)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user