From dac9e69f9efb491c274670f36301fd38b0ef4dd6 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 18 Apr 2020 03:06:20 +0100 Subject: [PATCH] enhance `collapse_vars` (#3793) --- lib/compress.js | 15 ++-- test/compress/collapse_vars.js | 127 +++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 11 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 70ac9b8f..d07c2412 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1307,12 +1307,10 @@ merge(Compressor.prototype, { if (candidate instanceof AST_Assign) referenced--; if (replaced && referenced == replaced) { abort = false; - } else if (candidate instanceof AST_Assign) { + } else { candidates.push(hit_stack); force_single = true; continue; - } else { - replaced = false; } if (replaced) { hit_index = 0; @@ -1320,6 +1318,9 @@ merge(Compressor.prototype, { for (var i = stat_index; !abort && i < statements.length; i++) { if (!statements[i].transform(multi_replacer)) statements.splice(i--, 1); } + if (candidate instanceof AST_VarDef) { + replaced = !compressor.exposed(def) && def.references.length == def.replaced; + } value_def.single_use = false; } } @@ -1738,8 +1739,11 @@ merge(Compressor.prototype, { if (!member(expr.name, def.orig)) return; var referenced = def.references.length - def.replaced; var declared = def.orig.length - def.eliminated; - if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg) - || (referenced > 1 ? mangleable_var(expr.value) : !compressor.exposed(def))) { + if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)) { + mangleable_var(expr.value); + return make_node(AST_SymbolRef, expr.name, expr.name); + } + if (referenced > 1 ? mangleable_var(expr.value) : !compressor.exposed(def)) { return make_node(AST_SymbolRef, expr.name, expr.name); } } else if (expr instanceof AST_Assign) { @@ -1863,6 +1867,7 @@ merge(Compressor.prototype, { found = true; if (node instanceof AST_VarDef) { node.value = null; + if (value_def) value_def.replaced++; return node; } return in_list ? List.skip : null; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index fd421a20..1c3af6fa 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -2205,8 +2205,8 @@ var_defs: { } expect: { var f1 = function(x, y) { - var r = x + y, a = r * r - r, b = 7; - console.log(a + b); + var r = x + y, z = r * r - r, b = 7; + console.log(z + b); }; f1("1", 0); } @@ -2700,8 +2700,8 @@ toplevel_single_reference: { } expect: { for (var b in x) { - var a; - b(a = b); + var a = b; + b(b); } } } @@ -4244,8 +4244,7 @@ issue_2497: { if (true) for (var i = 0; i < 1; ++i) for (var k = 0; k < 1; ++k) { - value = 1; - value = value ? value + 1 : 0; + value = (value = 1) ? value + 1 : 0; } else for (i = 0; i < 1; ++i) @@ -7807,3 +7806,119 @@ issue_3744: { } expect_stdout: "PASS" } + +assign_value_def: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(a) { + while (1) { + var b = a[0], c = a[1]; + d = b; + e = c; + if (c[0] - e[0] > c[1] - d[1]) break; + return "PASS"; + } + var d, e; + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect: { + function f(a) { + while (1) { + var b = a[0], c = a[1]; + if (c[0] - c[0] > c[1] - b[1]) break; + return "PASS"; + } + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect_stdout: "PASS" +} + +join_vars_value_def: { + options = { + collapse_vars: true, + join_vars: true, + unused: true, + } + input: { + function f(a) { + while (1) { + var b = a[0], c = a[1]; + d = b; + e = c; + if (c[0] - e[0] > c[1] - d[1]) break; + return "PASS"; + } + var d, e; + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect: { + function f(a) { + while (1) { + var b = a[0], c = a[1]; + if (c[0] - c[0] > c[1] - b[1]) break; + return "PASS"; + } + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect_stdout: "PASS" +} + +var_value_def: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(a) { + while (1) { + var b = a[0], c = a[1], d = b, e = c; + if (c[0] - e[0] > c[1] - d[1]) break; + return "PASS"; + } + var d, e; + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect: { + function f(a) { + while (1) { + var b = a[0], c = a[1]; + if (c[0] - c[0] > c[1] - b[1]) break; + return "PASS"; + } + return "FAIL"; + } + console.log(f([ + [ 1, 2 ], + [ 3, 4 ], + ])); + } + expect_stdout: "PASS" +} -- 2.34.1