diff options
Diffstat (limited to 'lib/scope.js')
-rw-r--r-- | lib/scope.js | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/scope.js b/lib/scope.js index bb36583c..3ff0c631 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -70,7 +70,9 @@ SymbolDef.prototype = { } else if (!this.mangled_name && !this.unmangleable(options)) { var def = this.redefined(); if (def) { - this.mangled_name = def.mangled_name || def.name; + var name = def.mangled_name || def.name; + this.mangled_name = name; + names_in_use(this.scope, options)[name] = true; } else { this.mangled_name = next_mangled_name(this, options); } @@ -80,15 +82,16 @@ SymbolDef.prototype = { } }, redefined: function() { - var scope = this.defun; + var self = this; + var scope = self.defun; if (!scope) return; - var name = this.name; + var name = self.name; var def = scope.variables.get(name) || scope instanceof AST_Toplevel && scope.globals.get(name) - || this.orig[0] instanceof AST_SymbolConst && find_if(function(def) { - return def.name == name; + || self.orig[0] instanceof AST_SymbolConst && find_if(function(def) { + return def.name == name && def !== self; }, scope.enclosed); - if (def && def !== this) return def.redefined() || def; + if (def && def !== self) return def.redefined() || def; }, unmangleable: function(options) { return this.global && !options.toplevel @@ -122,6 +125,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { // pass 1: setup scope chaining and handle definitions var self = this; + var const_names = null; var defun = null; var exported = false; var next_def_id = 0; @@ -200,6 +204,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } else if (node instanceof AST_SymbolConst) { var def = scope.def_variable(node); def.defun = defun; + const_names.add(def.name, def); if (exported) def.exported = true; } else if (node instanceof AST_SymbolDefun) { var def = defun.def_function(node, tw.parent()); @@ -222,13 +227,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { function walk_scope(descend) { node.init_vars(scope); + var save_names = const_names; var save_defun = defun; var save_scope = scope; - if (node instanceof AST_Scope) defun = node; + if (node instanceof AST_Scope) { + const_names = new Dictionary(); + defun = node; + } scope = node; descend(); + if (node instanceof AST_Scope) const_names.each(function(defs, name) { + if (defs.length > 1 && !node.variables.has(name)) push_uniq(node.enclosed, defs[0]); + }); scope = save_scope; defun = save_defun; + const_names = save_names; } function entangle(defun, scope) { @@ -668,6 +681,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { if (def.scope.parent_scope.find_variable(sym.name)) return false; redef = scope.def_variable(sym); scope.to_mangle.push(redef); + } else if (redef.mangled_name) { + return false; } redefined.push(def); def.references.forEach(reference); |