enhance if_return (#5541)

This commit is contained in:
Alex Lam S.L
2022-07-06 21:28:00 +01:00
committed by GitHub
parent 0207b46d70
commit c8d98f4787
2 changed files with 118 additions and 27 deletions

View File

@@ -3411,20 +3411,20 @@ Compressor.prototype.compress = function(node) {
if (in_lambda && !next && stat instanceof AST_Return
&& !(in_try && in_try.bfinally && in_async_generator(in_lambda))) {
if (!stat.value) {
var body = stat.value;
if (!body) {
changed = true;
statements.splice(i, 1);
continue;
}
var tail = stat.value.tail_node();
if (tail instanceof AST_UnaryPrefix && tail.operator == "void") {
var tail = body.tail_node();
if (is_undefined(tail)) {
changed = true;
var body;
if (tail === stat.value) {
body = tail.expression;
} else {
body = stat.value.clone();
body.expressions[body.length - 1] = tail.expression;
if (body instanceof AST_UnaryPrefix) {
body = body.expression;
} else if (tail instanceof AST_UnaryPrefix) {
body = body.clone();
body.expressions[body.expressions.length - 1] = tail.expression;
}
statements[i] = make_node(AST_SimpleStatement, stat, { body: body });
continue;
@@ -3573,14 +3573,18 @@ Compressor.prototype.compress = function(node) {
});
}
function match_return(ab) {
function match_return(ab, exact) {
if (!exit) return false;
if (exit.TYPE != ab.TYPE) return false;
var value = ab.value;
if (!value) return false;
var equals = exit.equivalent_to(ab);
if (!equals && value instanceof AST_Sequence) {
value = value.tail_node();
equals = exit.value ? exit.value.equivalent_to(value) : is_undefined(value);
if (exit.value && exit.value.equivalent_to(value)) equals = 2;
}
if (!equals && !exact && exit.value instanceof AST_Sequence) {
if (exit.value.tail_node().equivalent_to(value)) equals = 3;
}
if (!equals) return false;
if (exit_defs == null) {
@@ -3591,19 +3595,22 @@ Compressor.prototype.compress = function(node) {
if (!exit_defs.size()) exit_defs = false;
}
var abort = false;
if (value && exit_defs) value.walk(new TreeWalker(function(node) {
if (exit_defs) value.walk(new TreeWalker(function(node) {
if (abort) return true;
if (node instanceof AST_SymbolRef && exit_defs.get(node.name) !== node.definition()) {
return abort = true;
}
}));
return !abort;
return !abort && equals;
}
function can_drop_abort(ab) {
if (ab instanceof AST_Exit) {
if (match_return(ab)) return merge_exit = true;
return in_lambda && ab instanceof AST_Return && is_undefined(ab.value);
if (merge_exit = match_return(ab)) return true;
if (!in_lambda) return false;
if (!(ab instanceof AST_Return)) return false;
if (is_undefined(ab.value)) return true;
return ab.value instanceof AST_Sequence && is_undefined(ab.value.tail_node());
}
if (!(ab instanceof AST_LoopControl)) return false;
var lct = compressor.loopcontrol_target(ab);
@@ -3650,17 +3657,23 @@ Compressor.prototype.compress = function(node) {
if (is_lexical_definition(stat)) lexical = true;
return true;
});
if (merge_exit === 3) {
tail.push(make_node(AST_SimpleStatement, exit.value, {
body: make_sequence(exit.value, exit.value.expressions.slice(0, -1)),
}));
exit.value = exit.value.tail_node();
}
[].push.apply(lexical ? tail : statements, defuns);
return tail;
}
function trim_return(value) {
if (!value) return;
if (exit.value) {
if (exit.value.TYPE == value.TYPE) return;
if (value instanceof AST_Sequence) return make_sequence(value, value.expressions.slice(0, -1));
function trim_return(value, mode) {
if (value) switch (mode) {
case 3:
if (!(value instanceof AST_Sequence)) break;
case 2:
return make_sequence(value, value.expressions.slice(0, -1));
}
return value;
}
function as_statement_array_with_return(node, ab) {
@@ -3671,7 +3684,7 @@ Compressor.prototype.compress = function(node) {
}
block.pop();
var value = ab.value;
if (merge_exit) value = trim_return(value);
if (merge_exit) value = trim_return(value, merge_exit);
if (value) block.push(make_node(AST_SimpleStatement, value, { body: value }));
return body;
}
@@ -3711,8 +3724,9 @@ Compressor.prototype.compress = function(node) {
function eliminate_returns(stat, in_block) {
if (stat instanceof AST_Exit) {
if (match_return(stat)) {
var value = trim_return(stat.value);
var mode = match_return(stat, true);
if (mode) {
var value = trim_return(stat.value, mode);
if (value) return make_node(AST_SimpleStatement, value, { body: value });
return in_block ? null : make_node(AST_EmptyStatement, stat);
}