aboutsummaryrefslogtreecommitdiff
path: root/lib/scope.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-10-11 18:18:57 +0100
committerGitHub <noreply@github.com>2020-10-12 01:18:57 +0800
commit55451e7b78c1765c6c3011d880c7980c10b7330f (patch)
tree8e63243cf2c73dd25867e2cb1ba3c8d7cf0ed1e9 /lib/scope.js
parentffcce28ce15afe9f0b8d8a4a83b901508eb866de (diff)
downloadtracifyjs-55451e7b78c1765c6c3011d880c7980c10b7330f.tar.gz
tracifyjs-55451e7b78c1765c6c3011d880c7980c10b7330f.zip
support `const` (#4190)
Diffstat (limited to 'lib/scope.js')
-rw-r--r--lib/scope.js61
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) {