- remove duplicated functionalities - fix similar issue with `else`
This commit is contained in:
120
lib/compress.js
120
lib/compress.js
@@ -924,6 +924,45 @@ merge(Compressor.prototype, {
|
|||||||
// step. nevertheless, it's good to check.
|
// step. nevertheless, it's good to check.
|
||||||
continue loop;
|
continue loop;
|
||||||
case stat instanceof AST_If:
|
case stat instanceof AST_If:
|
||||||
|
var ab = aborts(stat.body);
|
||||||
|
if (can_merge_flow(ab)) {
|
||||||
|
if (ab.label) {
|
||||||
|
remove(ab.label.thedef.references, ab);
|
||||||
|
}
|
||||||
|
CHANGED = true;
|
||||||
|
var funs = extract_functions_from_statement_array(ret);
|
||||||
|
var body = as_statement_array_with_return(stat.body, ab);
|
||||||
|
stat = stat.clone();
|
||||||
|
stat.condition = stat.condition.negate(compressor);
|
||||||
|
stat.body = make_node(AST_BlockStatement, stat, {
|
||||||
|
body: as_statement_array(stat.alternative).concat(ret)
|
||||||
|
});
|
||||||
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
||||||
|
body: body
|
||||||
|
});
|
||||||
|
ret = [ stat.transform(compressor) ].concat(funs);
|
||||||
|
continue loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ab = aborts(stat.alternative);
|
||||||
|
if (can_merge_flow(ab)) {
|
||||||
|
if (ab.label) {
|
||||||
|
remove(ab.label.thedef.references, ab);
|
||||||
|
}
|
||||||
|
CHANGED = true;
|
||||||
|
var funs = extract_functions_from_statement_array(ret);
|
||||||
|
stat = stat.clone();
|
||||||
|
stat.body = make_node(AST_BlockStatement, stat.body, {
|
||||||
|
body: as_statement_array(stat.body).concat(ret)
|
||||||
|
});
|
||||||
|
var body = as_statement_array_with_return(stat.alternative, ab);
|
||||||
|
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
||||||
|
body: body
|
||||||
|
});
|
||||||
|
ret = [ stat.transform(compressor) ].concat(funs);
|
||||||
|
continue loop;
|
||||||
|
}
|
||||||
|
|
||||||
if (stat.body instanceof AST_Return) {
|
if (stat.body instanceof AST_Return) {
|
||||||
var value = stat.body.value;
|
var value = stat.body.value;
|
||||||
//---
|
//---
|
||||||
@@ -960,23 +999,6 @@ merge(Compressor.prototype, {
|
|||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
// if (foo()) return [ void bar() ]; [ else x...; ] y... ==> if (!foo()) { x...; y... } else bar();
|
|
||||||
if (in_lambda && (!value || value instanceof AST_UnaryPrefix && value.operator == "void")) {
|
|
||||||
CHANGED = true;
|
|
||||||
stat = stat.clone();
|
|
||||||
stat.condition = stat.condition.negate(compressor);
|
|
||||||
var funs = extract_functions_from_statement_array(ret);
|
|
||||||
var body = as_statement_array(stat.alternative).concat(ret);
|
|
||||||
stat.body = make_node(AST_BlockStatement, stat, {
|
|
||||||
body: body
|
|
||||||
});
|
|
||||||
stat.alternative = value ? make_node(AST_SimpleStatement, value, {
|
|
||||||
body: value.expression
|
|
||||||
}) : null;
|
|
||||||
ret = [ stat.transform(compressor) ].concat(funs);
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
//---
|
|
||||||
// if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
|
// if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
|
||||||
//
|
//
|
||||||
// if sequences is not enabled, this can lead to an endless loop (issue #866).
|
// if sequences is not enabled, this can lead to an endless loop (issue #866).
|
||||||
@@ -995,48 +1017,6 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ab = aborts(stat.body);
|
|
||||||
var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
|
|
||||||
if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda)
|
|
||||||
|| (ab instanceof AST_Continue && self === loop_body(lct))
|
|
||||||
|| (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) {
|
|
||||||
if (ab.label) {
|
|
||||||
remove(ab.label.thedef.references, ab);
|
|
||||||
}
|
|
||||||
CHANGED = true;
|
|
||||||
var body = as_statement_array(stat.body).slice(0, -1);
|
|
||||||
stat = stat.clone();
|
|
||||||
stat.condition = stat.condition.negate(compressor);
|
|
||||||
stat.body = make_node(AST_BlockStatement, stat, {
|
|
||||||
body: as_statement_array(stat.alternative).concat(ret)
|
|
||||||
});
|
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat, {
|
|
||||||
body: body
|
|
||||||
});
|
|
||||||
ret = [ stat.transform(compressor) ];
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ab = aborts(stat.alternative);
|
|
||||||
var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
|
|
||||||
if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda)
|
|
||||||
|| (ab instanceof AST_Continue && self === loop_body(lct))
|
|
||||||
|| (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) {
|
|
||||||
if (ab.label) {
|
|
||||||
remove(ab.label.thedef.references, ab);
|
|
||||||
}
|
|
||||||
CHANGED = true;
|
|
||||||
stat = stat.clone();
|
|
||||||
stat.body = make_node(AST_BlockStatement, stat.body, {
|
|
||||||
body: as_statement_array(stat.body).concat(ret)
|
|
||||||
});
|
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
|
||||||
body: as_statement_array(stat.alternative).slice(0, -1)
|
|
||||||
});
|
|
||||||
ret = [ stat.transform(compressor) ];
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.unshift(stat);
|
ret.unshift(stat);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1056,6 +1036,28 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_return_void(value) {
|
||||||
|
return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function as_statement_array_with_return(node, ab) {
|
||||||
|
var body = as_statement_array(node).slice(0, -1);
|
||||||
|
if (ab.value) {
|
||||||
|
body.push(make_node(AST_SimpleStatement, ab.value, {
|
||||||
|
body: ab.value.expression
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function eliminate_dead_code(statements, compressor) {
|
function eliminate_dead_code(statements, compressor) {
|
||||||
|
|||||||
@@ -307,6 +307,8 @@ issue_512: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function a() {
|
function a() {
|
||||||
|
|||||||
@@ -136,7 +136,29 @@ defun_hoist_funs: {
|
|||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
function h() {}
|
function h() {}
|
||||||
!window;
|
if (window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_else_if_return: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (window) function g() {}
|
||||||
|
else return;
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (window) function g() {}
|
||||||
|
function h() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user