From a36c5472d2cf9f79ca5245e9299a011ec7e4cef1 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 24 Jan 2021 03:00:47 +0000 Subject: [PATCH] fix corner cases with default parameters (#4589) fixes #4588 --- lib/compress.js | 46 +++++++++++++-------- test/compress/default-values.js | 71 +++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 19 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 6b8a7ef9..e5ee7406 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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); } } diff --git a/test/compress/default-values.js b/test/compress/default-values.js index 6fc2d3f5..ac89b1ed 100644 --- a/test/compress/default-values.js +++ b/test/compress/default-values.js @@ -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" +} -- 2.34.1