From 12a6728c4ea72d9caebafc73ff552552ba6f1b54 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 6 Mar 2022 09:56:00 +0000 Subject: [PATCH] fix corner case in `hoist_vars` (#5379) fixes #5378 --- lib/compress.js | 47 +++++++++++++++++++------------------ test/compress/hoist_vars.js | 31 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 1889db0c..80ace965 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -7844,15 +7844,15 @@ Compressor.prototype.compress = function(node) { && !consts.has(sym.name) && self.find_variable(sym.name) === sym.definition(); })) return node; - node.definitions.forEach(function(def) { - vars.set(def.name.name, def); + node.definitions.forEach(function(defn) { + vars.set(defn.name.name, defn); ++vars_found; }); var seq = node.to_assignments(); if (p instanceof AST_ForEnumeration && p.init === node) { if (seq) return seq; - var def = node.definitions[0].name; - return make_node(AST_SymbolRef, def, def); + var sym = node.definitions[0].name; + return make_node(AST_SymbolRef, sym, sym); } if (p instanceof AST_For && p.init === node) return seq; if (!seq) return in_list ? List.skip : make_node(AST_EmptyStatement, node); @@ -7867,21 +7867,22 @@ Compressor.prototype.compress = function(node) { self.transform(tt); if (vars_found > 0) { // collect only vars which don't show up in self's arguments list - var defs = []; + var defns = []; if (self instanceof AST_Lambda) self.each_argname(function(argname) { vars.del(argname.name); }); - vars.each(function(def, name) { - def = def.clone(); - def.value = null; - defs.push(def); - vars.set(name, def); + vars.each(function(defn, name) { + defn = defn.clone(); + defn.name = defn.name.clone(); + defn.value = null; + defns.push(defn); + vars.set(name, defn); + defn.name.definition().orig.unshift(defn.name); }); - if (defs.length > 0) { + if (defns.length > 0) { // try to merge in assignments insert_vars(self.body); - defs = make_node(AST_Var, self, { definitions: defs }); - hoisted.push(defs); + hoisted.push(make_node(AST_Var, self, { definitions: defns })); } } self.body = dirs.concat(hoisted, self.body); @@ -7895,13 +7896,13 @@ Compressor.prototype.compress = function(node) { && expr.operator == "=" && (sym = expr.left) instanceof AST_Symbol && vars.has(sym.name)) { - var def = vars.get(sym.name); - if (def.value) break; + var defn = vars.get(sym.name); + if (defn.value) break; var value = expr.right; if (value instanceof AST_Sequence) value = value.clone(); - def.value = value; - remove(defs, def); - defs.push(def); + defn.value = value; + remove(defns, defn); + defns.push(defn); body.shift(); continue; } @@ -7910,11 +7911,11 @@ Compressor.prototype.compress = function(node) { && assign.operator == "=" && (sym = assign.left) instanceof AST_Symbol && vars.has(sym.name)) { - var def = vars.get(sym.name); - if (def.value) break; - def.value = assign.right; - remove(defs, def); - defs.push(def); + var defn = vars.get(sym.name); + if (defn.value) break; + defn.value = assign.right; + remove(defns, defn); + defns.push(defn); stat.body = make_sequence(expr, expr.expressions.slice(1)); continue; } diff --git a/test/compress/hoist_vars.js b/test/compress/hoist_vars.js index 626300e3..30fb4837 100644 --- a/test/compress/hoist_vars.js +++ b/test/compress/hoist_vars.js @@ -499,3 +499,34 @@ issue_5195: { } expect_stdout: "[object Object]" } + +issue_5378: { + options = { + hoist_vars: true, + inline: true, + toplevel: true, + } + input: { + var a = 2; + while (a--) + (function() { + var b; + var c; + while (console.log(b)); + --b; + })(); + } + expect: { + var a = 2; + while (a--) { + b = void 0; + var b, c; + while (console.log(b)); + --b; + } + } + expect_stdout: [ + "undefined", + "undefined", + ] +}