aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-10-04 01:24:41 +0100
committerGitHub <noreply@github.com>2020-10-04 08:24:41 +0800
commit95ef4d5377efc159c7102f134d844ba617b28996 (patch)
treed3768efb468f24ba872c9ac39a981c0a7e0a7742 /lib
parent04017215cc0bd9a19492cd8792dac556a0912043 (diff)
downloadtracifyjs-95ef4d5377efc159c7102f134d844ba617b28996.tar.gz
tracifyjs-95ef4d5377efc159c7102f134d844ba617b28996.zip
fix corner case in `mangle` (#4174)
Diffstat (limited to 'lib')
-rw-r--r--lib/scope.js91
1 files changed, 57 insertions, 34 deletions
diff --git a/lib/scope.js b/lib/scope.js
index 27acf20f..359bd883 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -59,13 +59,9 @@ function SymbolDef(id, scope, orig, init) {
}
SymbolDef.prototype = {
- unmangleable: function(options) {
- return this.global && !options.toplevel
- || this.undeclared
- || !options.eval && this.scope.pinned()
- || options.keep_fnames
- && (this.orig[0] instanceof AST_SymbolLambda
- || this.orig[0] instanceof AST_SymbolDefun);
+ forEach: function(fn) {
+ this.orig.forEach(fn);
+ this.references.forEach(fn);
},
mangle: function(options) {
var cache = options.cache && options.cache.props;
@@ -85,7 +81,15 @@ SymbolDef.prototype = {
},
redefined: function() {
return this.defun && this.defun.variables.get(this.name);
- }
+ },
+ unmangleable: function(options) {
+ return this.global && !options.toplevel
+ || this.undeclared
+ || !options.eval && this.scope.pinned()
+ || options.keep_fnames
+ && (this.orig[0] instanceof AST_SymbolLambda
+ || this.orig[0] instanceof AST_SymbolDefun);
+ },
};
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
@@ -100,15 +104,18 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
var next_def_id = 0;
var scope = self.parent_scope = null;
var tw = new TreeWalker(function(node, descend) {
+ if (node instanceof AST_Defun) {
+ node.name.walk(tw);
+ walk_scope(function() {
+ node.argnames.forEach(function(argname) {
+ argname.walk(tw);
+ });
+ walk_body(node, tw);
+ });
+ return true;
+ }
if (node instanceof AST_BlockScope) {
- node.init_scope_vars(scope);
- var save_defun = defun;
- var save_scope = scope;
- if (node instanceof AST_Scope) defun = node;
- scope = node;
- descend();
- scope = save_scope;
- defun = save_defun;
+ walk_scope(descend);
return true;
}
if (node instanceof AST_With) {
@@ -122,25 +129,41 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
node.thedef = node;
node.references = [];
}
- if (node instanceof AST_SymbolDefun) {
- // This should be defined in the parent scope, as we encounter the
- // AST_Defun node before getting to its AST_Symbol.
- (node.scope = defun.parent_scope.resolve()).def_function(node, defun);
+ if (node instanceof AST_SymbolCatch) {
+ scope.def_variable(node).defun = defun;
+ } else if (node instanceof AST_SymbolDefun) {
+ defun.def_function(node, tw.parent());
+ entangle(defun, scope);
+ } else if (node instanceof AST_SymbolFunarg) {
+ defun.def_variable(node);
+ entangle(defun, scope);
} else if (node instanceof AST_SymbolLambda) {
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
if (options.ie8) def.defun = defun.parent_scope.resolve();
} else if (node instanceof AST_SymbolVar) {
- defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
- if (defun !== scope) {
- node.mark_enclosed(options);
- var def = scope.find_variable(node);
- if (node.thedef !== def) {
- node.thedef = def;
- }
- node.reference(options);
- }
- } else if (node instanceof AST_SymbolCatch) {
- scope.def_variable(node).defun = defun;
+ defun.def_variable(node, null);
+ entangle(defun, scope);
+ }
+
+ function walk_scope(descend) {
+ node.init_scope_vars(scope);
+ var save_defun = defun;
+ var save_scope = scope;
+ if (node instanceof AST_Scope) defun = node;
+ scope = node;
+ descend();
+ scope = save_scope;
+ defun = save_defun;
+ }
+
+ function entangle(defun, scope) {
+ if (defun === scope) return;
+ node.mark_enclosed(options);
+ var def = scope.find_variable(node);
+ if (node.thedef === def) return;
+ node.thedef = def;
+ def.orig.push(node);
+ node.mark_enclosed(options);
}
});
self.make_def = function(orig, init) {
@@ -227,7 +250,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
new_def = scope.def_variable(node);
}
old_def.defun = new_def.scope;
- old_def.orig.concat(old_def.references).forEach(function(node) {
+ old_def.forEach(function(node) {
node.redef = true;
node.thedef = new_def;
node.reference(options);
@@ -341,7 +364,7 @@ function next_mangled_name(scope, options, def) {
var holes = scope.cname_holes;
var names = Object.create(null);
var scopes = [ scope ];
- def.references.forEach(function(sym) {
+ def.forEach(function(sym) {
var scope = sym.scope;
do {
if (scopes.indexOf(scope) < 0) {
@@ -525,7 +548,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
var redef = def.redefined();
var name = redef ? redef.rename || redef.name : next_name();
def.rename = name;
- def.orig.concat(def.references).forEach(function(sym) {
+ def.forEach(function(sym) {
if (sym.definition() === def) sym.name = name;
});
}
5fc347192a3b&ofs=50'>[next]