aboutsummaryrefslogtreecommitdiff
path: root/lib/scope.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/scope.js')
-rw-r--r--lib/scope.js29
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);