aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js61
1 files changed, 38 insertions, 23 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 1b22d861..99e67b91 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4797,9 +4797,15 @@ merge(Compressor.prototype, {
|| this.right.has_side_effects(compressor);
});
def(AST_Binary, function(compressor) {
- return this.left.has_side_effects(compressor)
- || this.right.has_side_effects(compressor)
- || this.operator == "in" && !is_object(this.right);
+ var lhs = this.left;
+ if (lhs.has_side_effects(compressor)) return true;
+ var rhs = this.right;
+ var op = this.operator;
+ if (!rhs.has_side_effects(compressor)) return op == "in" && !is_object(rhs);
+ if (op == "&&" && rhs instanceof AST_PropAccess && lhs.equivalent_to(rhs.expression)) {
+ return rhs instanceof AST_Sub && rhs.property.has_side_effects(compressor);
+ }
+ return true;
});
def(AST_Block, function(compressor) {
return any(this.body, compressor);
@@ -7208,33 +7214,42 @@ merge(Compressor.prototype, {
return node;
});
def(AST_Binary, function(compressor, first_in_statement) {
- if (this.operator == "in" && !is_object(this.right)) {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (left === this.left) return this;
+ var left = this.left;
+ var right = this.right;
+ var op = this.operator;
+ if (op == "in" && !is_object(right)) {
+ var lhs = left.drop_side_effect_free(compressor, first_in_statement);
+ if (lhs === left) return this;
var node = this.clone();
- node.left = left || make_node(AST_Number, this.left, {
- value: 0
- });
+ node.left = lhs || make_node(AST_Number, left, { value: 0 });
return node;
}
- var right = this.right.drop_side_effect_free(compressor, first_in_statement);
- if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
- if (lazy_op[this.operator] && !(right instanceof AST_Function)) {
+ var rhs = right.drop_side_effect_free(compressor, first_in_statement);
+ if (!rhs) return left.drop_side_effect_free(compressor, first_in_statement);
+ if (lazy_op[op] && !(rhs instanceof AST_Function)) {
var node = this;
- if (right !== node.right) {
- node = this.clone();
- node.right = right.drop_side_effect_free(compressor);
- }
- if (this.operator == "??") return node;
+ if (op == "&&"
+ && rhs instanceof AST_PropAccess
+ && left.equivalent_to(rhs.expression)
+ && !left.has_side_effects(compressor)) {
+ var prop = rhs instanceof AST_Sub && rhs.property.drop_side_effect_free(compressor);
+ if (!prop) return left.drop_side_effect_free(compressor, first_in_statement);
+ node = node.clone();
+ node.right = prop;
+ } else if (rhs !== right) {
+ node = node.clone();
+ node.right = rhs.drop_side_effect_free(compressor);
+ }
+ if (op == "??") return node;
return (first_in_statement ? best_of_statement : best_of_expression)(node, make_node(AST_Binary, this, {
- operator: node.operator == "&&" ? "||" : "&&",
- left: node.left.negate(compressor, first_in_statement),
- right: node.right
+ operator: op == "&&" ? "||" : "&&",
+ left: left.negate(compressor, first_in_statement),
+ right: node.right,
}));
} else {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (!left) return right;
- return make_sequence(this, [ left, right.drop_side_effect_free(compressor) ]);
+ var lhs = left.drop_side_effect_free(compressor, first_in_statement);
+ if (!lhs) return rhs;
+ return make_sequence(this, [ lhs, rhs.drop_side_effect_free(compressor) ]);
}
});
def(AST_Call, function(compressor, first_in_statement) {