fix corner cases in `reduce_vars` (#4561)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 16 Jan 2021 08:55:10 +0000 (08:55 +0000)
committerGitHub <noreply@github.com>
Sat, 16 Jan 2021 08:55:10 +0000 (16:55 +0800)
fixes #4560

lib/compress.js
test/compress/spreads.js

index 86ce938..6bbae0f 100644 (file)
@@ -618,7 +618,7 @@ merge(Compressor.prototype, {
                     node.value.walk(tw);
                     pop(tw);
                     var save = fixed;
-                    fixed = function() {
+                    if (save) fixed = function() {
                         var value = save();
                         return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node.name;
                     };
@@ -631,7 +631,7 @@ merge(Compressor.prototype, {
                     var save = fixed;
                     node.elements.forEach(function(node, index) {
                         if (node instanceof AST_Hole) return reset_flags(node);
-                        fixed = function() {
+                        if (save) fixed = function() {
                             return make_node(AST_Sub, node, {
                                 expression: save(),
                                 property: make_node(AST_Number, node, {
@@ -642,7 +642,7 @@ merge(Compressor.prototype, {
                         node.walk(scanner);
                     });
                     if (node.rest) {
-                        fixed = compressor.option("rests") && function() {
+                        if (save) fixed = compressor.option("rests") && function() {
                             var value = save();
                             return value instanceof AST_Array ? make_node(AST_Array, node, {
                                 elements: value.elements.slice(node.elements.length),
@@ -663,7 +663,7 @@ merge(Compressor.prototype, {
                             node.key.walk(tw);
                             pop(tw);
                         }
-                        fixed = function() {
+                        if (save) fixed = function() {
                             var key = node.key;
                             var type = AST_Sub;
                             if (typeof key == "string") {
@@ -736,25 +736,31 @@ merge(Compressor.prototype, {
                 scan_declaration(tw, compressor, arg, function() {
                     var j = fn.argnames.indexOf(arg);
                     return (j < 0 ? value : iife.args[j]) || make_node(AST_Undefined, iife);
-                }, function(node, fixed) {
-                    var d = node.definition();
-                    if (fixed && safe && d.fixed === undefined) {
-                        mark(tw, d);
-                        tw.loop_ids[d.id] = tw.in_loop;
-                        var value = iife.args[i];
-                        d.fixed = fixed;
-                        d.fixed.assigns = [ arg ];
-                    } else {
-                        d.fixed = false;
-                    }
-                });
+                }, visit);
             });
+            if (fn.rest) scan_declaration(tw, compressor, fn.rest, compressor.option("rests") && function() {
+                return make_node(AST_Array, fn, {
+                    elements: iife.args.slice(fn.argnames.length),
+                });
+            }, visit);
             walk_lambda(fn, tw);
             var safe_ids = tw.safe_ids;
             pop(tw);
             walk_defuns(tw, fn);
             if (!aborts) tw.safe_ids = safe_ids;
             return true;
+
+            function visit(node, fixed) {
+                var d = node.definition();
+                if (fixed && safe && d.fixed === undefined) {
+                    mark(tw, d);
+                    tw.loop_ids[d.id] = tw.in_loop;
+                    d.fixed = fixed;
+                    d.fixed.assigns = [ node ];
+                } else {
+                    d.fixed = false;
+                }
+            }
         }
 
         def(AST_Assign, function(tw, descend, compressor) {
index 7c98fdc..7eac248 100644 (file)
@@ -846,3 +846,75 @@ issue_4556: {
     expect_stdout: "undefined"
     node_version: ">=6"
 }
+
+issue_4560_1: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        toplevel: true,
+    }
+    input: {
+        var a = 0;
+        (function(...{
+            [a++]: {},
+        }) {})(2);
+        console.log(a);
+    }
+    expect: {
+        var a = 0;
+        (function(...{
+            [a++]: {},
+        }) {})(2);
+        console.log(a);
+    }
+    expect_stdout: "1"
+    node_version: ">=6"
+}
+
+issue_4560_2: {
+    options = {
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a = 0;
+        (function(...{
+            [a++]: {},
+        }) {})(2);
+        console.log(a);
+    }
+    expect: {
+        var a = 0;
+        (function(...{
+            [a++]: {},
+        }) {})(2);
+        console.log(a);
+    }
+    expect_stdout: "1"
+    node_version: ">=6"
+}
+
+issue_4560_3: {
+    options = {
+        collapse_vars: true,
+        reduce_vars: true,
+        toplevel: true,
+    }
+    input: {
+        var a = 0, b;
+        [ ...{
+            [a++]: b,
+        } ] = [ "PASS" ];
+        console.log(b);
+    }
+    expect: {
+        var a = 0, b;
+        [ ...{
+            [a++]: b,
+        } ] = [ "PASS" ];
+        console.log(b);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}