From c59bf5e8d890f493bd78c8c632b79881536273d1 Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Mon, 27 Feb 2017 06:20:08 +0800 Subject: [PATCH] fix `SymbolDef.global` properly compute for top-level block-variables --- lib/scope.js | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/scope.js b/lib/scope.js index 1aef38a6..42afe87c 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -105,7 +105,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ var labels = new Dictionary(); var defun = null; var in_destructuring = null; - var in_export; + var in_export = false; + var in_block = 0; var tw = new TreeWalker(function(node, descend){ if (node.is_block_scope()) { var save_scope = scope; @@ -146,6 +147,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ in_export = false; return true; } + if (node instanceof AST_BlockStatement + || node instanceof AST_Switch + || node instanceof AST_Try + || node instanceof AST_Catch + || node instanceof AST_Finally) { + in_block++; + descend(); + in_block--; + return true; + } if (node instanceof AST_LabeledStatement) { var l = node.label; if (labels.has(l.name)) { @@ -172,7 +183,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ node.references = []; } if (node instanceof AST_SymbolLambda) { - defun.def_function(node, in_export); + defun.def_function(node, in_export, in_block); } else if (node instanceof AST_SymbolDefun) { // Careful here, the scope where this should be defined is @@ -184,29 +195,28 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ while (parent_lambda.is_block_scope()) { parent_lambda = parent_lambda.parent_scope; } - (node.scope = parent_lambda).def_function(node, in_export); + (node.scope = parent_lambda).def_function(node, in_export, in_block); } else if (node instanceof AST_SymbolClass) { - defun.def_variable(node, in_export); + defun.def_variable(node, in_export, in_block); } else if (node instanceof AST_SymbolImport) { - scope.def_variable(node, in_export); + scope.def_variable(node, in_export, in_block); } else if (node instanceof AST_SymbolDefClass) { // This deals with the name of the class being available // inside the class. - (node.scope = defun.parent_scope).def_function(node, in_export); + (node.scope = defun.parent_scope).def_function(node, in_export, in_block); } else if (node instanceof AST_SymbolVar || node instanceof AST_SymbolConst || node instanceof AST_SymbolLet) { - var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node, in_export); + var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node, in_export, in_block); def.destructuring = in_destructuring; def.init = tw.parent().value; } else if (node instanceof AST_SymbolCatch) { - (options.screw_ie8 ? scope : defun) - .def_variable(node); + (options.screw_ie8 ? scope : defun).def_variable(node, in_export, in_block); } else if (node instanceof AST_LabelRef) { var sym = labels.get(node.name); @@ -336,11 +346,11 @@ AST_Scope.DEFMETHOD("find_variable", function(name){ || (this.parent_scope && this.parent_scope.find_variable(name)); }); -AST_Scope.DEFMETHOD("def_function", function(symbol, in_export){ - this.functions.set(symbol.name, this.def_variable(symbol, in_export)); +AST_Scope.DEFMETHOD("def_function", function(symbol, in_export, in_block){ + this.functions.set(symbol.name, this.def_variable(symbol, in_export, in_block)); }); -AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export){ +AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export, in_block){ var def; if (!this.variables.has(symbol.name)) { def = new SymbolDef(this, this.variables.size(), symbol); @@ -349,7 +359,11 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export){ if (in_export) { def.export = true; } - def.global = !this.parent_scope && !(symbol instanceof AST_SymbolBlockDeclaration); + if (in_block && symbol instanceof AST_SymbolBlockDeclaration) { + def.global = false; + } else { + def.global = !this.parent_scope; + } } else { def = this.variables.get(symbol.name); def.orig.push(symbol);