fix corner case in `side_effects` (#5118)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 23 Aug 2021 00:51:59 +0000 (01:51 +0100)
committerGitHub <noreply@github.com>
Mon, 23 Aug 2021 00:51:59 +0000 (08:51 +0800)
lib/compress.js
test/compress/default-values.js
test/compress/rests.js

index 274a839..fa1e121 100644 (file)
@@ -1539,7 +1539,7 @@ merge(Compressor.prototype, {
     AST_Node.DEFMETHOD("match_symbol", function(predicate) {
         return predicate(this);
     });
-    AST_Destructured.DEFMETHOD("match_symbol", function(predicate, ignore_side_effects) {
+    function match_destructured(predicate, ignore_side_effects) {
         var found = false;
         var tw = new TreeWalker(function(node) {
             if (found) return true;
@@ -1557,7 +1557,9 @@ merge(Compressor.prototype, {
         });
         this.walk(tw);
         return found;
-    });
+    }
+    AST_DefaultValue.DEFMETHOD("match_symbol", match_destructured);
+    AST_Destructured.DEFMETHOD("match_symbol", match_destructured);
 
     function in_async_generator(scope) {
         return scope instanceof AST_AsyncGeneratorDefun || scope instanceof AST_AsyncGeneratorFunction;
@@ -7924,12 +7926,7 @@ merge(Compressor.prototype, {
                 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) {
+                    if (assign_this_only(fn, compressor)) {
                         var exprs = self.args.slice();
                         exprs.unshift(exp);
                         exprs = trim(exprs, compressor, first_in_statement, array_spread);
@@ -7941,6 +7938,16 @@ merge(Compressor.prototype, {
             self.call_only = true;
             return self;
         });
+        function assign_this_only(fn, compressor) {
+            fn.new = true;
+            var result = all(fn.body, function(stat) {
+                return !stat.has_side_effects(compressor);
+            }) && all(fn.argnames, function(argname) {
+                return !argname.match_symbol(return_false);
+            }) && !(fn.rest && fn.rest.match_symbol(return_false));
+            delete fn.new;
+            return result;
+        }
         function drop_class(self, compressor, first_in_statement) {
             var exprs = [], values = [];
             var props = self.properties;
index 28cc46f..13d4a18 100644 (file)
@@ -568,6 +568,20 @@ retain_empty_iife: {
     node_version: ">=6"
 }
 
+drop_new_function: {
+    options = {
+        side_effects: true,
+    }
+    input: {
+        new function(a = console.log("PASS")) {}();
+    }
+    expect: {
+        void console.log("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}
+
 retain_fargs: {
     options = {
         unused: true,
index a62e380..24c6f87 100644 (file)
@@ -636,6 +636,24 @@ keep_rest_lambda_2: {
     node_version: ">=6"
 }
 
+drop_new_function: {
+    options = {
+        side_effects: true,
+    }
+    input: {
+        new function(...{
+            [console.log("PASS")]: a,
+        }) {}();
+    }
+    expect: {
+        void ([ ... {
+            [console.log("PASS")]: [].e,
+        }] = []);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}
+
 issue_4525_1: {
     options = {
         arguments: true,