enhance side_effects (#4175)
This commit is contained in:
@@ -2911,6 +2911,9 @@ merge(Compressor.prototype, {
|
|||||||
this._dot_throw = return_false;
|
this._dot_throw = return_false;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
def(AST_This, function(compressor) {
|
||||||
|
return is_strict(compressor) && !this.scope.new;
|
||||||
|
});
|
||||||
def(AST_UnaryPrefix, function() {
|
def(AST_UnaryPrefix, function() {
|
||||||
return this.operator == "void";
|
return this.operator == "void";
|
||||||
});
|
});
|
||||||
@@ -3944,7 +3947,15 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Array, function(compressor) {
|
def(AST_Array, function(compressor) {
|
||||||
return any(this.elements, 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) {
|
def(AST_Binary, function(compressor) {
|
||||||
return this.left.has_side_effects(compressor)
|
return this.left.has_side_effects(compressor)
|
||||||
|| this.right.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) {
|
def(AST_Call, function(compressor, first_in_statement) {
|
||||||
if (!this.is_expr_pure(compressor)) {
|
var self = this;
|
||||||
var exp = this.expression;
|
if (self.is_expr_pure(compressor)) {
|
||||||
if (this.is_call_pure(compressor)) {
|
if (self.pure) AST_Node.warn("Dropping __PURE__ call [{file}:{line},{col}]", self.start);
|
||||||
var exprs = this.args.slice();
|
var args = trim(self.args, compressor, first_in_statement);
|
||||||
exprs.unshift(exp.expression);
|
return args && make_sequence(self, args);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
if (this.pure) AST_Node.warn("Dropping __PURE__ call [{file}:{line},{col}]", this.start);
|
var exp = self.expression;
|
||||||
var args = trim(this.args, compressor, first_in_statement);
|
if (self.is_call_pure(compressor)) {
|
||||||
return args && make_sequence(this, args);
|
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) {
|
def(AST_Conditional, function(compressor) {
|
||||||
var consequent = this.consequent.drop_side_effect_free(compressor);
|
var consequent = this.consequent.drop_side_effect_free(compressor);
|
||||||
|
|||||||
@@ -1123,11 +1123,7 @@ new_this: {
|
|||||||
}
|
}
|
||||||
}.f(42);
|
}.f(42);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {}
|
||||||
new function(a) {
|
|
||||||
this.a = a;
|
|
||||||
}(42);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2513: {
|
issue_2513: {
|
||||||
|
|||||||
@@ -416,3 +416,20 @@ issue_4008: {
|
|||||||
"PASS",
|
"PASS",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trim_new: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(a) {
|
||||||
|
console.log(a);
|
||||||
|
}("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
new function(){console.log(3)};
|
console.log(3);
|
||||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSJ9
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
new function(){console.log(3)};
|
console.log(3);
|
||||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSJ9
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||||
|
|||||||
Reference in New Issue
Block a user