aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js57
-rw-r--r--test/compress/conditionals.js72
2 files changed, 105 insertions, 24 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 9e4ab315..53ed4afc 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -6047,20 +6047,22 @@ merge(Compressor.prototype, {
// |
// v
// exp = foo ? something : something_else;
- if (consequent instanceof AST_Assign
- && alternative instanceof AST_Assign
- && consequent.operator == alternative.operator
- && consequent.left.equivalent_to(alternative.left)
- && (!self.condition.has_side_effects(compressor)
- || consequent.operator == "="
- && !consequent.left.has_side_effects(compressor))) {
+ var seq_tail = consequent.tail_node();
+ var alt_tail = alternative.tail_node();
+ if (seq_tail instanceof AST_Assign
+ && alt_tail instanceof AST_Assign
+ && seq_tail.operator == alt_tail.operator
+ && seq_tail.left.equivalent_to(alt_tail.left)
+ && (!condition.has_side_effects(compressor)
+ || seq_tail.operator == "="
+ && !seq_tail.left.has_side_effects(compressor))) {
return make_node(AST_Assign, self, {
- operator: consequent.operator,
- left: consequent.left,
+ operator: seq_tail.operator,
+ left: seq_tail.left,
right: make_node(AST_Conditional, self, {
- condition: self.condition,
- consequent: consequent.right,
- alternative: alternative.right
+ condition: condition,
+ consequent: pop_lhs(consequent),
+ alternative: pop_lhs(alternative)
})
});
}
@@ -6071,12 +6073,12 @@ merge(Compressor.prototype, {
&& consequent.args.length > 0
&& consequent.args.length == alternative.args.length
&& consequent.expression.equivalent_to(alternative.expression)
- && !self.condition.has_side_effects(compressor)
+ && !condition.has_side_effects(compressor)
&& !consequent.expression.has_side_effects(compressor)
&& typeof (arg_index = single_arg_diff()) == "number") {
var node = consequent.clone();
node.args[arg_index] = make_node(AST_Conditional, self, {
- condition: self.condition,
+ condition: condition,
consequent: consequent.args[arg_index],
alternative: alternative.args[arg_index]
});
@@ -6087,7 +6089,7 @@ merge(Compressor.prototype, {
&& consequent.alternative.equivalent_to(alternative)) {
return make_node(AST_Conditional, self, {
condition: make_node(AST_Binary, self, {
- left: self.condition,
+ left: condition,
operator: "&&",
right: consequent.condition
}),
@@ -6098,7 +6100,7 @@ merge(Compressor.prototype, {
// x ? y : y --> x, y
if (consequent.equivalent_to(alternative)) {
return make_sequence(self, [
- self.condition,
+ condition,
consequent
]).optimize(compressor);
}
@@ -6107,7 +6109,7 @@ merge(Compressor.prototype, {
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
return make_sequence(self, [
make_node(AST_Conditional, self, {
- condition: self.condition,
+ condition: condition,
consequent: pop_seq(consequent),
alternative: pop_seq(alternative)
}),
@@ -6122,7 +6124,7 @@ merge(Compressor.prototype, {
operator: "||",
left: make_node(AST_Binary, self, {
operator: "&&",
- left: self.condition,
+ left: condition,
right: consequent.left
}),
right: alternative
@@ -6132,24 +6134,24 @@ merge(Compressor.prototype, {
if (is_true(self.consequent)) {
if (is_false(self.alternative)) {
// c ? true : false ---> !!c
- return booleanize(self.condition);
+ return booleanize(condition);
}
// c ? true : x ---> !!c || x
return make_node(AST_Binary, self, {
operator: "||",
- left: booleanize(self.condition),
+ left: booleanize(condition),
right: self.alternative
});
}
if (is_false(self.consequent)) {
if (is_true(self.alternative)) {
// c ? false : true ---> !c
- return booleanize(self.condition.negate(compressor));
+ return booleanize(condition.negate(compressor));
}
// c ? false : x ---> !c && x
return make_node(AST_Binary, self, {
operator: "&&",
- left: booleanize(self.condition.negate(compressor)),
+ left: booleanize(condition.negate(compressor)),
right: self.alternative
});
}
@@ -6157,7 +6159,7 @@ merge(Compressor.prototype, {
// c ? x : true ---> !c || x
return make_node(AST_Binary, self, {
operator: "||",
- left: booleanize(self.condition.negate(compressor)),
+ left: booleanize(condition.negate(compressor)),
right: self.consequent
});
}
@@ -6165,7 +6167,7 @@ merge(Compressor.prototype, {
// c ? x : false ---> !!c && x
return make_node(AST_Binary, self, {
operator: "&&",
- left: booleanize(self.condition),
+ left: booleanize(condition),
right: self.consequent
});
}
@@ -6217,6 +6219,13 @@ merge(Compressor.prototype, {
}
}
+ function pop_lhs(node) {
+ if (!(node instanceof AST_Sequence)) return node.right;
+ var exprs = node.expressions.slice();
+ exprs.push(exprs.pop().right);
+ return make_sequence(node, exprs);
+ }
+
function pop_seq(node) {
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
value: 0
diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js
index 577e7871..35505c87 100644
--- a/test/compress/conditionals.js
+++ b/test/compress/conditionals.js
@@ -1292,3 +1292,75 @@ to_and_or: {
}
expect_stdout: true
}
+
+cond_seq_assign_1: {
+ options = {
+ conditionals: true,
+ sequences: true,
+ }
+ input: {
+ function f(a) {
+ var t;
+ if (a) {
+ t = "foo";
+ t = "bar";
+ } else {
+ console.log(t);
+ t = 42;
+ }
+ console.log(t);
+ }
+ f(f);
+ f();
+ }
+ expect: {
+ function f(a) {
+ var t;
+ t = a ? (t = "foo", "bar") : (console.log(t), 42),
+ console.log(t);
+ }
+ f(f),
+ f();
+ }
+ expect_stdout: [
+ "bar",
+ "undefined",
+ "42",
+ ]
+}
+
+cond_seq_assign_2: {
+ options = {
+ conditionals: true,
+ sequences: true,
+ }
+ input: {
+ function f(a) {
+ var t;
+ if (a) {
+ t = "foo";
+ a = "bar";
+ } else {
+ console.log(t);
+ t = 42;
+ }
+ console.log(t);
+ }
+ f(f);
+ f();
+ }
+ expect: {
+ function f(a) {
+ var t;
+ a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
+ console.log(t);
+ }
+ f(f),
+ f();
+ }
+ expect_stdout: [
+ "foo",
+ "undefined",
+ "42",
+ ]
+}