diff --git a/lib/compress.js b/lib/compress.js index 2b9aa1ce8ee..2c725997642 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4276,11 +4276,11 @@ Compressor.prototype.compress = function(node) { prev.definitions = prev.definitions.concat(stat.definitions); changed = true; } else if (stat && prev instanceof AST_Let && stat.can_letify(compressor)) { - prev.definitions = prev.definitions.concat(to_let(stat).definitions); + prev.definitions = prev.definitions.concat(to_let(stat, block_scope).definitions); changed = true; } else if (prev && stat instanceof AST_Let && prev.can_letify(compressor)) { defs = prev_defs; - statements[j] = prev = to_let(prev); + statements[j] = prev = to_let(prev, block_scope); prev.definitions = prev.definitions.concat(stat.definitions); changed = true; } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) { @@ -9394,7 +9394,7 @@ Compressor.prototype.compress = function(node) { }, true)) { self.init = to_var(self.init, self.resolve()); } else if (self.init.can_letify(compressor, true)) { - self.init = to_let(self.init); + self.init = to_let(self.init, self); } } return self; @@ -10208,13 +10208,18 @@ Compressor.prototype.compress = function(node) { } } - function to_let(stat) { + function to_let(stat, scope) { return make_node(AST_Let, stat, { definitions: stat.definitions.map(function(defn) { return make_node(AST_VarDef, defn, { name: defn.name.convert_symbol(AST_SymbolLet, function(name, node) { var def = name.definition(); def.orig[def.orig.indexOf(node)] = name; + for (var s = scope; s !== def.scope && (s = s.parent_scope);) { + remove(s.enclosed, def); + } + def.scope = scope; + scope.variables.set(def.name, def); }), value: defn.value, }); @@ -10297,7 +10302,7 @@ Compressor.prototype.compress = function(node) { OPT(AST_Const, function(self, compressor) { if (!compressor.option("varify")) return self; if (self.can_varify(compressor)) return to_var(self, compressor.find_parent(AST_Scope)); - if (self.can_letify(compressor)) return to_let(self); + if (self.can_letify(compressor)) return to_let(self, find_scope(compressor)); return self; }); diff --git a/test/compress/let.js b/test/compress/let.js index 2321bfbca8a..7a60e19592a 100644 --- a/test/compress/let.js +++ b/test/compress/let.js @@ -2391,3 +2391,105 @@ issue_5745_2: { expect_stdout: "PASS" node_version: ">=4" } + +issue_5756_1: { + options = { + join_vars: true, + loops: true, + reduce_vars: true, + toplevel: true, + } + input: { + "use strict"; + do { + function f() { + return b; + } + var a = "PASS".toString(); + let b; + console.log(a); + } while (!console); + } + expect: { + "use strict"; + do { + function f() { + return b; + } + let a = "PASS".toString(), b; + console.log(a); + } while (!console); + } + expect_stdout: "PASS" + node_version: ">=4" +} + +issue_5756_2: { + options = { + join_vars: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + "use strict"; + function f() { + let a = console.log("PASS"); + { + var b; + for (var c in b) { + b; + var c = function() { + a; + }; + } + } + } + f(); + } + expect: { + "use strict"; + (function() { + let a = console.log("PASS"), b; + for (c in b) { + b; + var c = function() { + a; + }; + } + })(); + } + expect_stdout: "PASS" + node_version: ">=4" +} + +issue_5756_3: { + options = { + module: true, + reduce_vars: true, + toplevel: true, + unused: true, + varify: true, + } + input: { + "use strict"; + console.log(f()()); + function f() { + const a = "PASS"; + return function() { + return a; + }; + } + } + expect: { + "use strict"; + console.log(function() { + let a = "PASS"; + return function() { + return a; + }; + }()()); + } + expect_stdout: "PASS" + node_version: ">=4" +}