From 66140b459e65e0540e567966f8dbefdbc2016f9e Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 4 Oct 2020 16:43:49 +0100 Subject: [PATCH] enhance `side_effects` (#4175) --- lib/compress.js | 84 ++++++++++++++++++++++----------- test/compress/properties.js | 6 +-- test/compress/side_effects.js | 17 +++++++ test/input/issue-3294/output.js | 4 +- test/input/issue-520/output.js | 4 +- 5 files changed, 78 insertions(+), 37 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); diff --git a/test/compress/properties.js b/test/compress/properties.js index 169dcd11..43f08b42 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -1123,11 +1123,7 @@ new_this: { } }.f(42); } - expect: { - new function(a) { - this.a = a; - }(42); - } + expect: {} } issue_2513: { diff --git a/test/compress/side_effects.js b/test/compress/side_effects.js index 0746a56d..3c53dd25 100644 --- a/test/compress/side_effects.js +++ b/test/compress/side_effects.js @@ -416,3 +416,20 @@ issue_4008: { "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" +} diff --git a/test/input/issue-3294/output.js b/test/input/issue-3294/output.js index 33efadb6..2e847e1b 100644 --- a/test/input/issue-3294/output.js +++ b/test/input/issue-3294/output.js @@ -1,2 +1,2 @@ -new function(){console.log(3)}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSJ9 +console.log(3); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9 diff --git a/test/input/issue-520/output.js b/test/input/issue-520/output.js index 33efadb6..2e847e1b 100644 --- a/test/input/issue-520/output.js +++ b/test/input/issue-520/output.js @@ -1,2 +1,2 @@ -new function(){console.log(3)}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSJ9 +console.log(3); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9 -- 2.34.1