enhance if_return (#4097)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user