From: Alex Lam S.L Date: Thu, 30 Nov 2017 19:40:46 +0000 (+0800) Subject: improve code reuse (#2542) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=172079a47f2f7bf09d2a5b4e4cf05691a1206358;p=UglifyJS.git improve code reuse (#2542) --- diff --git a/lib/ast.js b/lib/ast.js index a2aa2b40..997486c2 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -898,24 +898,6 @@ TreeWalker.prototype = { } } }, - in_boolean_context: function() { - var stack = this.stack; - var i = stack.length, self = stack[--i]; - while (i > 0) { - var p = stack[--i]; - if ((p instanceof AST_If && p.condition === self) || - (p instanceof AST_Conditional && p.condition === self) || - (p instanceof AST_DWLoop && p.condition === self) || - (p instanceof AST_For && p.condition === self) || - (p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self)) - { - return true; - } - if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||"))) - return false; - self = p; - } - }, loopcontrol_target: function(node) { var stack = this.stack; if (node.label) for (var i = stack.length; --i >= 0;) { diff --git a/lib/compress.js b/lib/compress.js index 6bdd1599..206c77f3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -145,6 +145,26 @@ merge(Compressor.prototype, { return true; return false; }, + in_boolean_context: function() { + if (!this.option("booleans")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_SimpleStatement + || p instanceof AST_Conditional && p.condition === self + || p instanceof AST_DWLoop && p.condition === self + || p instanceof AST_For && p.condition === self + || p instanceof AST_If && p.condition === self + || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) { + return true; + } + if (p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||") + || p.tail_node() === self) { + self = p; + } else { + return false; + } + } + }, compress: function(node) { if (this.option("expression")) { node.process_expression(true); @@ -1547,7 +1567,7 @@ merge(Compressor.prototype, { || this.alternative._dot_throw(compressor); }) def(AST_Sequence, function(compressor) { - return this.expressions[this.expressions.length - 1]._dot_throw(compressor); + return this.tail_node()._dot_throw(compressor); }); def(AST_SymbolRef, function(compressor) { if (this.is_undefined) return true; @@ -1584,7 +1604,7 @@ merge(Compressor.prototype, { return this.operator == "=" && this.right.is_boolean(); }); def(AST_Sequence, function(){ - return this.expressions[this.expressions.length - 1].is_boolean(); + return this.tail_node().is_boolean(); }); def(AST_True, return_true); def(AST_False, return_true); @@ -1611,7 +1631,7 @@ merge(Compressor.prototype, { || this.operator == "=" && this.right.is_number(compressor); }); def(AST_Sequence, function(compressor){ - return this.expressions[this.expressions.length - 1].is_number(compressor); + return this.tail_node().is_number(compressor); }); def(AST_Conditional, function(compressor){ return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); @@ -1635,7 +1655,7 @@ merge(Compressor.prototype, { return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); }); def(AST_Sequence, function(compressor){ - return this.expressions[this.expressions.length - 1].is_string(compressor); + return this.tail_node().is_string(compressor); }); def(AST_Conditional, function(compressor){ return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); @@ -2974,7 +2994,7 @@ merge(Compressor.prototype, { return make_sequence(this, [ expression, property ]); }); def(AST_Sequence, function(compressor){ - var last = this.expressions[this.expressions.length - 1]; + var last = this.tail_node(); var expr = last.drop_side_effect_free(compressor); if (expr === last) return this; var expressions = this.expressions.slice(0, -1); @@ -3826,7 +3846,7 @@ merge(Compressor.prototype, { return make_node(AST_Undefined, self).optimize(compressor); } } - if (compressor.option("booleans") && compressor.in_boolean_context()) { + if (compressor.in_boolean_context()) { switch (self.operator) { case "!": if (e instanceof AST_UnaryPrefix && e.operator == "!") { @@ -3979,7 +3999,7 @@ merge(Compressor.prototype, { } break; } - if (compressor.option("booleans") && self.operator == "+" && compressor.in_boolean_context()) { + if (self.operator == "+" && compressor.in_boolean_context()) { var ll = self.left.evaluate(compressor); var rr = self.right.evaluate(compressor); if (ll && typeof ll == "string") { @@ -4044,7 +4064,7 @@ merge(Compressor.prototype, { compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); return maintain_this_binding(compressor.parent(), compressor.self(), self.right).optimize(compressor); } - if (compressor.option("booleans") && compressor.in_boolean_context()) { + if (compressor.in_boolean_context()) { var rr = self.right.evaluate(compressor); if (!rr) { compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); @@ -4067,7 +4087,7 @@ merge(Compressor.prototype, { compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); } - if (compressor.option("booleans") && compressor.in_boolean_context()) { + if (compressor.in_boolean_context()) { var rr = self.right.evaluate(compressor); if (!rr) { compressor.warn("Dropping side-effect-free || in boolean context [{file}:{line},{col}]", self.start); @@ -4841,7 +4861,7 @@ merge(Compressor.prototype, { }); function literals_in_boolean_context(self, compressor) { - if (compressor.option("booleans") && compressor.in_boolean_context()) { + if (compressor.in_boolean_context()) { return best_of(compressor, self, make_sequence(self, [ self, make_node(AST_True, self) diff --git a/lib/propmangle.js b/lib/propmangle.js index 36a67e80..c2f27c42 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -84,7 +84,7 @@ function reserve_quoted_keys(ast, reserved) { function addStrings(node, add) { node.walk(new TreeWalker(function(node) { if (node instanceof AST_Sequence) { - addStrings(node.expressions[node.expressions.length - 1], add); + addStrings(node.tail_node(), add); } else if (node instanceof AST_String) { add(node.value); } else if (node instanceof AST_Conditional) { diff --git a/lib/scope.js b/lib/scope.js index f3010e7c..bbfa037c 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -510,6 +510,11 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) { } }); +AST_Node.DEFMETHOD("tail_node", return_this); +AST_Sequence.DEFMETHOD("tail_node", function() { + return this.expressions[this.expressions.length - 1]; +}); + AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ options = this._default_mangler_options(options); try { @@ -538,7 +543,7 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ skip_string(node.consequent); skip_string(node.alternative); } else if (node instanceof AST_Sequence) { - skip_string(node.expressions[node.expressions.length - 1]); + skip_string(node.tail_node()); } } });