fix corner case in hoist_vars (#5379)

fixes #5378
This commit is contained in:
Alex Lam S.L
2022-03-06 09:56:00 +00:00
committed by GitHub
parent 042c228c7b
commit 12a6728c4e
2 changed files with 55 additions and 23 deletions

View File

@@ -7844,15 +7844,15 @@ Compressor.prototype.compress = function(node) {
&& !consts.has(sym.name) && !consts.has(sym.name)
&& self.find_variable(sym.name) === sym.definition(); && self.find_variable(sym.name) === sym.definition();
})) return node; })) return node;
node.definitions.forEach(function(def) { node.definitions.forEach(function(defn) {
vars.set(def.name.name, def); vars.set(defn.name.name, defn);
++vars_found; ++vars_found;
}); });
var seq = node.to_assignments(); var seq = node.to_assignments();
if (p instanceof AST_ForEnumeration && p.init === node) { if (p instanceof AST_ForEnumeration && p.init === node) {
if (seq) return seq; if (seq) return seq;
var def = node.definitions[0].name; var sym = node.definitions[0].name;
return make_node(AST_SymbolRef, def, def); return make_node(AST_SymbolRef, sym, sym);
} }
if (p instanceof AST_For && p.init === node) return seq; if (p instanceof AST_For && p.init === node) return seq;
if (!seq) return in_list ? List.skip : make_node(AST_EmptyStatement, node); if (!seq) return in_list ? List.skip : make_node(AST_EmptyStatement, node);
@@ -7867,21 +7867,22 @@ Compressor.prototype.compress = function(node) {
self.transform(tt); self.transform(tt);
if (vars_found > 0) { if (vars_found > 0) {
// collect only vars which don't show up in self's arguments list // 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) { if (self instanceof AST_Lambda) self.each_argname(function(argname) {
vars.del(argname.name); vars.del(argname.name);
}); });
vars.each(function(def, name) { vars.each(function(defn, name) {
def = def.clone(); defn = defn.clone();
def.value = null; defn.name = defn.name.clone();
defs.push(def); defn.value = null;
vars.set(name, def); 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 // try to merge in assignments
insert_vars(self.body); insert_vars(self.body);
defs = make_node(AST_Var, self, { definitions: defs }); hoisted.push(make_node(AST_Var, self, { definitions: defns }));
hoisted.push(defs);
} }
} }
self.body = dirs.concat(hoisted, self.body); self.body = dirs.concat(hoisted, self.body);
@@ -7895,13 +7896,13 @@ Compressor.prototype.compress = function(node) {
&& expr.operator == "=" && expr.operator == "="
&& (sym = expr.left) instanceof AST_Symbol && (sym = expr.left) instanceof AST_Symbol
&& vars.has(sym.name)) { && vars.has(sym.name)) {
var def = vars.get(sym.name); var defn = vars.get(sym.name);
if (def.value) break; if (defn.value) break;
var value = expr.right; var value = expr.right;
if (value instanceof AST_Sequence) value = value.clone(); if (value instanceof AST_Sequence) value = value.clone();
def.value = value; defn.value = value;
remove(defs, def); remove(defns, defn);
defs.push(def); defns.push(defn);
body.shift(); body.shift();
continue; continue;
} }
@@ -7910,11 +7911,11 @@ Compressor.prototype.compress = function(node) {
&& assign.operator == "=" && assign.operator == "="
&& (sym = assign.left) instanceof AST_Symbol && (sym = assign.left) instanceof AST_Symbol
&& vars.has(sym.name)) { && vars.has(sym.name)) {
var def = vars.get(sym.name); var defn = vars.get(sym.name);
if (def.value) break; if (defn.value) break;
def.value = assign.right; defn.value = assign.right;
remove(defs, def); remove(defns, defn);
defs.push(def); defns.push(defn);
stat.body = make_sequence(expr, expr.expressions.slice(1)); stat.body = make_sequence(expr, expr.expressions.slice(1));
continue; continue;
} }

View File

@@ -499,3 +499,34 @@ issue_5195: {
} }
expect_stdout: "[object Object]" 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",
]
}