aboutsummaryrefslogtreecommitdiff
path: root/lib/scope.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-10-04 23:56:52 +0100
committerGitHub <noreply@github.com>2020-10-05 06:56:52 +0800
commit220dc95c0d212ad4f3b97fcd937c4370ae5345dd (patch)
treee12e654ab36b9526b3ebad8363fdac4f9a43a30e /lib/scope.js
parent8f0521d51d0292cc84782628cda1a9d16b083ed6 (diff)
downloadtracifyjs-220dc95c0d212ad4f3b97fcd937c4370ae5345dd.tar.gz
tracifyjs-220dc95c0d212ad4f3b97fcd937c4370ae5345dd.zip
clean up scope-related variables (#4179)
Diffstat (limited to 'lib/scope.js')
-rw-r--r--lib/scope.js34
1 files changed, 24 insertions, 10 deletions
diff --git a/lib/scope.js b/lib/scope.js
index 86fd3957..209ac235 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -127,7 +127,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
return true;
}
if (node instanceof AST_With) {
- for (var s = scope; s; s = s.parent_scope) s.uses_with = true;
+ var s = scope;
+ do {
+ s = s.resolve();
+ if (s.uses_with) break;
+ s.uses_with = true;
+ } while (s = s.parent_scope);
return;
}
if (node instanceof AST_Symbol) {
@@ -154,7 +159,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
function walk_scope(descend) {
- node.init_scope_vars(scope);
+ node.init_vars(scope);
var save_defun = defun;
var save_scope = scope;
if (node instanceof AST_Scope) defun = node;
@@ -197,9 +202,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
if (name == "eval") {
var parent = tw.parent();
if (parent.TYPE == "Call" && parent.expression === node) {
- for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
+ var s = node.scope;
+ do {
+ s = s.resolve();
+ if (s.uses_eval) break;
s.uses_eval = true;
- }
+ } while (s = s.parent_scope);
} else if (sym.undeclared) {
self.uses_eval = true;
}
@@ -281,22 +289,28 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
}
});
-function init_scope_vars(scope, parent) {
+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.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
- scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
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)
scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances
}
-AST_BlockScope.DEFMETHOD("init_scope_vars", function(parent_scope) {
+function init_scope_vars(scope, parent) {
+ init_block_vars(scope, parent);
+ scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
+ scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
+}
+
+AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
+ init_block_vars(this, parent_scope);
+});
+AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
});
-
-AST_Lambda.DEFMETHOD("init_scope_vars", function(parent_scope) {
+AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
init_scope_vars(this, parent_scope);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({