enhance loops (#4180)

This commit is contained in:
Alex Lam S.L
2020-10-05 01:26:59 +01:00
committed by GitHub
parent 220dc95c0d
commit 813ac3ba96
2 changed files with 89 additions and 20 deletions

View File

@@ -1180,6 +1180,16 @@ merge(Compressor.prototype, {
|| node instanceof AST_Undefined; || node instanceof AST_Undefined;
} }
function declarations_only(node) {
return all(node.definitions, function(var_def) {
return !var_def.value;
});
}
function is_declaration(stat) {
return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat);
}
function tighten_body(statements, compressor) { function tighten_body(statements, compressor) {
var in_loop, in_try, scope; var in_loop, in_try, scope;
find_loop_scope_try(); find_loop_scope_try();
@@ -2407,16 +2417,6 @@ merge(Compressor.prototype, {
}); });
} }
function declarations_only(node) {
return all(node.definitions, function(var_def) {
return !var_def.value;
});
}
function is_declaration(stat) {
return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat);
}
function sequencesize(statements, compressor) { function sequencesize(statements, compressor) {
if (statements.length < 2) return; if (statements.length < 2) return;
var seq = [], n = 0; var seq = [], n = 0;
@@ -4268,13 +4268,17 @@ merge(Compressor.prototype, {
return self; return self;
}); });
function trim_block(stat) {
switch (stat.body.length) {
case 1: return stat.body[0];
case 0: return make_node(AST_EmptyStatement, stat);
}
return stat;
}
OPT(AST_BlockStatement, function(self, compressor) { OPT(AST_BlockStatement, function(self, compressor) {
self.body = tighten_body(self.body, compressor); self.body = tighten_body(self.body, compressor);
switch (self.body.length) { return trim_block(self);
case 1: return self.body[0];
case 0: return make_node(AST_EmptyStatement, self);
}
return self;
}); });
OPT(AST_Function, function(self, compressor) { OPT(AST_Function, function(self, compressor) {
@@ -5847,6 +5851,33 @@ merge(Compressor.prototype, {
}).optimize(compressor); }).optimize(compressor);
} }
} }
if (self.body instanceof AST_BlockStatement) {
var body = self.body.body;
for (var i = body.length; --i >= 0;) {
var stat = body[i];
if (stat instanceof AST_If
&& !stat.alternative
&& stat.body instanceof AST_Break
&& compressor.loopcontrol_target(stat.body) === compressor.self()) {
self.condition = make_node(AST_Binary, self, {
operator: "&&",
left: stat.condition.negate(compressor),
right: self.condition,
});
body.splice(i, 1);
} else if (stat instanceof AST_SimpleStatement) {
self.condition = make_sequence(self, [
stat.body,
self.condition,
]);
body.splice(i, 1);
} else if (!is_declaration(stat)) {
break;
}
}
self.body = trim_block(self.body);
}
if (self.body instanceof AST_EmptyStatement) return make_node(AST_For, self, self).optimize(compressor);
if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, { if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, {
condition: make_sequence(self.condition, [ condition: make_sequence(self.condition, [
self.body.body, self.body.body,

View File

@@ -201,7 +201,7 @@ evaluate: {
} }
} }
issue_1532: { issue_1532_1: {
options = { options = {
evaluate: true, evaluate: true,
loops: true, loops: true,
@@ -210,18 +210,56 @@ issue_1532: {
function f(x, y) { function f(x, y) {
do { do {
if (x) break; if (x) break;
foo(); console.log(y);
} while (false); } while (false);
} }
f(null, "PASS");
f(42, "FAIL");
}
expect: {
function f(x, y) {
for (; !x && (console.log(y), false););
}
f(null, "PASS");
f(42, "FAIL");
}
expect_stdout: "PASS"
}
issue_1532_2: {
options = {
evaluate: true,
loops: true,
}
input: {
function f(x, y) {
do {
if (x) {
console.log(x);
break;
}
console.log(y);
} while (false);
}
f(null, "PASS");
f(42, "FAIL");
} }
expect: { expect: {
function f(x, y) { function f(x, y) {
do { do {
if (x) break; if (x) {
foo(); console.log(x);
} while (false); break;
}
} while (console.log(y), false);
} }
f(null, "PASS");
f(42, "FAIL");
} }
expect_stdout: [
"PASS",
"42",
]
} }
issue_186: { issue_186: {