fix corner cases in rename & varify (#4955)

fixes #4954
This commit is contained in:
Alex Lam S.L
2021-05-23 23:54:48 +01:00
committed by GitHub
parent 5d4e6e3bdc
commit 8b0c836515
5 changed files with 118 additions and 12 deletions

View File

@@ -8604,6 +8604,8 @@ merge(Compressor.prototype, {
if (def.scope === scope) return; if (def.scope === scope) return;
def.scope = scope; def.scope = scope;
scope.variables.set(def.name, def); scope.variables.set(def.name, def);
scope.enclosed.push(def);
scope.var_names()[def.name] = true;
}), }),
value: defn.value, value: defn.value,
}); });

View File

@@ -70,7 +70,9 @@ SymbolDef.prototype = {
} else if (!this.mangled_name && !this.unmangleable(options)) { } else if (!this.mangled_name && !this.unmangleable(options)) {
var def = this.redefined(); var def = this.redefined();
if (def) { if (def) {
this.mangled_name = def.mangled_name || def.name; var name = def.mangled_name || def.name;
this.mangled_name = name;
names_in_use(this.scope, options)[name] = true;
} else { } else {
this.mangled_name = next_mangled_name(this, options); this.mangled_name = next_mangled_name(this, options);
} }
@@ -80,15 +82,16 @@ SymbolDef.prototype = {
} }
}, },
redefined: function() { redefined: function() {
var scope = this.defun; var self = this;
var scope = self.defun;
if (!scope) return; if (!scope) return;
var name = this.name; var name = self.name;
var def = scope.variables.get(name) var def = scope.variables.get(name)
|| scope instanceof AST_Toplevel && scope.globals.get(name) || scope instanceof AST_Toplevel && scope.globals.get(name)
|| this.orig[0] instanceof AST_SymbolConst && find_if(function(def) { || self.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
return def.name == name; return def.name == name && def !== self;
}, scope.enclosed); }, scope.enclosed);
if (def && def !== this) return def.redefined() || def; if (def && def !== self) return def.redefined() || def;
}, },
unmangleable: function(options) { unmangleable: function(options) {
return this.global && !options.toplevel return this.global && !options.toplevel
@@ -122,6 +125,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 1: setup scope chaining and handle definitions // pass 1: setup scope chaining and handle definitions
var self = this; var self = this;
var const_names = null;
var defun = null; var defun = null;
var exported = false; var exported = false;
var next_def_id = 0; var next_def_id = 0;
@@ -200,6 +204,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
} else if (node instanceof AST_SymbolConst) { } else if (node instanceof AST_SymbolConst) {
var def = scope.def_variable(node); var def = scope.def_variable(node);
def.defun = defun; def.defun = defun;
const_names.add(def.name, def);
if (exported) def.exported = true; if (exported) def.exported = true;
} else if (node instanceof AST_SymbolDefun) { } else if (node instanceof AST_SymbolDefun) {
var def = defun.def_function(node, tw.parent()); var def = defun.def_function(node, tw.parent());
@@ -222,13 +227,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
function walk_scope(descend) { function walk_scope(descend) {
node.init_vars(scope); node.init_vars(scope);
var save_names = const_names;
var save_defun = defun; var save_defun = defun;
var save_scope = scope; var save_scope = scope;
if (node instanceof AST_Scope) defun = node; if (node instanceof AST_Scope) {
const_names = new Dictionary();
defun = node;
}
scope = node; scope = node;
descend(); descend();
if (node instanceof AST_Scope) const_names.each(function(defs, name) {
if (defs.length > 1 && !node.variables.has(name)) push_uniq(node.enclosed, defs[0]);
});
scope = save_scope; scope = save_scope;
defun = save_defun; defun = save_defun;
const_names = save_names;
} }
function entangle(defun, scope) { function entangle(defun, scope) {
@@ -668,6 +681,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
if (def.scope.parent_scope.find_variable(sym.name)) return false; if (def.scope.parent_scope.find_variable(sym.name)) return false;
redef = scope.def_variable(sym); redef = scope.def_variable(sym);
scope.to_mangle.push(redef); scope.to_mangle.push(redef);
} else if (redef.mangled_name) {
return false;
} }
redefined.push(def); redefined.push(def);
def.references.forEach(reference); def.references.forEach(reference);

View File

@@ -1535,3 +1535,56 @@ issue_4848: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_4954_1: {
rename = true
input: {
(function() {
{
const a = "foo";
console.log(a);
}
{
const a = "bar";
console.log(a);
}
})();
}
expect: {
(function() {
{
const a = "foo";
console.log(a);
}
{
const a = "bar";
console.log(a);
}
})();
}
expect_stdout: true
}
issue_4954_2: {
mangle = {}
input: {
"use strict";
const a = null;
(function(b) {
for (const a in null);
for (const a in b)
console.log("PASS");
})([ null ]);
}
expect: {
"use strict";
const a = null;
(function(o) {
for (const n in null);
for (const n in o)
console.log("PASS");
})([ null ]);
}
expect_stdout: "PASS"
node_version: ">=4"
}

View File

@@ -3080,11 +3080,9 @@ issue_4235: {
})(); })();
} }
expect: { expect: {
(function() { void function() {
f = console.log(f), var f = console.log(f);
void 0; }();
var f;
})();
} }
expect_stdout: "undefined" expect_stdout: "undefined"
} }

View File

@@ -575,3 +575,41 @@ issue_4933_2: {
} }
expect_stdout: "undefined" expect_stdout: "undefined"
} }
issue_4954: {
options = {
functions: true,
reduce_vars: true,
unused: true,
varify: true,
}
input: {
"use strict";
(function() {
{
let a = console;
console.log(typeof a);
}
{
let a = function() {};
a && console.log(typeof a);
}
})();
}
expect: {
"use strict";
(function() {
var a = console;
console.log(typeof a);
{
let a = function() {};
a && console.log(typeof a);
}
})();
}
expect_stdout: [
"object",
"function",
]
node_version: ">=4"
}