diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2018-06-28 03:46:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-28 03:46:19 +0800 |
commit | 957d5537a80fcb4037df21f0dbe16391fd0424ad (patch) | |
tree | 5b3611481daad223c62e01dacba0da16a3717f21 /lib | |
parent | 88c8f4e363e0d585b33ea29df560243d3dc74ce1 (diff) | |
download | tracifyjs-957d5537a80fcb4037df21f0dbe16391fd0424ad.tar.gz tracifyjs-957d5537a80fcb4037df21f0dbe16391fd0424ad.zip |
improve `unsafe` `comparisons` (#3200)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 121 |
1 files changed, 90 insertions, 31 deletions
diff --git a/lib/compress.js b/lib/compress.js index 0268e07f..e347169e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2264,29 +2264,35 @@ merge(Compressor.prototype, { // methods to determine whether an expression has a boolean result type (function(def) { - var unary_bool = makePredicate("! delete"); - var binary_bool = makePredicate("in instanceof == != === !== < <= >= >"); def(AST_Node, return_false); - def(AST_UnaryPrefix, function() { - return unary_bool[this.operator]; + def(AST_Assign, function(compressor) { + return this.operator == "=" && this.right.is_boolean(compressor); }); - def(AST_Binary, function() { - return binary_bool[this.operator] - || lazy_op[this.operator] - && this.left.is_boolean() - && this.right.is_boolean(); + var binary = makePredicate("in instanceof == != === !== < <= >= >"); + def(AST_Binary, function(compressor) { + return binary[this.operator] || lazy_op[this.operator] + && this.left.is_boolean(compressor) + && this.right.is_boolean(compressor); }); - def(AST_Conditional, function() { - return this.consequent.is_boolean() && this.alternative.is_boolean(); + def(AST_Boolean, return_true); + var fn = makePredicate("every hasOwnProperty isPrototypeOf propertyIsEnumerable some"); + def(AST_Call, function(compressor) { + if (!compressor.option("unsafe")) return false; + var exp = this.expression; + return exp instanceof AST_Dot && (fn[exp.property] + || exp.property == "test" && exp.expression instanceof AST_RegExp); }); - def(AST_Assign, function() { - return this.operator == "=" && this.right.is_boolean(); + def(AST_Conditional, function(compressor) { + return this.consequent.is_boolean(compressor) && this.alternative.is_boolean(compressor); }); - def(AST_Sequence, function() { - return this.tail_node().is_boolean(); + def(AST_New, return_false); + def(AST_Sequence, function(compressor) { + return this.tail_node().is_boolean(compressor); + }); + var unary = makePredicate("! delete"); + def(AST_UnaryPrefix, function() { + return unary[this.operator]; }); - def(AST_True, return_true); - def(AST_False, return_true); })(function(node, func) { node.DEFMETHOD("is_boolean", func); }); @@ -2294,26 +2300,79 @@ merge(Compressor.prototype, { // methods to determine if an expression has a numeric result type (function(def) { def(AST_Node, return_false); - def(AST_Number, return_true); - var unary = makePredicate("+ - ~ ++ --"); - def(AST_Unary, function() { - return unary[this.operator]; - }); var binary = makePredicate("- * / % & | ^ << >> >>>"); + def(AST_Assign, function(compressor) { + return binary[this.operator.slice(0, -1)] + || this.operator == "=" && this.right.is_number(compressor); + }); def(AST_Binary, function(compressor) { return binary[this.operator] || this.operator == "+" && this.left.is_number(compressor) && this.right.is_number(compressor); }); - def(AST_Assign, function(compressor) { - return binary[this.operator.slice(0, -1)] - || this.operator == "=" && this.right.is_number(compressor); + var fn = makePredicate([ + "charCodeAt", + "getDate", + "getDay", + "getFullYear", + "getHours", + "getMilliseconds", + "getMinutes", + "getMonth", + "getSeconds", + "getTime", + "getTimezoneOffset", + "getUTCDate", + "getUTCDay", + "getUTCFullYear", + "getUTCHours", + "getUTCMilliseconds", + "getUTCMinutes", + "getUTCMonth", + "getUTCSeconds", + "getYear", + "indexOf", + "lastIndexOf", + "localeCompare", + "push", + "search", + "setDate", + "setFullYear", + "setHours", + "setMilliseconds", + "setMinutes", + "setMonth", + "setSeconds", + "setTime", + "setUTCDate", + "setUTCFullYear", + "setUTCHours", + "setUTCMilliseconds", + "setUTCMinutes", + "setUTCMonth", + "setUTCSeconds", + "setYear", + "toExponential", + "toFixed", + "toPrecision", + ]); + def(AST_Call, function(compressor) { + if (!compressor.option("unsafe")) return false; + var exp = this.expression; + return exp instanceof AST_Dot && (fn[exp.property] + || is_undeclared_ref(exp.expression) && exp.expression.name == "Math"); }); + def(AST_Conditional, function(compressor) { + return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); + }); + def(AST_New, return_false); + def(AST_Number, return_true); def(AST_Sequence, function(compressor) { return this.tail_node().is_number(compressor); }); - def(AST_Conditional, function(compressor) { - return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); + var unary = makePredicate("+ - ~ ++ --"); + def(AST_Unary, function() { + return unary[this.operator]; }); })(function(node, func) { node.DEFMETHOD("is_number", func); @@ -2902,7 +2961,7 @@ merge(Compressor.prototype, { var map; if (expr instanceof AST_Array) { map = native_fns.Array; - } else if (expr.is_boolean()) { + } else if (expr.is_boolean(compressor)) { map = native_fns.Boolean; } else if (expr.is_number(compressor)) { map = native_fns.Number; @@ -5247,7 +5306,7 @@ merge(Compressor.prototype, { var is_strict_comparison = true; if ((self.left.is_string(compressor) && self.right.is_string(compressor)) || (self.left.is_number(compressor) && self.right.is_number(compressor)) || - (self.left.is_boolean() && self.right.is_boolean()) || + (self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) || self.left.equivalent_to(self.right)) { self.operator = self.operator.substr(0, 2); } @@ -5328,7 +5387,7 @@ merge(Compressor.prototype, { ]).optimize(compressor); } } - if (compressor.option("comparisons") && self.is_boolean()) { + if (compressor.option("comparisons") && self.is_boolean(compressor)) { if (!(compressor.parent() instanceof AST_Binary) || compressor.parent() instanceof AST_Assign) { var negated = make_node(AST_UnaryPrefix, self, { @@ -6102,7 +6161,7 @@ merge(Compressor.prototype, { return self; function booleanize(node) { - if (node.is_boolean()) return node; + if (node.is_boolean(compressor)) return node; // !!expression return make_node(AST_UnaryPrefix, node, { operator: "!", |