diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/lib/compress.js b/lib/compress.js index c5b67569..c00b9f07 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -7005,25 +7005,42 @@ merge(Compressor.prototype, { }); } } - // x ? y(a) : y(b) --> y(x ? a : b) - var arg_index; + // x ? y : y --> x, y + if (consequent.equivalent_to(alternative)) return make_sequence(self, [ + condition, + consequent + ]).optimize(compressor); if (consequent instanceof AST_Call && alternative.TYPE === consequent.TYPE - && consequent.args.length > 0 - && consequent.args.length == alternative.args.length - && consequent.expression.equivalent_to(alternative.expression) - && !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: condition, - consequent: consequent.args[arg_index], - alternative: alternative.args[arg_index] - }); - return node; + && consequent.args.length == alternative.args.length) { + var arg_index = arg_diff(); + // x ? y(a) : z(a) --> (x ? y : z)(a) + if (arg_index == -1 + && !(consequent.expression instanceof AST_PropAccess) + && !(alternative.expression instanceof AST_PropAccess)) { + var node = consequent.clone(); + node.expression = make_node(AST_Conditional, self, { + condition: condition, + consequent: consequent.expression, + alternative: alternative.expression + }); + return node; + } + // x ? y(a) : y(b) --> y(x ? a : b) + if (arg_index >= 0 + && consequent.expression.equivalent_to(alternative.expression) + && !condition.has_side_effects(compressor) + && !consequent.expression.has_side_effects(compressor)) { + var node = consequent.clone(); + node.args[arg_index] = make_node(AST_Conditional, self, { + condition: condition, + consequent: consequent.args[arg_index], + alternative: alternative.args[arg_index] + }); + return node; + } } - // x?y?z:a:a --> x&&y?z:a + // x ? (y ? a : b) : b --> x && y ? a : b if (consequent instanceof AST_Conditional && consequent.alternative.equivalent_to(alternative)) { return make_node(AST_Conditional, self, { @@ -7036,12 +7053,18 @@ merge(Compressor.prototype, { alternative: alternative }); } - // x ? y : y --> x, y - if (consequent.equivalent_to(alternative)) { - return make_sequence(self, [ - condition, - consequent - ]).optimize(compressor); + // x ? a : (y ? a : b)--> x || y ? a : b + if (alternative instanceof AST_Conditional + && consequent.equivalent_to(alternative.consequent)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: condition, + operator: "||", + right: alternative.condition + }), + consequent: consequent, + alternative: alternative.alternative + }); } // x ? (y, w) : (z, w) --> x ? y : z, w if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence) @@ -7145,17 +7168,18 @@ merge(Compressor.prototype, { && node.expression.getValue()); } - function single_arg_diff() { + function 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; + if (!a[j].equivalent_to(b[j])) return -2; } return i; } } + return -1; } function can_shift_lhs_of_tail(node) { |