enhance side_effects (#4175)

This commit is contained in:
Alex Lam S.L
2020-10-04 16:43:49 +01:00
committed by GitHub
parent 1786c69070
commit 66140b459e
5 changed files with 80 additions and 39 deletions

View File

@@ -2911,6 +2911,9 @@ merge(Compressor.prototype, {
this._dot_throw = return_false;
return false;
});
def(AST_This, function(compressor) {
return is_strict(compressor) && !this.scope.new;
});
def(AST_UnaryPrefix, function() {
return this.operator == "void";
});
@@ -3944,7 +3947,15 @@ merge(Compressor.prototype, {
def(AST_Array, function(compressor) {
return any(this.elements, compressor);
});
def(AST_Assign, return_true);
def(AST_Assign, function(compressor) {
var lhs = this.left;
if (!(lhs instanceof AST_PropAccess)) return true;
var node = lhs.expression;
return !(node instanceof AST_This)
|| !node.scope.new
|| lhs instanceof AST_Sub && lhs.property.has_side_effects(compressor)
|| this.right.has_side_effects(compressor);
});
def(AST_Binary, function(compressor) {
return this.left.has_side_effects(compressor)
|| this.right.has_side_effects(compressor)
@@ -5627,36 +5638,53 @@ merge(Compressor.prototype, {
}
});
def(AST_Call, function(compressor, first_in_statement) {
if (!this.is_expr_pure(compressor)) {
var exp = this.expression;
if (this.is_call_pure(compressor)) {
var exprs = this.args.slice();
exprs.unshift(exp.expression);
exprs = trim(exprs, compressor, first_in_statement);
return exprs && make_sequence(this, exprs);
}
if (exp instanceof AST_Function) {
if (exp.name) {
var def = exp.name.definition();
if (def.references.length > def.replaced) return this;
}
exp.process_expression(false, function(node) {
var value = node.value && node.value.drop_side_effect_free(compressor, true);
return value ? make_node(AST_SimpleStatement, node, {
body: value
}) : make_node(AST_EmptyStatement, node);
});
scan_local_returns(exp, function(node) {
if (node.value) node.value = node.value.drop_side_effect_free(compressor);
});
// always shallow clone to ensure stripping of negated IIFEs
return this.clone();
}
return this;
var self = this;
if (self.is_expr_pure(compressor)) {
if (self.pure) AST_Node.warn("Dropping __PURE__ call [{file}:{line},{col}]", self.start);
var args = trim(self.args, compressor, first_in_statement);
return args && make_sequence(self, args);
}
if (this.pure) AST_Node.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
var args = trim(this.args, compressor, first_in_statement);
return args && make_sequence(this, args);
var exp = self.expression;
if (self.is_call_pure(compressor)) {
var exprs = self.args.slice();
exprs.unshift(exp.expression);
exprs = trim(exprs, compressor, first_in_statement);
return exprs && make_sequence(self, exprs);
}
var def;
if (exp instanceof AST_Function
&& !(exp.name && (def = exp.name.definition()).references.length > def.replaced)) {
exp.process_expression(false, function(node) {
var value = node.value && node.value.drop_side_effect_free(compressor, true);
return value ? make_node(AST_SimpleStatement, node, {
body: value
}) : make_node(AST_EmptyStatement, node);
});
scan_local_returns(exp, function(node) {
if (node.value) node.value = node.value.drop_side_effect_free(compressor);
});
// always shallow clone to ensure stripping of negated IIFEs
self = self.clone();
}
if (self instanceof AST_New) {
var fn = exp;
if (fn instanceof AST_SymbolRef) fn = fn.fixed_value();
if (fn instanceof AST_Lambda) {
fn.new = true;
var assign_this_only = all(fn.body, function(stat) {
return !stat.has_side_effects(compressor);
});
delete fn.new;
if (assign_this_only) {
var exprs = self.args.slice();
exprs.unshift(exp);
exprs = trim(exprs, compressor, first_in_statement);
return exprs && make_sequence(self, exprs);
}
if (!fn.contains_this()) return make_node(AST_Call, self, self);
}
}
return self;
});
def(AST_Conditional, function(compressor) {
var consequent = this.consequent.drop_side_effect_free(compressor);