diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-10-11 18:18:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-12 01:18:57 +0800 |
commit | 55451e7b78c1765c6c3011d880c7980c10b7330f (patch) | |
tree | 8e63243cf2c73dd25867e2cb1ba3c8d7cf0ed1e9 /lib/scope.js | |
parent | ffcce28ce15afe9f0b8d8a4a83b901508eb866de (diff) | |
download | tracifyjs-55451e7b78c1765c6c3011d880c7980c10b7330f.tar.gz tracifyjs-55451e7b78c1765c6c3011d880c7980c10b7330f.zip |
support `const` (#4190)
Diffstat (limited to 'lib/scope.js')
-rw-r--r-- | lib/scope.js | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/lib/scope.js b/lib/scope.js index ec2c1f6d..fa558640 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -80,7 +80,12 @@ SymbolDef.prototype = { } }, redefined: function() { - return this.defun && this.defun.variables.get(this.name); + var scope = this.defun; + if (!scope) return; + var def = scope.variables.get(this.name); + if (!def && scope instanceof AST_Toplevel) def = scope.globals.get(this.name); + if (def === this) return; + return def; }, unmangleable: function(options) { return this.global && !options.toplevel @@ -114,6 +119,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { }); return true; } + if (node instanceof AST_SwitchBranch) { + node.init_vars(scope); + descend(); + return true; + } if (node instanceof AST_Try) { walk_scope(function() { walk_body(node, tw); @@ -122,10 +132,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { if (node.bfinally) node.bfinally.walk(tw); return true; } - if (node instanceof AST_BlockScope) { - walk_scope(descend); - return true; - } if (node instanceof AST_With) { var s = scope; do { @@ -133,7 +139,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { if (s.uses_with) break; s.uses_with = true; } while (s = s.parent_scope); - return; + walk_scope(descend); + return true; + } + if (node instanceof AST_BlockScope) { + walk_scope(descend); + return true; } if (node instanceof AST_Symbol) { node.scope = scope; @@ -144,6 +155,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } if (node instanceof AST_SymbolCatch) { scope.def_variable(node).defun = defun; + } else if (node instanceof AST_SymbolConst) { + scope.def_variable(node).defun = defun; } else if (node instanceof AST_SymbolDefun) { defun.def_function(node, tw.parent()); entangle(defun, scope); @@ -216,7 +229,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { node.reference(options); return true; } - // ensure mangling works if catch reuses a scope variable + // ensure mangling works if `catch` reuses a scope variable if (node instanceof AST_SymbolCatch) { var def = node.definition().redefined(); if (def) for (var s = node.scope; s; s = s.parent_scope) { @@ -225,6 +238,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } return true; } + // ensure compression works if `const` reuses a scope variable + if (node instanceof AST_SymbolConst) { + var def = node.definition(); + var redef = def.redefined(); + if (redef) { + if (!redef.const_redefs) redef.const_redefs = []; + redef.const_redefs.push(def); + } + return true; + } }); self.walk(tw); @@ -290,7 +313,6 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) { }); function init_block_vars(scope, parent) { - scope.cname = -1; // the current index for mangling functions/variables scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes scope.parent_scope = parent; // the parent scope (null if this is the top level) scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope) @@ -368,8 +390,9 @@ AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) { function names_in_use(scope, options) { var names = scope.names_in_use; if (!names) { - scope.names_in_use = names = Object.create(null); + scope.cname = -1; scope.cname_holes = []; + scope.names_in_use = names = Object.create(null); var cache = options.cache && options.cache.props; scope.enclosed.forEach(function(def) { if (def.unmangleable(options)) names[def.name] = true; @@ -467,7 +490,11 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { lname = save_nesting; return true; } - if (node instanceof AST_Scope) { + if (node instanceof AST_BlockScope) { + var to_mangle = []; + node.variables.each(function(def) { + if (!defer_redef(def)) to_mangle.push(def); + }); descend(); if (options.cache && node instanceof AST_Toplevel) { node.globals.each(mangle); @@ -477,9 +504,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { sym.scope = node; sym.reference(options); } - node.variables.each(function(def) { - if (!defer_redef(def)) mangle(def); - }); + to_mangle.forEach(mangle); return true; } if (node instanceof AST_Label) { @@ -490,13 +515,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { node.mangled_name = name; return true; } - if (!options.ie8 && node instanceof AST_Catch && node.argname) { - var def = node.argname.definition(); - var redef = defer_redef(def, node.argname); - descend(); - if (!redef) mangle(def); - return true; - } }); this.walk(tw); redefined.forEach(mangle); @@ -511,7 +529,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { if (!redef) return false; redefined.push(def); def.references.forEach(reference); - if (node) reference(node); + var node = def.orig[0]; + if (node instanceof AST_SymbolCatch || node instanceof AST_SymbolConst) reference(node); return true; function reference(sym) { |