From 4c227cc6bd795278c085a6b6dfd40a960ec35698 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Thu, 30 Jun 2022 08:34:45 +0100 Subject: [PATCH] fix corner cases in `inline` & `unused` (#5534) fixes #5533 --- lib/compress.js | 20 +- test/compress/default-values.js | 344 ++++++++++++++++++++++++++++++++ test/compress/destructured.js | 84 ++++++++ test/compress/drop-unused.js | 82 ++++++++ test/compress/rests.js | 168 ++++++++++++++++ test/reduce.js | 4 +- test/ufuzz/index.js | 4 +- 7 files changed, 694 insertions(+), 12 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 76491e14..29914940 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -6948,7 +6948,7 @@ Compressor.prototype.compress = function(node) { node.properties = properties; return node; } - if (node instanceof AST_SymbolDeclaration) return node.definition().id in in_use_ids ? node : null; + if (node instanceof AST_SymbolDeclaration) return trim_decl(node); }); var tt = new TreeTransformer(function(node, descend, in_list) { var parent = tt.parent(); @@ -7063,9 +7063,7 @@ Compressor.prototype.compress = function(node) { } else { var trimmed = trim_destructured(rest, make_node(AST_Array, parent, { elements: args.slice(argnames.length), - }), function(node) { - return node.definition().id in in_use_ids ? node : null; - }, !node.uses_arguments, rest); + }), trim_decl, !node.uses_arguments, rest); rest = trimmed.name; args.length = argnames.length; if (trimmed.value.elements.length) [].push.apply(args, trimmed.value.elements); @@ -7095,6 +7093,8 @@ Compressor.prototype.compress = function(node) { } else if (trim) { log(sym, "Dropping unused function argument {name}"); argnames.pop(); + def.eliminated++; + sym.unused = true; } else { sym.unused = true; } @@ -7104,9 +7104,7 @@ Compressor.prototype.compress = function(node) { if (!args || spread < i) { funarg = sym.transform(trimmer); } else { - var trimmed = trim_destructured(sym, args[i], function(node) { - return node.definition().id in in_use_ids ? node : null; - }, trim_value, sym); + var trimmed = trim_destructured(sym, args[i], trim_decl, trim_value, sym); funarg = trimmed.name; if (trimmed.value) args[i] = trimmed.value; } @@ -7706,6 +7704,12 @@ Compressor.prototype.compress = function(node) { return (node instanceof AST_DefaultValue ? node.name : node) instanceof AST_SymbolDeclaration; } + function trim_decl(node) { + if (node.definition().id in in_use_ids) return node; + if (node instanceof AST_SymbolFunarg) node.unused = true; + return null; + } + function trim_default(trimmer, node) { node.value = node.value.transform(tt); var name = node.name.transform(trimmer); @@ -13660,7 +13664,7 @@ Compressor.prototype.compress = function(node) { if (def.orig.length == 1 && fn.functions.has(name)) return; if (!all(def.orig, function(sym) { if (sym instanceof AST_SymbolConst) return false; - if (sym instanceof AST_SymbolFunarg) return def.scope.resolve() !== fn; + if (sym instanceof AST_SymbolFunarg) return !sym.unused && def.scope.resolve() !== fn; if (sym instanceof AST_SymbolLet) return false; return true; })) return; diff --git a/test/compress/default-values.js b/test/compress/default-values.js index 5e24120b..5f149d45 100644 --- a/test/compress/default-values.js +++ b/test/compress/default-values.js @@ -2463,3 +2463,347 @@ issue_5485: { expect_stdout: "PASS" node_version: ">=6" } + +issue_5533_1_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_1_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_2_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f([ b ] = []) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) { + var [ [] = [] ] = []; + throw "PASS"; + } + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_2_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f([ b ] = []) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) { + var [ [] = [] ] = []; + throw "PASS"; + } + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_3_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42, c = null) { + c; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_3_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42, c = null) { + c; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_4_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42, [ c ] = []) { + c; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) { + var [ [] = [] ] = []; + throw "PASS"; + } + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_4_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b = 42, [ c ] = []) { + c; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) { + var [ [] = [] ] = []; + throw "PASS"; + } + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} diff --git a/test/compress/destructured.js b/test/compress/destructured.js index 60b0b69d..9b49da34 100644 --- a/test/compress/destructured.js +++ b/test/compress/destructured.js @@ -3646,3 +3646,87 @@ issue_5485: { expect_stdout: "PASS" node_version: ">=6" } + +issue_5533_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f([ b ]) { + b; + throw "PASS"; + })([]); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f([ b ]) { + b; + throw "PASS"; + })([]); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 21e5c4d6..d34b2bd9 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -3685,3 +3685,85 @@ issue_5271: { } expect_stdout: "42" } + +issue_5533_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" +} + +issue_5533_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(b) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" +} diff --git a/test/compress/rests.js b/test/compress/rests.js index 056d8c8a..752b81c4 100644 --- a/test/compress/rests.js +++ b/test/compress/rests.js @@ -1363,3 +1363,171 @@ issue_5391: { expect_stdout: "NaN" node_version: ">=8.3.0" } + +issue_5533_1_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(...b) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_1_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(...b) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_2_keep_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: true, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(...[ b ]) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5533_2_drop_fargs: { + options = { + evaluate: true, + inline: true, + join_vars: true, + keep_fargs: false, + loops: true, + side_effects: true, + unused: true, + } + input: { + "use strict"; + try { + (function() { + var a; + for (; 1;) + a = function() { + (function f(...[ b ]) { + b; + throw "PASS"; + })(); + }(); + })(); + } catch (e) { + console.log(e); + } + } + expect: { + "use strict"; + try { + (function() { + for (;;) + throw "PASS"; + })(); + } catch (e) { + console.log(e); + } + } + expect_stdout: "PASS" + node_version: ">=6" +} diff --git a/test/reduce.js b/test/reduce.js index ffb1c2f5..71cdb2a6 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -778,9 +778,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) { function run(code, timeout) { if (minify_options.module) code = [ '"use strict";', - "(async ()=>{", + "(async()=>{", code, - "})().catch(e=>console.log(e));", + '})().catch(e=>process.on("exit",()=>{throw e}));', ].join("\n"); return run_code(code, toplevel, result_cache, timeout); } diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index 415ed45b..162209ef 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -2104,9 +2104,9 @@ if (require.main !== module) { function run_code(code, toplevel, timeout) { if (async && has_await) code = [ '"use strict";', - "(async ()=>{", + "(async()=>{", code, - "})().catch(e=>console.log(e));", + '})().catch(e=>process.on("exit",()=>{throw e}));', ].join("\n"); return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout); }