aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-10-04 16:43:49 +0100
committerGitHub <noreply@github.com>2020-10-04 23:43:49 +0800
commit66140b459e65e0540e567966f8dbefdbc2016f9e (patch)
treeb1a5911f86bf4887e38bc425a4d43165de13d722 /lib/compress.js
parent1786c6907070ee984d36548ab9941f36c524237e (diff)
downloadtracifyjs-66140b459e65e0540e567966f8dbefdbc2016f9e.tar.gz
tracifyjs-66140b459e65e0540e567966f8dbefdbc2016f9e.zip
enhance `side_effects` (#4175)
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js84
1 files changed, 56 insertions, 28 deletions
diff --git a/lib/compress.js b/lib/compress.js
index a7e5eaca..30757c44 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -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);
+ 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);
+ }
+ 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);
});
- // always shallow clone to ensure stripping of negated IIFEs
- return this.clone();
+ 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 this;
}
- 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);
+ return self;
});
def(AST_Conditional, function(compressor) {
var consequent = this.consequent.drop_side_effect_free(compressor);