Skip to content

Commit

Permalink
enhance merge_vars (#5349)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Feb 12, 2022
1 parent 33c163f commit 6d0bb58
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 20 deletions.
58 changes: 38 additions & 20 deletions lib/compress.js
Expand Up @@ -6025,10 +6025,7 @@ Compressor.prototype.compress = function(node) {
}
if (node instanceof AST_Binary) {
if (!lazy_op[node.operator]) return;
node.left.walk(tw);
push();
node.right.walk(tw);
pop();
walk_cond(node);
return true;
}
if (node instanceof AST_Break) {
Expand All @@ -6053,13 +6050,7 @@ Compressor.prototype.compress = function(node) {
return true;
}
if (node instanceof AST_Conditional) {
node.condition.walk(tw);
push();
node.consequent.walk(tw);
pop();
push();
node.alternative.walk(tw);
pop();
walk_cond(node.condition, node.consequent, node.alternative);
return true;
}
if (node instanceof AST_Continue) {
Expand Down Expand Up @@ -6100,15 +6091,7 @@ Compressor.prototype.compress = function(node) {
return true;
}
if (node instanceof AST_If) {
node.condition.walk(tw);
push();
node.body.walk(tw);
pop();
if (node.alternative) {
push();
node.alternative.walk(tw);
pop();
}
walk_cond(node.condition, node.body, node.alternative);
return true;
}
if (node instanceof AST_LabeledStatement) {
Expand Down Expand Up @@ -6276,6 +6259,41 @@ Compressor.prototype.compress = function(node) {
}
return true;
}

function walk_cond(condition, consequent, alternative) {
var save = segment;
var segments = [ save, save ];
if (condition instanceof AST_Binary) switch (condition.operator) {
case "&&":
segments[0] = walk_cond(condition.left, condition.right)[0];
break;
case "||":
case "??":
segments[1] = walk_cond(condition.left, null, condition.right)[1];
break;
default:
condition.walk(tw);
break;
} else if (condition instanceof AST_Conditional) {
walk_cond(condition.condition, condition.consequent, condition.alternative);
} else {
condition.walk(tw);
}
segment = segments[0];
if (consequent) {
push();
consequent.walk(tw);
}
segments[0] = segment;
segment = segments[1];
if (alternative) {
push();
alternative.walk(tw);
}
segments[1] = segment;
segment = save;
return segments;
}
});
tw.directives = Object.create(compressor.directives);
self.walk(tw);
Expand Down
152 changes: 152 additions & 0 deletions test/compress/merge_vars.js
Expand Up @@ -169,6 +169,158 @@ conditional_branch: {
expect_stdout: "PASS"
}

conditional_chain_1: {
options = {
merge_vars: true,
}
input: {
function f(a, b) {
var c, d;
if (a && (c = a))
console.log(c);
else
b || (d = b) ? console.log("foo") : console.log(d);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect: {
function f(a, b) {
var a, a;
if (a && (a = a))
console.log(a);
else
b || (a = b) ? console.log("foo") : console.log(a);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect_stdout: [
"null",
"foo",
"42",
"42",
]
}

conditional_chain_2: {
options = {
merge_vars: true,
}
input: {
function f(a, b) {
var c, d;
if (a && (c = a))
console.log(c);
else
b || (d = b) ? console.log(c) : console.log(d);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect: {
function f(a, b) {
var c, a;
if (a && (c = a))
console.log(c);
else
b || (a = b) ? console.log(c) : console.log(a);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect_stdout: [
"null",
"undefined",
"42",
"42",
]
}

conditional_chain_3: {
options = {
merge_vars: true,
}
input: {
function f(a, b) {
var c, d;
if (a && (c = a) || b || (d = b))
console.log(c);
else
console.log(d);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect: {
function f(a, b) {
var c, a;
if (a && (c = a) || b || (a = b))
console.log(c);
else
console.log(a);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect_stdout: [
"null",
"undefined",
"42",
"42",
]
}

conditional_chain_4: {
options = {
merge_vars: true,
}
input: {
function f(a, b) {
var c, d;
if (a && b ? c = a : d = b)
console.log(c);
else
console.log(d);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect: {
function f(a, b) {
var c, d;
if (a && b ? c = a : d = b)
console.log(c);
else
console.log(d);
}
f("", null);
f("", true);
f(42, null);
f(42, true);
}
expect_stdout: [
"null",
"undefined",
"null",
"42",
]
}

if_branch: {
options = {
merge_vars: true,
Expand Down

0 comments on commit 6d0bb58

Please sign in to comment.