Skip to content

Commit 64e3cee

Browse files
authored
enhance if_return (#5594)
1 parent 672cdfa commit 64e3cee

File tree

2 files changed

+195
-84
lines changed

2 files changed

+195
-84
lines changed

lib/compress.js

Lines changed: 58 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3451,7 +3451,7 @@ Compressor.prototype.compress = function(node) {
34513451
var changed = false;
34523452
var parent = compressor.parent();
34533453
var self = compressor.self();
3454-
var jump, merge_jump;
3454+
var declare_only, jump, merge_jump;
34553455
var in_iife = in_lambda && parent && parent.TYPE == "Call" && parent.expression === self;
34563456
var chain_if_returns = in_lambda && compressor.option("conditionals") && compressor.option("sequences");
34573457
var multiple_if_returns = has_multiple_if_returns(statements);
@@ -3460,7 +3460,7 @@ Compressor.prototype.compress = function(node) {
34603460
var j = next_index(i);
34613461
var next = statements[j];
34623462

3463-
if (in_lambda && !next && stat instanceof AST_Return
3463+
if (in_lambda && declare_only && !next && stat instanceof AST_Return
34643464
&& !(self instanceof AST_SwitchBranch)
34653465
&& !(in_try && in_try.bfinally && in_async_generator(in_lambda))) {
34663466
var body = stat.value;
@@ -3493,7 +3493,7 @@ Compressor.prototype.compress = function(node) {
34933493
body: as_statement_array_with_return(stat.body, ab),
34943494
});
34953495
stat.alternative = make_node(AST_BlockStatement, stat, {
3496-
body: as_statement_array(stat.alternative).concat(extract_functions()),
3496+
body: as_statement_array(stat.alternative).concat(extract_functions(merge_jump, jump)),
34973497
});
34983498
statements[i] = stat;
34993499
statements[i] = stat.transform(compressor);
@@ -3502,15 +3502,17 @@ Compressor.prototype.compress = function(node) {
35023502

35033503
if (ab && !stat.alternative && next instanceof AST_Jump) {
35043504
var cond = stat.condition;
3505-
cond = best_of_expression(cond, cond.negate(compressor), stat.body instanceof AST_BlockStatement);
3505+
var preference = i + 1 == j && stat.body instanceof AST_BlockStatement;
3506+
cond = best_of_expression(cond, cond.negate(compressor), preference);
35063507
if (cond !== stat.condition) {
35073508
changed = true;
35083509
stat = stat.clone();
35093510
stat.condition = cond;
3510-
statements[j] = stat.body;
3511-
stat.body = next;
3512-
if (next === jump) jump = null;
3513-
statements[i] = stat;
3511+
var body = stat.body;
3512+
stat.body = make_node(AST_BlockStatement, next, {
3513+
body: extract_functions(true, null, j + 1),
3514+
});
3515+
statements.splice(i, 1, stat, body);
35143516
statements[i] = stat.transform(compressor);
35153517
continue;
35163518
}
@@ -3522,7 +3524,7 @@ Compressor.prototype.compress = function(node) {
35223524
changed = true;
35233525
stat = stat.clone();
35243526
stat.body = make_node(AST_BlockStatement, stat.body, {
3525-
body: as_statement_array(stat.body).concat(extract_functions()),
3527+
body: as_statement_array(stat.body).concat(extract_functions(merge_jump, jump)),
35263528
});
35273529
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
35283530
body: as_statement_array_with_return(stat.alternative, alt),
@@ -3551,38 +3553,26 @@ Compressor.prototype.compress = function(node) {
35513553
if (!stat.alternative && next instanceof AST_Return) {
35523554
changed = true;
35533555
stat = stat.clone();
3554-
stat.alternative = next;
3555-
if (next === jump) jump = null;
3556-
statements.splice(i, 1, stat.transform(compressor));
3557-
statements.splice(j, 1);
3556+
stat.alternative = make_node(AST_BlockStatement, next, {
3557+
body: extract_functions(true, null, j + 1),
3558+
});
3559+
statements[i] = stat;
3560+
statements[i] = stat.transform(compressor);
35583561
continue;
35593562
}
3560-
if (!stat.alternative && !next && in_lambda) {
3561-
// if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined;
3562-
if (in_bool || value && multiple_if_returns) {
3563-
changed = true;
3564-
stat = stat.clone();
3565-
stat.alternative = make_node(AST_Return, stat, { value: null });
3566-
statements.splice(i, 1, stat.transform(compressor));
3567-
continue;
3568-
}
3569-
// if (foo()) return bar() ? x : void 0; ---> return foo() && bar() ? x : void 0;
3570-
// if (foo()) return bar() ? void 0 : x; ---> return !foo() || bar() ? void 0 : x;
3571-
var or;
3572-
if (value instanceof AST_Conditional
3573-
&& ((or = is_undefined(value.consequent, compressor))
3574-
|| is_undefined(value.alternative, compressor))) {
3575-
changed = true;
3576-
var ret = stat.body.clone();
3577-
ret.value = value.clone();
3578-
ret.value.condition = make_node(AST_Binary, stat, {
3579-
operator: or ? "||" : "&&",
3580-
left: or ? stat.condition.negate(compressor) : stat.condition,
3581-
right: value.condition,
3582-
});
3583-
statements.splice(i, 1, ret.transform(compressor));
3584-
continue;
3585-
}
3563+
// if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined;
3564+
// if (foo()) return bar() ? x : void 0; ---> return foo() && bar() ? x : void 0;
3565+
// if (foo()) return bar() ? void 0 : x; ---> return !foo() || bar() ? void 0 : x;
3566+
if (in_lambda && declare_only && !next && !stat.alternative && (in_bool
3567+
|| value && multiple_if_returns
3568+
|| value instanceof AST_Conditional && (is_undefined(value.consequent, compressor)
3569+
|| is_undefined(value.alternative, compressor)))) {
3570+
changed = true;
3571+
stat = stat.clone();
3572+
stat.alternative = make_node(AST_Return, stat, { value: null });
3573+
statements[i] = stat;
3574+
statements[i] = stat.transform(compressor);
3575+
continue;
35863576
}
35873577
// if (a) return b; if (c) return d; e; ---> return a ? b : c ? d : void e;
35883578
//
@@ -3593,22 +3583,17 @@ Compressor.prototype.compress = function(node) {
35933583
if (chain_if_returns && !stat.alternative
35943584
&& (!(prev_stat = statements[prev = prev_index(i)]) && in_iife
35953585
|| prev_stat instanceof AST_If && prev_stat.body instanceof AST_Return)
3596-
&& next_index(j) == statements.length && next instanceof AST_SimpleStatement) {
3586+
&& (!next ? !declare_only
3587+
: next instanceof AST_SimpleStatement && next_index(j) == statements.length)) {
35973588
changed = true;
35983589
var exprs = [];
3599-
var args = prev_stat ? trim_defns(prev, exprs) : [ i, 1 ];
36003590
stat = stat.clone();
36013591
exprs.push(stat.condition);
36023592
stat.condition = make_sequence(stat, exprs);
36033593
stat.alternative = make_node(AST_BlockStatement, next, {
3604-
body: [
3605-
next,
3606-
make_node(AST_Return, next, { value: null }),
3607-
],
3594+
body: extract_functions().concat(make_node(AST_Return, next, { value: null })),
36083595
});
3609-
args.push(stat.transform(compressor));
3610-
statements.splice(j, 1);
3611-
[].splice.apply(statements, args);
3596+
statements[i] = stat.transform(compressor);
36123597
i = prev + 1;
36133598
continue;
36143599
}
@@ -3703,17 +3688,18 @@ Compressor.prototype.compress = function(node) {
37033688
return true;
37043689
}
37053690

3706-
function extract_functions() {
3691+
function extract_functions(mode, stop, end) {
37073692
var defuns = [];
37083693
var lexical = false;
37093694
var start = i + 1;
3710-
var end;
3711-
if (merge_jump) {
3712-
end = statements.lastIndexOf(jump);
3713-
if (end < 0) end = statements.length;
3714-
} else {
3695+
if (!mode) {
37153696
end = statements.length;
37163697
jump = null;
3698+
} else if (stop) {
3699+
end = statements.lastIndexOf(stop);
3700+
} else {
3701+
stop = statements[end];
3702+
if (stop !== jump) jump = null;
37173703
}
37183704
var tail = statements.splice(start, end - start).filter(function(stat) {
37193705
if (stat instanceof AST_LambdaDefinition) {
@@ -3723,11 +3709,11 @@ Compressor.prototype.compress = function(node) {
37233709
if (is_lexical_definition(stat)) lexical = true;
37243710
return true;
37253711
});
3726-
if (merge_jump === 3) {
3727-
tail.push(make_node(AST_SimpleStatement, jump.value, {
3728-
body: make_sequence(jump.value, jump.value.expressions.slice(0, -1)),
3712+
if (mode === 3) {
3713+
tail.push(make_node(AST_SimpleStatement, stop.value, {
3714+
body: make_sequence(stop.value, stop.value.expressions.slice(0, -1)),
37293715
}));
3730-
jump.value = jump.value.tail_node();
3716+
stop.value = stop.value.tail_node();
37313717
}
37323718
[].push.apply(lexical ? tail : statements, defuns);
37333719
return tail;
@@ -3758,36 +3744,27 @@ Compressor.prototype.compress = function(node) {
37583744
}
37593745

37603746
function next_index(i) {
3761-
for (var j = i + 1; j < statements.length; j++) {
3762-
if (!is_declaration(statements[j])) break;
3747+
declare_only = true;
3748+
for (var j = i; ++j < statements.length;) {
3749+
var stat = statements[j];
3750+
if (is_declaration(stat)) continue;
3751+
if (stat instanceof AST_Var) {
3752+
declare_only = false;
3753+
continue;
3754+
}
3755+
break;
37633756
}
37643757
return j;
37653758
}
37663759

37673760
function prev_index(i) {
37683761
for (var j = i; --j >= 0;) {
3769-
if (!(statements[j] instanceof AST_Var)) break;
3770-
}
3771-
return j;
3772-
}
3773-
3774-
function trim_defns(j, exprs) {
3775-
var args = [ j + 1, i - j ];
3776-
var var_defs = [];
3777-
while (++j < i) {
37783762
var stat = statements[j];
3779-
stat.remove_initializers(compressor, var_defs);
3780-
stat.definitions.forEach(function(var_def) {
3781-
if (!var_def.value) return;
3782-
exprs.push(make_node(AST_Assign, var_def, {
3783-
operator: "=",
3784-
left: var_def.name.convert_symbol(AST_SymbolRef, process_to_assign),
3785-
right: var_def.value,
3786-
}));
3787-
});
3763+
if (stat instanceof AST_Var) continue;
3764+
if (is_declaration(stat)) continue;
3765+
break;
37883766
}
3789-
if (var_defs.length > 0) args.push(make_node(AST_Var, stat, { definitions: var_defs }));
3790-
return args;
3767+
return j;
37913768
}
37923769

37933770
function eliminate_returns(stat, in_block) {
@@ -9618,7 +9595,7 @@ Compressor.prototype.compress = function(node) {
96189595
}
96199596
if (var_defs.length > 0) body.push(make_node(AST_Var, self, { definitions: var_defs }));
96209597
if (body.length > 0) {
9621-
body.push(self);
9598+
body.push(self.transform(compressor));
96229599
return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
96239600
}
96249601
} else if (body_exprs && alt_exprs) {

0 commit comments

Comments
 (0)