diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-09-15 22:51:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-16 05:51:42 +0800 |
commit | 20391850518f4050917a4812af07520eb47cfecf (patch) | |
tree | c1bd66edfb47f36988052472bde677497da4b082 /lib/compress.js | |
parent | ad27c1420226032459157444cf7ac17bf95bd5e6 (diff) | |
download | tracifyjs-20391850518f4050917a4812af07520eb47cfecf.tar.gz tracifyjs-20391850518f4050917a4812af07520eb47cfecf.zip |
enhance `conditionals` (#4106)
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/lib/compress.js b/lib/compress.js index 52ed0e61..dbf4e09d 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8456,35 +8456,26 @@ merge(Compressor.prototype, { condition, consequent ]).optimize(compressor); + // x ? y.p : z.p => (x ? y : z).p + // x ? y(a) : z(a) => (x ? y : z)(a) + // x ? y.f(a) : z.f(a) => (x ? y : z).f(a) + var combined = combine_tail(consequent, alternative, true); + if (combined) return combined; + // x ? y(a) : y(b) => y(x ? a : b) + var arg_index; if (consequent instanceof AST_Call - && alternative.TYPE === consequent.TYPE - && 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; - } + && alternative.TYPE == consequent.TYPE + && (arg_index = arg_diff(consequent, alternative)) >= 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 ? a : b) : b => x && y ? a : b if (consequent instanceof AST_Conditional @@ -8685,10 +8676,12 @@ merge(Compressor.prototype, { && node.expression.value); } - function arg_diff() { + function arg_diff(consequent, alternative) { var a = consequent.args; var b = alternative.args; - for (var i = 0, len = a.length; i < len; i++) { + var len = a.length; + if (len != b.length) return -2; + for (var i = 0; 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 -2; @@ -8699,6 +8692,32 @@ merge(Compressor.prototype, { return -1; } + function is_tail_equivalent(consequent, alternative) { + if (consequent.TYPE != alternative.TYPE) return; + if (consequent instanceof AST_Call) { + if (arg_diff(consequent, alternative) != -1) return; + return consequent.TYPE != "Call" + || !(consequent.expression instanceof AST_PropAccess + || alternative.expression instanceof AST_PropAccess) + || is_tail_equivalent(consequent.expression, alternative.expression); + } + if (consequent instanceof AST_Dot) return consequent.property == alternative.property; + if (consequent instanceof AST_Sub) return consequent.property.equivalent_to(alternative.property); + } + + function combine_tail(consequent, alternative, top) { + if (!is_tail_equivalent(consequent, alternative)) return !top && make_node(AST_Conditional, self, { + condition: condition, + consequent: consequent, + alternative: alternative + }); + var exp = combine_tail(consequent.expression, alternative.expression); + if (!exp) return; + var node = consequent.clone(); + node.expression = exp; + return node; + } + function can_shift_lhs_of_tail(node) { return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) { return !expr.has_side_effects(compressor); |