From 5d12abc41b9cb4890b937599fa588a53fdb2996b Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 30 Oct 2020 02:04:23 +0000 Subject: [PATCH] fix corner cases in `collapse_vars` (#4249) fixes #4248 --- lib/compress.js | 33 ++++++++++++++++++++------------- test/compress/collapse_vars.js | 25 +++++++++++++++++++++++++ test/compress/const.js | 31 +++++++++++++++++++++++++++++++ test/compress/let.js | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 13 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 822e0507..0b6ad857 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1556,12 +1556,17 @@ merge(Compressor.prototype, { if (node instanceof AST_Defun) return funarg && lhs.name === node.name.name; if (node instanceof AST_DWLoop) return true; if (node instanceof AST_LoopControl) return true; + if (node instanceof AST_SymbolRef) { + if (node.is_declared(compressor) ? node.fixed_value() || all(node.definition().orig, function(sym) { + return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet); + }) : parent instanceof AST_Assign && parent.operator == "=" && parent.left === node) return false; + if (!replace_all) return true; + scan_rhs = false; + return false; + } if (node instanceof AST_Try) return true; if (node instanceof AST_With) return true; - if (replace_all) return false; - return node instanceof AST_SymbolRef - && !node.is_declared(compressor) - && !(parent instanceof AST_Assign && parent.operator == "=" && parent.left === node); + return false; } function in_conditional(node, parent) { @@ -1710,6 +1715,8 @@ merge(Compressor.prototype, { extract_candidates(expr.condition); extract_candidates(expr.consequent); extract_candidates(expr.alternative); + } else if (expr instanceof AST_Definitions) { + expr.definitions.forEach(extract_candidates); } else if (expr instanceof AST_Dot) { extract_candidates(expr.expression); } else if (expr instanceof AST_DWLoop) { @@ -1763,18 +1770,18 @@ merge(Compressor.prototype, { } else { extract_candidates(expr.expression); } - } else if (expr instanceof AST_Var) { - expr.definitions.forEach(extract_candidates); } else if (expr instanceof AST_VarDef) { - if (expr.value) { - var def = expr.name.definition(); - if (def.references.length > def.replaced) { - candidates.push(hit_stack.slice()); + if (expr.name instanceof AST_SymbolVar) { + if (expr.value) { + var def = expr.name.definition(); + if (def.references.length > def.replaced) { + candidates.push(hit_stack.slice()); + } + } else { + declare_only[expr.name.name] = (declare_only[expr.name.name] || 0) + 1; } - extract_candidates(expr.value); - } else { - declare_only[expr.name.name] = (declare_only[expr.name.name] || 0) + 1; } + if (expr.value) extract_candidates(expr.value); } hit_stack.pop(); } diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index dea01b60..edf4795a 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -8577,3 +8577,28 @@ issue_4242: { } expect_stdout: "undefined" } + +issue_4248: { + options = { + collapse_vars: true, + } + input: { + var a = 0; + try { + a = 1; + b[1]; + } catch (e) { + console.log(a); + } + } + expect: { + var a = 0; + try { + a = 1; + b[1]; + } catch (e) { + console.log(a); + } + } + expect_stdout: "1" +} diff --git a/test/compress/const.js b/test/compress/const.js index 2f88975e..896e8c38 100644 --- a/test/compress/const.js +++ b/test/compress/const.js @@ -1104,3 +1104,34 @@ issue_4245: { } expect_stdout: true } + +issue_4248: { + options = { + collapse_vars: true, + } + input: { + var a = "FAIL"; + try { + (function() { + a = "PASS"; + b[a]; + const b = 0; + })(); + } catch (e) { + console.log(a); + } + } + expect: { + var a = "FAIL"; + try { + (function() { + a = "PASS"; + b[a]; + const b = 0; + })(); + } catch (e) { + console.log(a); + } + } + expect_stdout: "PASS" +} diff --git a/test/compress/let.js b/test/compress/let.js index deb48120..9a6fc944 100644 --- a/test/compress/let.js +++ b/test/compress/let.js @@ -916,3 +916,37 @@ issue_4245: { expect_stdout: ReferenceError("a is not defined") node_version: ">=4" } + +issue_4248: { + options = { + collapse_vars: true, + } + input: { + var a = "FAIL"; + try { + (function() { + "use strict"; + a = "PASS"; + b[a]; + let b; + })(); + } catch (e) { + console.log(a); + } + } + expect: { + var a = "FAIL"; + try { + (function() { + "use strict"; + a = "PASS"; + b[a]; + let b; + })(); + } catch (e) { + console.log(a); + } + } + expect_stdout: "PASS" + node_version: ">=4" +} -- 2.34.1