fix corner cases with default parameters (#4589)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 24 Jan 2021 03:00:47 +0000 (03:00 +0000)
committerGitHub <noreply@github.com>
Sun, 24 Jan 2021 03:00:47 +0000 (11:00 +0800)
fixes #4588

lib/compress.js
test/compress/default-values.js

index 6b8a7ef..e5ee740 100644 (file)
@@ -3817,6 +3817,14 @@ merge(Compressor.prototype, {
         return skip_directives(this.body);
     });
 
+    AST_Lambda.DEFMETHOD("length", function() {
+        var argnames = this.argnames;
+        for (var i = 0; i < argnames.length; i++) {
+            if (argnames[i] instanceof AST_DefaultValue) break;
+        }
+        return i;
+    });
+
     function try_evaluate(compressor, node) {
         var ev = node.evaluate(compressor);
         if (ev === node) return node;
@@ -4277,7 +4285,7 @@ merge(Compressor.prototype, {
                   case "name":
                     return val.node.name ? val.node.name.name : "";
                   case "length":
-                    return val.node.argnames.length;
+                    return val.node.length();
                   default:
                     return this;
                 }
@@ -5705,19 +5713,33 @@ merge(Compressor.prototype, {
                     unused_fn_names.push(node);
                 }
                 if (!(node instanceof AST_Accessor)) {
+                    if (node.rest) {
+                        node.rest = node.rest.transform(trimmer);
+                        if (!(node.uses_arguments && !tt.has_directive("use strict"))
+                            && (node.rest instanceof AST_DestructuredArray && node.rest.elements.length == 0
+                                || node.rest instanceof AST_DestructuredObject && node.rest.properties.length == 0)) {
+                            node.rest = null;
+                        }
+                    }
+                    var argnames = node.argnames;
                     var trim = compressor.drop_fargs(node, parent) && !node.rest;
-                    for (var a = node.argnames, i = a.length; --i >= 0;) {
-                        var sym = a[i];
+                    var default_length = trim ? -1 : node.length();
+                    for (var i = argnames.length; --i >= 0;) {
+                        var sym = argnames[i];
                         if (!(sym instanceof AST_SymbolFunarg)) {
                             var arg = sym.transform(trimmer);
                             if (arg) {
                                 trim = false;
                             } else if (trim) {
-                                log(sym.name, "Dropping unused function argument {name}");
-                                a.pop();
-                            } else {
+                                log(sym.name, "Dropping unused default argument {name}");
+                                argnames.pop();
+                            } else if (i > default_length) {
+                                log(sym.name, "Dropping unused default argument assignment {name}");
                                 sym.name.__unused = true;
-                                a[i] = sym.name;
+                                argnames[i] = sym.name;
+                            } else {
+                                log(sym.name, "Dropping unused default argument value {name}");
+                                sym.value = make_node(AST_Number, sym, { value: 0 });
                             }
                             continue;
                         }
@@ -5727,19 +5749,11 @@ merge(Compressor.prototype, {
                             if (indexOf_assign(def, sym) < 0) sym.__unused = null;
                         } else if (trim) {
                             log(sym, "Dropping unused function argument {name}");
-                            a.pop();
+                            argnames.pop();
                         } else {
                             sym.__unused = true;
                         }
                     }
-                    if (node.rest) {
-                        node.rest = node.rest.transform(trimmer);
-                        if (!(node.uses_arguments && !tt.has_directive("use strict"))
-                            && (node.rest instanceof AST_DestructuredArray && node.rest.elements.length == 0
-                                || node.rest instanceof AST_DestructuredObject && node.rest.properties.length == 0)) {
-                            node.rest = null;
-                        }
-                    }
                     fns_with_marked_args.push(node);
                 }
             }
index 6fc2d3f..ac89b1e 100644 (file)
@@ -161,6 +161,7 @@ process_boolean_returns: {
 collapse_value_1: {
     options = {
         collapse_vars: true,
+        keep_fargs: false,
         unused: true,
     }
     input: {
@@ -169,7 +170,7 @@ collapse_value_1: {
         }());
     }
     expect: {
-        console.log(function(a) {
+        console.log(function() {
             return "PASS";
         }());
     }
@@ -180,6 +181,7 @@ collapse_value_1: {
 collapse_value_2: {
     options = {
         collapse_vars: true,
+        keep_fargs: false,
         unused: true,
     }
     input: {
@@ -188,7 +190,7 @@ collapse_value_2: {
         })().log("PASS");
     }
     expect: {
-        (function(a) {
+        (function() {
             return console;
         })().log("PASS");
     }
@@ -554,8 +556,9 @@ drop_fargs: {
         "bar",
     ]
     expect_warnings: [
-        "WARN: Dropping unused function argument c [test/compress/default-values.js:1,61]",
+        "WARN: Dropping unused default argument c [test/compress/default-values.js:1,61]",
         "WARN: Side effects in default value of unused variable b [test/compress/default-values.js:1,37]",
+        "WARN: Dropping unused default argument assignment a [test/compress/default-values.js:1,29]",
     ]
     node_version: ">=6"
 }
@@ -1596,3 +1599,65 @@ issue_4548: {
     ]
     node_version: ">=6"
 }
+
+issue_4588_1_unused: {
+    options = {
+        unused: true,
+    }
+    input: {
+        console.log(function(a = 42) {}.length);
+    }
+    expect: {
+        console.log(function(a = 0) {}.length);
+    }
+    expect_stdout: "0"
+    node_version: ">=6"
+}
+
+issue_4588_2_unused: {
+    options = {
+        unused: true,
+    }
+    input: {
+        console.log(function(a, b = void 0, c, d = "foo") {}.length);
+    }
+    expect: {
+        console.log(function(a, b = 0, c, d) {}.length);
+    }
+    expect_stdout: "1"
+    expect_warnings: [
+        "WARN: Dropping unused default argument assignment d [test/compress/default-values.js:1,47]",
+        "WARN: Dropping unused default argument value b [test/compress/default-values.js:1,32]",
+    ]
+    node_version: ">=6"
+}
+
+issue_4588_1_evaluate: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log(function(a = 42) {}.length);
+    }
+    expect: {
+        console.log(0);
+    }
+    expect_stdout: "0"
+    node_version: ">=6"
+}
+
+issue_4588_2_evaluate: {
+    options = {
+        evaluate: true,
+        unsafe: true,
+    }
+    input: {
+        console.log(function(a, b = void 0, c, d = "foo") {}.length);
+    }
+    expect: {
+        console.log(1);
+    }
+    expect_stdout: "1"
+    node_version: ">=6"
+}