compress self comparisons (#2398)
This commit is contained in:
@@ -581,7 +581,7 @@ merge(Compressor.prototype, {
|
||||
if (!value && props[i].key === key) value = props[i].value;
|
||||
}
|
||||
}
|
||||
return value instanceof AST_SymbolRef ? value.fixed_value() : value;
|
||||
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
||||
}
|
||||
|
||||
function is_modified(node, value, level, immutable) {
|
||||
@@ -3824,6 +3824,11 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
var commutativeOperators = makePredicate("== === != !== * & | ^");
|
||||
function is_object(node) {
|
||||
return node instanceof AST_Array
|
||||
|| node instanceof AST_Lambda
|
||||
|| node instanceof AST_Object;
|
||||
}
|
||||
|
||||
OPT(AST_Binary, function(self, compressor){
|
||||
function reversible() {
|
||||
@@ -3859,7 +3864,8 @@ merge(Compressor.prototype, {
|
||||
case "!==":
|
||||
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() && self.right.is_boolean()) ||
|
||||
self.left.equivalent_to(self.right)) {
|
||||
self.operator = self.operator.substr(0, 2);
|
||||
}
|
||||
// XXX: intentionally falling down to the next case
|
||||
@@ -3879,6 +3885,13 @@ merge(Compressor.prototype, {
|
||||
if (self.operator.length == 2) self.operator += "=";
|
||||
}
|
||||
}
|
||||
// obj !== obj => false
|
||||
else if (self.left instanceof AST_SymbolRef
|
||||
&& self.right instanceof AST_SymbolRef
|
||||
&& self.left.definition() === self.right.definition()
|
||||
&& is_object(self.left.fixed_value())) {
|
||||
return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (compressor.option("booleans") && self.operator == "+" && compressor.in_boolean_context()) {
|
||||
|
||||
@@ -73,4 +73,41 @@ dont_change_in_or_instanceof_expressions: {
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a === a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c !== b.c;
|
||||
}
|
||||
expect: {
|
||||
a == a;
|
||||
a !== b;
|
||||
b.c === a.c;
|
||||
b.c != b.c;
|
||||
}
|
||||
}
|
||||
|
||||
self_comparison_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(f != f, o === o);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var o = {};
|
||||
console.log(false, true);
|
||||
}
|
||||
expect_stdout: "false true"
|
||||
}
|
||||
|
||||
@@ -1195,3 +1195,40 @@ issue_2231_2: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
self_comparison_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { n: NaN };
|
||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
||||
}
|
||||
expect: {
|
||||
console.log(false, false, true, true, "number");
|
||||
}
|
||||
expect_stdout: "false false true true 'number'"
|
||||
}
|
||||
|
||||
self_comparison_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { n: NaN };
|
||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
||||
}
|
||||
expect: {
|
||||
console.log(false, false, true, true, "number");
|
||||
}
|
||||
expect_stdout: "false false true true 'number'"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user