@@ -3452,16 +3452,15 @@ Compressor.prototype.compress = function(node) {
|
|||||||
var parent = compressor.parent();
|
var parent = compressor.parent();
|
||||||
var self = compressor.self();
|
var self = compressor.self();
|
||||||
var declare_only, jump, merge_jump;
|
var declare_only, jump, merge_jump;
|
||||||
var in_tail = in_lambda && self instanceof AST_Block && self.body === statements;
|
var in_iife = in_lambda && parent && parent.TYPE == "Call" && parent.expression === self;
|
||||||
var in_iife = in_tail && parent && parent.TYPE == "Call" && parent.expression === self;
|
var chain_if_returns = in_lambda && compressor.option("conditionals") && compressor.option("sequences");
|
||||||
var chain_if_returns = in_tail && compressor.option("conditionals") && compressor.option("sequences");
|
|
||||||
var multiple_if_returns = has_multiple_if_returns(statements);
|
var multiple_if_returns = has_multiple_if_returns(statements);
|
||||||
for (var i = statements.length; --i >= 0;) {
|
for (var i = statements.length; --i >= 0;) {
|
||||||
var stat = statements[i];
|
var stat = statements[i];
|
||||||
var j = next_index(i);
|
var j = next_index(i);
|
||||||
var next = statements[j];
|
var next = statements[j];
|
||||||
|
|
||||||
if (in_tail && declare_only && !next && stat instanceof AST_Return
|
if (in_lambda && declare_only && !next && stat instanceof AST_Return
|
||||||
&& !(self instanceof AST_SwitchBranch)
|
&& !(self instanceof AST_SwitchBranch)
|
||||||
&& !(in_try && in_try.bfinally && in_async_generator(in_lambda))) {
|
&& !(in_try && in_try.bfinally && in_async_generator(in_lambda))) {
|
||||||
var body = stat.value;
|
var body = stat.value;
|
||||||
@@ -3486,6 +3485,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
|
|
||||||
if (stat instanceof AST_If) {
|
if (stat instanceof AST_If) {
|
||||||
var ab = aborts(stat.body);
|
var ab = aborts(stat.body);
|
||||||
|
// if (foo()) { bar(); return; } else baz(); moo(); ---> if (foo()) bar(); else { baz(); moo(); }
|
||||||
if (can_merge_flow(ab)) {
|
if (can_merge_flow(ab)) {
|
||||||
if (ab.label) remove(ab.label.thedef.references, ab);
|
if (ab.label) remove(ab.label.thedef.references, ab);
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -3500,7 +3500,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
statements[i] = stat.transform(compressor);
|
statements[i] = stat.transform(compressor);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// if (foo()) { bar(); return x; } return y; ---> if (!foo()) return y; bar(); return x;
|
||||||
if (ab && !stat.alternative && next instanceof AST_Jump) {
|
if (ab && !stat.alternative && next instanceof AST_Jump) {
|
||||||
var cond = stat.condition;
|
var cond = stat.condition;
|
||||||
var preference = i + 1 == j && stat.body instanceof AST_BlockStatement;
|
var preference = i + 1 == j && stat.body instanceof AST_BlockStatement;
|
||||||
@@ -3514,12 +3514,17 @@ Compressor.prototype.compress = function(node) {
|
|||||||
body: extract_functions(true, null, j + 1),
|
body: extract_functions(true, null, j + 1),
|
||||||
});
|
});
|
||||||
statements.splice(i, 1, stat, body);
|
statements.splice(i, 1, stat, body);
|
||||||
statements[i] = stat.transform(compressor);
|
// proceed further only if `TreeWalker.stack` is in a consistent state
|
||||||
|
// https://github.com/mishoo/UglifyJS/issues/5595
|
||||||
|
// https://github.com/mishoo/UglifyJS/issues/5597
|
||||||
|
if (!in_lambda || self instanceof AST_Block && self.body === statements) {
|
||||||
|
statements[i] = stat.transform(compressor);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var alt = aborts(stat.alternative);
|
var alt = aborts(stat.alternative);
|
||||||
|
// if (foo()) bar(); else { baz(); return; } moo(); ---> if (foo()) { bar(); moo(); } else baz();
|
||||||
if (can_merge_flow(alt)) {
|
if (can_merge_flow(alt)) {
|
||||||
if (alt.label) remove(alt.label.thedef.references, alt);
|
if (alt.label) remove(alt.label.thedef.references, alt);
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -3534,7 +3539,6 @@ Compressor.prototype.compress = function(node) {
|
|||||||
statements[i] = stat.transform(compressor);
|
statements[i] = stat.transform(compressor);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compressor.option("typeofs")) {
|
if (compressor.option("typeofs")) {
|
||||||
if (ab && !alt) {
|
if (ab && !alt) {
|
||||||
var stats = make_node(AST_BlockStatement, self, { body: statements.slice(i + 1) });
|
var stats = make_node(AST_BlockStatement, self, { body: statements.slice(i + 1) });
|
||||||
@@ -3564,7 +3568,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
// if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined;
|
// if (foo()) return x; [ return ; ] ---> return foo() ? x : undefined;
|
||||||
// if (foo()) return bar() ? x : void 0; ---> return foo() && bar() ? x : void 0;
|
// if (foo()) return bar() ? x : void 0; ---> return foo() && bar() ? x : void 0;
|
||||||
// if (foo()) return bar() ? void 0 : x; ---> return !foo() || bar() ? void 0 : x;
|
// if (foo()) return bar() ? void 0 : x; ---> return !foo() || bar() ? void 0 : x;
|
||||||
if (in_tail && declare_only && !next && !stat.alternative && (in_bool
|
if (in_lambda && declare_only && !next && !stat.alternative && (in_bool
|
||||||
|| value && multiple_if_returns
|
|| value && multiple_if_returns
|
||||||
|| value instanceof AST_Conditional && (is_undefined(value.consequent, compressor)
|
|| value instanceof AST_Conditional && (is_undefined(value.consequent, compressor)
|
||||||
|| is_undefined(value.alternative, compressor)))) {
|
|| is_undefined(value.alternative, compressor)))) {
|
||||||
@@ -3645,7 +3649,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
function can_drop_abort(ab) {
|
function can_drop_abort(ab) {
|
||||||
if (ab instanceof AST_Exit) {
|
if (ab instanceof AST_Exit) {
|
||||||
if (merge_jump = match_return(ab)) return true;
|
if (merge_jump = match_return(ab)) return true;
|
||||||
if (!in_tail) return false;
|
if (!in_lambda) return false;
|
||||||
if (!(ab instanceof AST_Return)) return false;
|
if (!(ab instanceof AST_Return)) return false;
|
||||||
var value = ab.value;
|
var value = ab.value;
|
||||||
if (value && !is_undefined(value.tail_node())) return false;
|
if (value && !is_undefined(value.tail_node())) return false;
|
||||||
@@ -3658,7 +3662,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
if (!(ab instanceof AST_LoopControl)) return false;
|
if (!(ab instanceof AST_LoopControl)) return false;
|
||||||
if (jump && self instanceof AST_SwitchBranch) {
|
if (jump && self instanceof AST_SwitchBranch) {
|
||||||
if (jump instanceof AST_Exit) {
|
if (jump instanceof AST_Exit) {
|
||||||
if (!in_tail) return false;
|
if (!in_lambda) return false;
|
||||||
if (jump.value) return false;
|
if (jump.value) return false;
|
||||||
} else if (compressor.loopcontrol_target(jump) !== parent) {
|
} else if (compressor.loopcontrol_target(jump) !== parent) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -2279,3 +2279,29 @@ issue_5595: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5597: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (a) L: {
|
||||||
|
return;
|
||||||
|
var b;
|
||||||
|
} else
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
console.log(f(42) || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (!a)
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
console.log(f(42) || "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user