diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-04-18 15:32:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-18 22:32:22 +0800 |
commit | fd6144d95baebb9eaa75b5695bd75a492479c691 (patch) | |
tree | 061c6e21d2be74f1e431218bdeae1daf4829c082 /lib | |
parent | 60d4e7b09fb962598a9f9f0fb64f92416a9f7e9c (diff) | |
download | tracifyjs-fd6144d95baebb9eaa75b5695bd75a492479c691.tar.gz tracifyjs-fd6144d95baebb9eaa75b5695bd75a492479c691.zip |
enhance `conditionals` (#3798)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 135 |
1 files changed, 94 insertions, 41 deletions
diff --git a/lib/compress.js b/lib/compress.js index 3aa9f0bc..872e2bbf 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5222,50 +5222,53 @@ merge(Compressor.prototype, { self.body = self.alternative || make_node(AST_EmptyStatement, self); self.alternative = tmp; } - if (self.body instanceof AST_SimpleStatement - && self.alternative instanceof AST_SimpleStatement) { - return make_node(AST_SimpleStatement, self, { - body: make_node(AST_Conditional, self, { - condition : self.condition, - consequent : self.body.body, - alternative : self.alternative.body - }) - }).optimize(compressor); - } - if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { - if (self_condition_length === negated_length && !negated_is_best - && self.condition instanceof AST_Binary && self.condition.operator == "||") { - // although the code length of self.condition and negated are the same, - // negated does not require additional surrounding parentheses. - // see https://github.com/mishoo/UglifyJS2/issues/979 - negated_is_best = true; - } - if (negated_is_best) return make_node(AST_SimpleStatement, self, { - body: make_node(AST_Binary, self, { - operator : "||", - left : negated, - right : self.body.body - }).transform(compressor) - }).optimize(compressor); - return make_node(AST_SimpleStatement, self, { - body: make_node(AST_Binary, self, { - operator : "&&", - left : self.condition, - right : self.body.body - }).transform(compressor) + var body = [], var_defs = [], refs = []; + var body_exprs = sequencesize(self.body, body, var_defs, refs); + var alt_exprs = sequencesize(self.alternative, body, var_defs, refs); + if (body_exprs && alt_exprs) { + if (var_defs.length > 0) body.push(make_node(AST_Var, self, { + definitions: var_defs + })); + if (body_exprs.length == 0) { + body.push(make_node(AST_SimpleStatement, self.condition, { + body: alt_exprs.length > 0 ? make_node(AST_Binary, self, { + operator : "||", + left : self.condition, + right : make_sequence(self.alternative, alt_exprs) + }).transform(compressor) : self.condition.clone() + }).optimize(compressor)); + } else if (alt_exprs.length == 0) { + if (self_condition_length === negated_length && !negated_is_best + && self.condition instanceof AST_Binary && self.condition.operator == "||") { + // although the code length of self.condition and negated are the same, + // negated does not require additional surrounding parentheses. + // see https://github.com/mishoo/UglifyJS2/issues/979 + negated_is_best = true; + } + body.push(make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : negated_is_best ? "||" : "&&", + left : negated_is_best ? negated : self.condition, + right : make_sequence(self.body, body_exprs) + }).transform(compressor) + }).optimize(compressor)); + } else { + body.push(make_node(AST_SimpleStatement, self, { + body: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : make_sequence(self.body, body_exprs), + alternative : make_sequence(self.alternative, alt_exprs) + }) + }).optimize(compressor)); + } + refs.forEach(function(ref) { + ref.definition().references.push(ref); + }); + return make_node(AST_BlockStatement, self, { + body: body }).optimize(compressor); } if (is_empty(self.body)) { - if (is_empty(self.alternative)) return make_node(AST_SimpleStatement, self.condition, { - body: self.condition.clone() - }).optimize(compressor); - if (self.alternative instanceof AST_SimpleStatement) return make_node(AST_SimpleStatement, self, { - body: make_node(AST_Binary, self, { - operator : "||", - left : self.condition, - right : self.alternative.body - }).transform(compressor) - }).optimize(compressor); self = make_node(AST_If, self, { condition: negated, body: self.alternative, @@ -5320,6 +5323,56 @@ merge(Compressor.prototype, { } if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative); return self; + + function sequencesize(stat, defuns, var_defs, refs) { + if (stat == null) return []; + if (stat instanceof AST_BlockStatement) { + var exprs = []; + for (var i = 0; i < stat.body.length; i++) { + var line = stat.body[i]; + if (line instanceof AST_Defun) { + defuns.push(line); + } else if (line instanceof AST_EmptyStatement) { + continue; + } else if (line instanceof AST_SimpleStatement) { + if (!compressor.option("sequences") && exprs.length > 0) return; + exprs.push(line.body); + } else if (line instanceof AST_Var) { + if (!compressor.option("sequences") && exprs.length > 0) return; + line.definitions.forEach(process_var_def); + } else { + return; + } + } + return exprs; + } + if (stat instanceof AST_Defun) { + defuns.push(stat); + return []; + } + if (stat instanceof AST_EmptyStatement) return []; + if (stat instanceof AST_SimpleStatement) return [ stat.body ]; + if (stat instanceof AST_Var) { + var exprs = []; + stat.definitions.forEach(process_var_def); + return exprs; + } + + function process_var_def(var_def) { + var_defs.push(make_node(AST_VarDef, var_def, { + name: var_def.name, + value: null + })); + if (!var_def.value) return; + var ref = make_node(AST_SymbolRef, var_def.name, var_def.name); + exprs.push(make_node(AST_Assign, var_def, { + operator: "=", + left: ref, + right: var_def.value + })); + refs.push(ref); + } + } }); OPT(AST_Switch, function(self, compressor) { |