aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js31
-rw-r--r--test/compress/conditionals.js128
2 files changed, 132 insertions, 27 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 4195ab24..e59dce63 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4652,18 +4652,22 @@ merge(Compressor.prototype, {
});
}
// x ? y(a) : y(b) --> y(x ? a : b)
+ var arg_index;
if (consequent instanceof AST_Call
&& alternative.TYPE === consequent.TYPE
- && consequent.args.length == 1
- && alternative.args.length == 1
+ && consequent.args.length > 0
+ && consequent.args.length == alternative.args.length
&& consequent.expression.equivalent_to(alternative.expression)
- && !consequent.expression.has_side_effects(compressor)) {
- consequent.args[0] = make_node(AST_Conditional, self, {
+ && !self.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,
- consequent: consequent.args[0],
- alternative: alternative.args[0]
+ consequent: consequent.args[arg_index],
+ alternative: alternative.args[arg_index]
});
- return consequent;
+ return node;
}
// x?y?z:a:a --> x&&y?z:a
if (consequent instanceof AST_Conditional
@@ -4760,6 +4764,19 @@ merge(Compressor.prototype, {
&& node.expression instanceof AST_Constant
&& node.expression.getValue());
}
+
+ function single_arg_diff() {
+ var a = consequent.args;
+ var b = alternative.args;
+ for (var i = 0, len = a.length; i < len; i++) {
+ if (!a[i].equivalent_to(b[i])) {
+ for (var j = i + 1; j < len; j++) {
+ if (!a[j].equivalent_to(b[j])) return;
+ }
+ return i;
+ }
+ }
+ }
});
OPT(AST_Boolean, function(self, compressor){
diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js
index 89c05263..143ece4a 100644
--- a/test/compress/conditionals.js
+++ b/test/compress/conditionals.js
@@ -166,22 +166,24 @@ cond_1: {
conditionals: true
};
input: {
- var do_something; // if undeclared it's assumed to have side-effects
- if (some_condition()) {
- do_something(x);
- } else {
- do_something(y);
- }
- if (some_condition()) {
- side_effects(x);
- } else {
- side_effects(y);
+ function foo(do_something, some_condition) {
+ if (some_condition) {
+ do_something(x);
+ } else {
+ do_something(y);
+ }
+ if (some_condition) {
+ side_effects(x);
+ } else {
+ side_effects(y);
+ }
}
}
expect: {
- var do_something;
- do_something(some_condition() ? x : y);
- some_condition() ? side_effects(x) : side_effects(y);
+ function foo(do_something, some_condition) {
+ do_something(some_condition ? x : y);
+ some_condition ? side_effects(x) : side_effects(y);
+ }
}
}
@@ -190,16 +192,18 @@ cond_2: {
conditionals: true
};
input: {
- var x, FooBar;
- if (some_condition()) {
- x = new FooBar(1);
- } else {
- x = new FooBar(2);
+ function foo(x, FooBar, some_condition) {
+ if (some_condition) {
+ x = new FooBar(1);
+ } else {
+ x = new FooBar(2);
+ }
}
}
expect: {
- var x, FooBar;
- x = new FooBar(some_condition() ? 1 : 2);
+ function foo(x, FooBar, some_condition) {
+ x = new FooBar(some_condition ? 1 : 2);
+ }
}
}
@@ -605,6 +609,42 @@ cond_8c: {
}
}
+cond_9: {
+ options = {
+ conditionals: true,
+ }
+ input: {
+ function f(x, y) {
+ g() ? x(1) : x(2);
+ x ? (y || x)() : (y || x)();
+ x ? y(a, b) : y(d, b, c);
+ x ? y(a, b, c) : y(a, b, c);
+ x ? y(a, b, c) : y(a, b, f);
+ x ? y(a, b, c) : y(a, e, c);
+ x ? y(a, b, c) : y(a, e, f);
+ x ? y(a, b, c) : y(d, b, c);
+ x ? y(a, b, c) : y(d, b, f);
+ x ? y(a, b, c) : y(d, e, c);
+ x ? y(a, b, c) : y(d, e, f);
+ }
+ }
+ expect: {
+ function f(x, y) {
+ g() ? x(1) : x(2);
+ x, (y || x)();
+ x ? y(a, b) : y(d, b, c);
+ x, y(a, b, c);
+ y(a, b, x ? c : f);
+ y(a, x ? b : e, c);
+ x ? y(a, b, c) : y(a, e, f);
+ y(x ? a : d, b, c);
+ x ? y(a, b, c) : y(d, b, f);
+ x ? y(a, b, c) : y(d, e, c);
+ x ? y(a, b, c) : y(d, e, f);
+ }
+ }
+}
+
ternary_boolean_consequent: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
@@ -1115,3 +1155,51 @@ issue_2535_2: {
"false",
]
}
+
+issue_2560: {
+ options = {
+ conditionals: true,
+ inline: true,
+ reduce_funcs: true,
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ function log(x) {
+ console.log(x);
+ }
+ function foo() {
+ return log;
+ }
+ function bar() {
+ if (x !== (x = foo())) {
+ x(1);
+ } else {
+ x(2);
+ }
+ }
+ var x = function() {
+ console.log("init");
+ };
+ bar();
+ bar();
+ }
+ expect: {
+ function log(x) {
+ console.log(x);
+ }
+ function bar() {
+ x !== (x = log) ? x(1) : x(2);
+ }
+ var x = function() {
+ console.log("init");
+ };
+ bar();
+ bar();
+ }
+ expect_stdout: [
+ "1",
+ "2",
+ ]
+}