fix corner case in `evaluate` (#4645)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 11 Feb 2021 19:26:12 +0000 (19:26 +0000)
committerGitHub <noreply@github.com>
Thu, 11 Feb 2021 19:26:12 +0000 (03:26 +0800)
fixes #4644

lib/compress.js
test/compress/rests.js

index 1eed09b..38d25b1 100644 (file)
@@ -4368,6 +4368,7 @@ merge(Compressor.prototype, {
                     }
                     return !(sym instanceof AST_Destructured);
                 })) return this;
+                if (fn.rest instanceof AST_Destructured) return this;
                 if (!args && !ignore_side_effects) return this;
                 var stat = fn.first_statement();
                 if (!(stat instanceof AST_Return)) {
@@ -4394,18 +4395,8 @@ merge(Compressor.prototype, {
                 if (!val) return;
                 var cached_args = [];
                 if (!args || all(fn.argnames, function(sym, i) {
-                    if (sym instanceof AST_DefaultValue) sym = sym.name;
-                    var def = sym.definition();
-                    if (def.orig[def.orig.length - 1] !== sym) return false;
-                    var value = args[i];
-                    def.references.forEach(function(node) {
-                        node._eval = function() {
-                            return value;
-                        };
-                        cached_args.push(node);
-                    });
-                    return true;
-                }) || ignore_side_effects) {
+                    return assign(sym, args[i]);
+                }) && !(fn.rest && !assign(fn.rest, args.slice(fn.argnames.length))) || ignore_side_effects) {
                     fn.evaluating = true;
                     val = val._eval(compressor, ignore_side_effects, cached, depth);
                     delete fn.evaluating;
@@ -4450,6 +4441,20 @@ merge(Compressor.prototype, {
                 }
             }
             return this;
+
+            function assign(sym, arg) {
+                if (sym instanceof AST_DefaultValue) sym = sym.name;
+                var def = sym.definition();
+                if (def.orig[def.orig.length - 1] !== sym) return false;
+                var value = arg;
+                def.references.forEach(function(node) {
+                    node._eval = function() {
+                        return value;
+                    };
+                    cached_args.push(node);
+                });
+                return true;
+            }
         });
         def(AST_New, return_this);
         def(AST_Template, function(compressor, ignore_side_effects, cached, depth) {
index 21adf20..59e2945 100644 (file)
@@ -714,3 +714,52 @@ issue_4621: {
     expect_stdout: "PASS"
     node_version: ">=6"
 }
+
+issue_4644_1: {
+    options = {
+        evaluate: true,
+    }
+    input: {
+        var a = "FAIL";
+        (function f(b, ...{
+            [a = "PASS"]: c,
+        }) {
+            return b;
+        })();
+        console.log(a);
+    }
+    expect: {
+        var a = "FAIL";
+        (function f(b, ...{
+            [a = "PASS"]: c,
+        }) {
+            return b;
+        })();
+        console.log(a);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}
+
+issue_4644_2: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log(function(...a) {
+            return a[1];
+        }("FAIL", "PASS"), function(...b) {
+            return b.length;
+        }(), function(c, ...d) {
+            return d[0];
+        }("FAIL"));
+    }
+    expect: {
+        console.log("PASS", 0, function(c, ...d) {
+            return d[0];
+        }("FAIL"));
+    }
+    expect_stdout: "PASS 0 undefined"
+    node_version: ">=6"
+}