enhance if_return (#4097)

This commit is contained in:
Alex Lam S.L
2020-09-10 15:31:34 +01:00
committed by GitHub
parent d97672613d
commit d7456a2dc2
2 changed files with 114 additions and 24 deletions

View File

@@ -2113,18 +2113,22 @@ merge(Compressor.prototype, {
eliminate_spurious_blocks(stat.body);
[].splice.apply(statements, [i, 1].concat(stat.body));
i += stat.body.length;
} else if (stat instanceof AST_EmptyStatement) {
CHANGED = true;
statements.splice(i, 1);
} else if (stat instanceof AST_Directive) {
if (!member(stat.value, seen_dirs)) {
i++;
seen_dirs.push(stat.value);
} else {
continue;
}
if (stat instanceof AST_Directive) {
if (member(stat.value, seen_dirs)) {
CHANGED = true;
statements.splice(i, 1);
continue;
}
} else i++;
seen_dirs.push(stat.value);
}
if (stat instanceof AST_EmptyStatement) {
CHANGED = true;
statements.splice(i, 1);
continue;
}
i++;
}
}
@@ -2295,12 +2299,32 @@ merge(Compressor.prototype, {
return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
}
function is_last_statement(body, stat) {
var index = body.lastIndexOf(stat);
if (index < 0) return false;
while (++index < body.length) {
if (!is_declaration(body[index])) return false;
}
return true;
}
function match_target(target) {
var block = self, stat, level = 0;
do {
do {
if (block === target) return true;
block = compressor.parent(level++);
} while (block instanceof AST_If && (stat = block));
} while (block instanceof AST_BlockStatement && is_last_statement(block.body, stat));
}
function can_merge_flow(ab) {
if (!ab) return false;
var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
return ab instanceof AST_Return && in_lambda && is_return_void(ab.value)
|| ab instanceof AST_Continue && self === loop_body(lct)
|| ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
if (ab instanceof AST_Return) return in_lambda && is_return_void(ab.value);
if (!(ab instanceof AST_LoopControl)) return false;
var lct = compressor.loopcontrol_target(ab);
if (ab instanceof AST_Continue) return match_target(loop_body(lct));
if (lct instanceof AST_IterationStatement) return false;
return match_target(lct);
}
function extract_functions() {
@@ -2327,20 +2351,14 @@ merge(Compressor.prototype, {
function next_index(i) {
for (var j = i + 1; j < statements.length; j++) {
var stat = statements[j];
if (!(stat instanceof AST_Var && declarations_only(stat))) {
break;
}
if (!is_declaration(statements[j])) break;
}
return j;
}
function prev_index(i) {
for (var j = i; --j >= 0;) {
var stat = statements[j];
if (!(stat instanceof AST_Var && declarations_only(stat))) {
break;
}
if (!is_declaration(statements[j])) break;
}
return j;
}
@@ -2383,6 +2401,10 @@ merge(Compressor.prototype, {
});
}
function is_declaration(stat) {
return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat);
}
function sequencesize(statements, compressor) {
if (statements.length < 2) return;
var seq = [], n = 0;
@@ -2399,8 +2421,7 @@ merge(Compressor.prototype, {
var body = stat.body;
if (seq.length > 0) body = body.drop_side_effect_free(compressor);
if (body) merge_sequence(seq, body);
} else if (stat instanceof AST_Definitions && declarations_only(stat)
|| stat instanceof AST_Defun) {
} else if (is_declaration(stat)) {
statements[n++] = stat;
} else {
push_seq();

View File

@@ -594,3 +594,72 @@ iife_if_return_simple: {
}
expect_stdout: "PASS"
}
nested_if_break: {
options = {
if_return: true,
}
input: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i) {
if (0 === i) break L1;
console.log(i);
}
}
expect: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i)
if (0 !== i) console.log(i);
}
expect_stdout: [
"1",
"2",
]
}
nested_if_continue: {
options = {
conditionals: true,
if_return: true,
join_vars: true,
loops: true,
}
input: {
function f(n) {
var i = 0;
do {
if ("number" == typeof n) {
if (0 === n) {
console.log("even", i);
continue;
}
if (1 === n) {
console.log("odd", i);
continue;
}
i++;
}
} while (0 <= (n -= 2));
}
f(37);
f(42);
}
expect: {
function f(n) {
for (var i = 0;
"number" == typeof n
&& (0 !== n
? 1 !== n
? i++
: console.log("odd", i)
: console.log("even", i)),
0 <= (n -= 2););
}
f(37);
f(42);
}
expect_stdout: [
"odd 18",
"even 21",
]
}