Skip to content

Commit

Permalink
enhance conditionals, if_return & side_effects (#5348)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Feb 12, 2022
1 parent 6d0bb58 commit a14555a
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 164 deletions.
96 changes: 46 additions & 50 deletions lib/compress.js
Expand Up @@ -3336,23 +3336,24 @@ Compressor.prototype.compress = function(node) {
if (ab.label) remove(ab.label.thedef.references, ab);
changed = true;
stat = stat.clone();
stat.condition = stat.condition.negate(compressor);
var body = as_statement_array_with_return(stat.body, ab);
stat.body = make_node(AST_BlockStatement, stat, {
body: as_statement_array_with_return(stat.body, ab),
});
stat.alternative = make_node(AST_BlockStatement, stat, {
body: as_statement_array(stat.alternative).concat(extract_functions()),
});
stat.alternative = make_node(AST_BlockStatement, stat, { body: body });
statements[i] = stat;
statements[i] = stat.transform(compressor);
continue;
}

if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
var negated = stat.condition.negate(compressor);
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
if (ab && !stat.alternative && next instanceof AST_Jump) {
var cond = stat.condition;
cond = best_of_expression(cond, cond.negate(compressor), stat.body instanceof AST_BlockStatement);
if (cond !== stat.condition) {
changed = true;
stat = stat.clone();
stat.condition = negated;
stat.condition = cond;
statements[j] = stat.body;
stat.body = next;
statements[i] = stat;
Expand All @@ -3369,8 +3370,9 @@ Compressor.prototype.compress = function(node) {
stat.body = make_node(AST_BlockStatement, stat.body, {
body: as_statement_array(stat.body).concat(extract_functions()),
});
var body = as_statement_array_with_return(stat.alternative, alt);
stat.alternative = make_node(AST_BlockStatement, stat.alternative, { body: body });
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
body: as_statement_array_with_return(stat.alternative, alt),
});
statements[i] = stat;
statements[i] = stat.transform(compressor);
continue;
Expand All @@ -3392,15 +3394,6 @@ Compressor.prototype.compress = function(node) {
var value = stat.body.value;
var in_bool = stat.body.in_bool || next instanceof AST_Return && next.in_bool;
//---
// pretty silly case, but:
// if (foo()) return; return; ---> foo(); return;
if (!value && !stat.alternative
&& (in_lambda && !next || next instanceof AST_Return && !next.value)) {
changed = true;
statements[i] = make_node(AST_SimpleStatement, stat.condition, { body: stat.condition });
continue;
}
//---
// if (foo()) return x; return y; ---> return foo() ? x : y;
if (!stat.alternative && next instanceof AST_Return) {
changed = true;
Expand Down Expand Up @@ -8211,12 +8204,12 @@ Compressor.prototype.compress = function(node) {
node.right = rhs.drop_side_effect_free(compressor);
}
if (op == "??") return node;
var negated = make_node(AST_Binary, this, {
operator: op == "&&" ? "||" : "&&",
left: left.negate(compressor, first_in_statement),
right: node.right,
});
return first_in_statement ? best_of_statement(node, negated) : best_of_expression(node, negated);
var negated = node.clone();
negated.operator = op == "&&" ? "||" : "&&";
negated.left = left.negate(compressor, first_in_statement);
if (negated.operator == negated.right.operator) swap_chain(negated);
var best = first_in_statement ? best_of_statement : best_of_expression;
return op == "&&" ? best(node, negated) : best(negated, node);
}
var lhs = left.drop_side_effect_free(compressor, first_in_statement);
if (!lhs) return rhs;
Expand Down Expand Up @@ -9082,8 +9075,8 @@ Compressor.prototype.compress = function(node) {
// here because they are only used in an equality comparison later on.
self.condition = negated;
var tmp = self.body;
self.body = self.alternative || make_node(AST_EmptyStatement, self);
self.alternative = tmp;
self.body = self.alternative;
self.alternative = is_empty(tmp) ? null : tmp;
}
var body_defuns = [];
var body_var_defs = [];
Expand Down Expand Up @@ -9220,10 +9213,12 @@ Compressor.prototype.compress = function(node) {
var line = stat.body[i];
if (line instanceof AST_EmptyStatement) continue;
if (line instanceof AST_Exit) {
if (exprs.length == 0) return;
line = line.clone();
exprs.push(line.value || make_node(AST_Undefined, line).transform(compressor));
line.value = make_sequence(stat, exprs);
if (i == 0) return;
if (exprs.length > 0) {
line = line.clone();
exprs.push(line.value || make_node(AST_Undefined, line).transform(compressor));
line.value = make_sequence(stat, exprs);
}
var block = stat.clone();
block.body = block.body.slice(i + 1);
block.body.unshift(line);
Expand Down Expand Up @@ -10962,6 +10957,23 @@ Compressor.prototype.compress = function(node) {
return !node.has_side_effects(compressor);
}

function swap_chain(self, compressor) {
var rhs = self.right;
self.left = make_node(AST_Binary, self, {
operator: self.operator,
left: self.left,
right: rhs.left,
start: self.left.start,
end: rhs.left.end
});
self.right = rhs.right;
if (compressor) {
self.left = self.left.transform(compressor);
} else if (self.operator == rhs.left.operator) {
swap_chain(self.left);
}
}

OPT(AST_Binary, function(self, compressor) {
if (commutativeOperators[self.operator]
&& self.right.is_constant()
Expand Down Expand Up @@ -11132,7 +11144,7 @@ Compressor.prototype.compress = function(node) {
&& lazy_op[self.operator]
&& self.right instanceof AST_Binary
&& self.operator == self.right.operator) {
swap_chain();
swap_chain(self, compressor);
}
if (compressor.option("strings") && self.operator == "+") {
// "foo" + 42 + "" ---> "foo" + 42
Expand Down Expand Up @@ -11164,7 +11176,7 @@ Compressor.prototype.compress = function(node) {
&& (self.left.is_string(compressor) && self.right.is_string(compressor)
|| self.right.left.is_string(compressor)
&& (self.left.is_constant() || !self.right.right.has_side_effects(compressor)))) {
swap_chain();
swap_chain(self, compressor);
}
}
if (compressor.option("evaluate")) {
Expand Down Expand Up @@ -11631,19 +11643,6 @@ Compressor.prototype.compress = function(node) {
self.right = tmp;
}
}

function swap_chain() {
var rhs = self.right;
self.left = make_node(AST_Binary, self, {
operator: self.operator,
left: self.left,
right: rhs.left,
start: self.left.start,
end: rhs.left.end
});
self.right = rhs.right;
self.left = self.left.transform(compressor);
}
});

OPT(AST_SymbolExport, function(self) {
Expand Down Expand Up @@ -12747,7 +12746,7 @@ Compressor.prototype.compress = function(node) {
if (flatten && value.has_side_effects(compressor)) flatten = false;
}
}
if (!flatten) values.unshift(retValue);
values.unshift(retValue);
while (--i >= 0) {
var value = elements[i].drop_side_effect_free(compressor);
if (value) {
Expand All @@ -12758,10 +12757,7 @@ Compressor.prototype.compress = function(node) {
index--;
}
}
if (flatten) {
values.push(retValue);
return make_sequence(self, values).optimize(compressor);
} else return make_node(AST_Sub, self, {
return flatten ? make_sequence(self, values).optimize(compressor) : make_node(AST_Sub, self, {
expression: make_node(AST_Array, expr, { elements: values }),
property: make_node(AST_Number, prop, { value: index }),
});
Expand Down
2 changes: 1 addition & 1 deletion test/compress/comparisons.js
Expand Up @@ -489,7 +489,7 @@ issue_3413: {
}
expect: {
var b;
void 0 !== ("" < b || void 0) || console.log("PASS");
void 0 === ("" < b || void 0) && console.log("PASS");
}
expect_stdout: "PASS"
}
7 changes: 3 additions & 4 deletions test/compress/const.js
Expand Up @@ -597,8 +597,7 @@ do_if_continue_1: {
}
expect: {
do {
if (!console);
else {
if (console) {
console.log("PASS");
{
const a = 0;
Expand Down Expand Up @@ -628,8 +627,7 @@ do_if_continue_2: {
}
expect: {
do {
if (!console);
else {
if (console) {
console.log("PASS");
{
const a = 0;
Expand Down Expand Up @@ -1518,6 +1516,7 @@ issue_4689: {

issue_4691: {
options = {
conditionals: true,
if_return: true,
toplevel: true,
}
Expand Down
10 changes: 5 additions & 5 deletions test/compress/functions.js
Expand Up @@ -7981,6 +7981,7 @@ issue_5264_2: {

issue_5283: {
options = {
conditionals: true,
if_return: true,
inline: true,
pure_getters: "strict",
Expand All @@ -8005,11 +8006,10 @@ issue_5283: {
var a = "FAIL 1";
(function() {
a = "PASS";
if (!console)
(function(a) {
console.log("FAIL 2");
a.p;
})();
console || function(a) {
console.log("FAIL 2");
a.p;
}();
})();
console.log(a);
}
Expand Down
15 changes: 8 additions & 7 deletions test/compress/if_return.js
Expand Up @@ -698,7 +698,9 @@ iife_if_return_simple: {

nested_if_break: {
options = {
conditionals: true,
if_return: true,
side_effects: true,
}
input: {
for (var i = 0; i < 3; i++)
Expand All @@ -709,8 +711,7 @@ nested_if_break: {
}
expect: {
for (var i = 0; i < 3; i++)
L1: if ("number" == typeof i)
if (0 !== i) console.log(i);
L1: "number" == typeof i && 0 !== i && console.log(i);
}
expect_stdout: [
"1",
Expand Down Expand Up @@ -749,11 +750,11 @@ nested_if_continue: {
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
? console.log("even", i)
: 1 === n
? console.log("odd", i)
: i++),
0 <= (n -= 2););
}
f(37);
Expand Down

0 comments on commit a14555a

Please sign in to comment.