Skip to content

Commit

Permalink
enhance conditionals
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Aug 16, 2024
1 parent 23f98ba commit ba20ec8
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 4 deletions.
57 changes: 53 additions & 4 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -11673,7 +11673,7 @@ Compressor.prototype.compress = function(node) {
OPT(AST_Sequence, function(self, compressor) {
var expressions = filter_for_side_effects();
var end = expressions.length - 1;
merge_assignments();
merge_expressions();
trim_right_for_undefined();
if (end == 0) {
self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]);
Expand Down Expand Up @@ -11717,12 +11717,58 @@ Compressor.prototype.compress = function(node) {
&& node.left.definition();
}

function merge_assignments() {
for (var i = 1; i < end; i++) {
function can_reorder(op1, op2) {
return op1 == op2 || op1 == "||" && op2 == "&&";
}

function is_lazy(node) {
return node instanceof AST_Binary && lazy_op[node.operator];
}

function merge_condition(a, b) {
if (is_lazy(a) && is_lazy(b) && a.operator == b.operator
&& a.left.equals(b.left) && repeatable(compressor, a.left)) {
var node = a.clone();
node.right = make_sequence(self, [ a.right, b.right ]);
return node;
}
if (is_lazy(a) && is_lazy(a.left) && can_reorder(a.left.operator, a.operator)) {
var c = merge_condition(a.left, b);
if (c) {
a = a.clone();
a.left = a.left.right.tail_node();
c.right.expressions[c.right.expressions.indexOf(a.left)] = a;
return c;
}
}
if (is_lazy(b) && is_lazy(b.left) && can_reorder(b.left.operator, b.operator)) {
var d = merge_condition(a, b.left);
if (d) {
b = b.clone();
b.left = b.left.right.tail_node();
d.right.expressions[d.right.expressions.indexOf(b.left)] = b;
return d;
}
}
}

function merge_expressions() {
for (var i = 1; i <= end; i++) {
var prev = expressions[i - 1];
var expr = expressions[i];
// (a && b, a && c && d) ---> a && (b, c && d)
// (a && b && c, a && d || e) ---> a && (b && c, d || e)
if (compressor.option("conditionals")) {
var node = merge_condition(prev, expr);
if (node) {
expressions.splice(--i, 2, node);
end--;
continue;
}
}
if (i == end) break;
var def = is_simple_assign(prev);
if (!def) continue;
var expr = expressions[i];
if (compressor.option("conditionals")) {
var cond = to_conditional_assignment(compressor, def, prev.right, expr);
if (cond) {
Expand Down Expand Up @@ -11995,6 +12041,9 @@ Compressor.prototype.compress = function(node) {
}

function repeatable(compressor, node) {
if (node instanceof AST_Binary && lazy_op[node.operator]) {
return repeatable(compressor, node.left) && repeatable(compressor, node.right);
}
if (node instanceof AST_Dot) return repeatable(compressor, node.expression);
if (node instanceof AST_Sub) {
return repeatable(compressor, node.expression) && repeatable(compressor, node.property);
Expand Down
69 changes: 69 additions & 0 deletions test/compress/conditionals.js
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,75 @@ extendscript_2: {
]
}

common_condition_1: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a, b) {
a && console.log("foo");
a && b && console.log("bar");
a && b || console.log("baz");
}
f(false, false);
f(false, true);
f(true, false);
f(true, true);
}
expect: {
function f(a, b) {
a && (console.log("foo"), b && console.log("bar")),
a && b || console.log("baz");
}
f(false, false),
f(false, true),
f(true, false),
f(true, true);
}
expect_stdout: [
"baz",
"baz",
"foo",
"baz",
"foo",
"bar",
]
}

common_condition_2: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a, b) {
a || console.log("foo");
a || b || console.log("bar");
a || b && console.log("baz");
}
f(false, false);
f(false, true);
f(true, false);
f(true, true);
}
expect: {
function f(a, b) {
a || (console.log("foo"), b || console.log("bar"), b && console.log("baz"));
}
f(false, false),
f(false, true),
f(true, false),
f(true, true);
}
expect_stdout: [
"foo",
"bar",
"foo",
"baz",
]
}

issue_1154: {
options = {
booleans: true,
Expand Down

0 comments on commit ba20ec8

Please sign in to comment.