From: Mihai Bazon Date: Thu, 12 Nov 2015 09:48:06 +0000 (+0200) Subject: Build label def/refs info when figuring out scope X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c898a26117c2687d5707a4e80d6058d5c8601165;p=UglifyJS.git Build label def/refs info when figuring out scope Fix #862 --- diff --git a/lib/scope.js b/lib/scope.js index 4a3739c4..1f0986c4 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -92,6 +92,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ // pass 1: setup scope chaining and handle definitions var self = this; var scope = self.parent_scope = null; + var labels = new Dictionary(); var defun = null; var nesting = 0; var tw = new TreeWalker(function(node, descend){ @@ -108,12 +109,25 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ node.init_scope_vars(nesting); var save_scope = node.parent_scope = scope; var save_defun = defun; + var save_labels = labels; defun = scope = node; + labels = new Dictionary(); ++nesting; descend(); --nesting; scope = save_scope; defun = save_defun; + labels = save_labels; return true; // don't descend again in TreeWalker } + if (node instanceof AST_LabeledStatement) { + var l = node.label; + if (labels.has(l.name)) { + throw new Error(string_template("Label {name} defined twice", l)); + } + labels.set(l.name, l); + descend(); + labels.del(l.name); + return true; // no descend again + } if (node instanceof AST_With) { for (var s = scope; s; s = s.parent_scope) s.uses_with = true; @@ -122,6 +136,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ if (node instanceof AST_Symbol) { node.scope = scope; } + if (node instanceof AST_Label) { + node.thedef = node; + node.references = []; + } if (node instanceof AST_SymbolLambda) { defun.def_function(node); } @@ -143,6 +161,15 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ (options.screw_ie8 ? scope : defun) .def_variable(node); } + else if (node instanceof AST_LabelRef) { + var sym = labels.get(node.name); + if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", { + name: node.name, + line: node.start.line, + col: node.start.col + })); + node.thedef = sym; + } }); self.walk(tw); @@ -157,6 +184,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ func = prev_func; return true; } + if (node instanceof AST_LoopControl && node.label) { + node.label.thedef.references.push(node); + return true; + } if (node instanceof AST_SymbolRef) { var name = node.name; var sym = node.scope.find_variable(name);