aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-06-28 03:46:19 +0800
committerGitHub <noreply@github.com>2018-06-28 03:46:19 +0800
commit957d5537a80fcb4037df21f0dbe16391fd0424ad (patch)
tree5b3611481daad223c62e01dacba0da16a3717f21 /lib
parent88c8f4e363e0d585b33ea29df560243d3dc74ce1 (diff)
downloadtracifyjs-957d5537a80fcb4037df21f0dbe16391fd0424ad.tar.gz
tracifyjs-957d5537a80fcb4037df21f0dbe16391fd0424ad.zip
improve `unsafe` `comparisons` (#3200)
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js121
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: "!",