Index: lib/src/codegen/js_names.dart |
diff --git a/lib/src/codegen/js_names.dart b/lib/src/codegen/js_names.dart |
index 38fc7d1e327fa509bf401a6eb398cc04b9bc718a..0e08929b4847bd932400e145fad60357647edda9 100644 |
--- a/lib/src/codegen/js_names.dart |
+++ b/lib/src/codegen/js_names.dart |
@@ -60,20 +60,22 @@ class MaybeQualifiedId extends Expression { |
/// `function` or `instanceof`, and their `name` field controls whether they |
/// refer to the same variable. |
class TemporaryNamer extends LocalNamer { |
- final Map<Object, String> renames; |
+ _FunctionScope scope; |
- TemporaryNamer(Node node) : renames = new _RenameVisitor.build(node).renames; |
+ TemporaryNamer(Node node) : scope = new _RenameVisitor.build(node).rootScope; |
String getName(Identifier node) { |
- var rename = renames[identifierKey(node)]; |
+ var rename = scope.renames[identifierKey(node)]; |
if (rename != null) return rename; |
- |
- assert(!needsRename(node)); |
return node.name; |
} |
- void enterScope(FunctionExpression node) {} |
- void leaveScope() {} |
+ void enterScope(FunctionExpression node) { |
+ scope = scope.functions[node]; |
+ } |
+ void leaveScope() { |
+ scope = scope.parent; |
+ } |
} |
/// Represents a complete function scope in JS. |
@@ -94,7 +96,10 @@ class _FunctionScope { |
/// Nested functions, these are visited after everything else so the names |
/// they might need are in scope. |
- final functions = new List<FunctionExpression>(); |
+ final functions = new Map<FunctionExpression, _FunctionScope>(); |
+ |
+ /// New names assigned for temps and identifiers. |
+ final renames = new HashMap<Object, String>(); |
_FunctionScope(this.parent); |
} |
@@ -102,7 +107,6 @@ class _FunctionScope { |
/// Collects all names used in the visited tree. |
class _RenameVisitor extends VariableDeclarationVisitor { |
final pendingRenames = new Map<Object, Set<_FunctionScope>>(); |
- final renames = new HashMap<Object, String>(); |
final _FunctionScope rootScope = new _FunctionScope(null); |
_FunctionScope scope; |
@@ -143,7 +147,8 @@ class _RenameVisitor extends VariableDeclarationVisitor { |
// If it needs rename, we can't add it to the used name set yet, instead we |
// will record all scopes it is visible in. |
Set<_FunctionScope> usedIn = null; |
- if (needsRename(node)) { |
+ var rename = declScope != rootScope && needsRename(node); |
+ if (rename) { |
usedIn = pendingRenames.putIfAbsent(id, () => new HashSet()); |
} |
for (var s = scope, end = declScope.parent; s != end; s = s.parent) { |
@@ -157,16 +162,16 @@ class _RenameVisitor extends VariableDeclarationVisitor { |
visitFunctionExpression(FunctionExpression node) { |
// Visit nested functions after all identifiers are declared. |
- scope.functions.add(node); |
+ scope.functions[node] = new _FunctionScope(scope); |
} |
void _finishFunctions() { |
- for (var f in scope.functions) { |
- scope = new _FunctionScope(scope); |
+ scope.functions.forEach((FunctionExpression f, _FunctionScope s) { |
+ scope = s; |
super.visitFunctionExpression(f); |
_finishFunctions(); |
scope = scope.parent; |
- } |
+ }); |
} |
void _finishNames() { |
@@ -176,9 +181,10 @@ class _RenameVisitor extends VariableDeclarationVisitor { |
for (var s in scopes) allNames.addAll(s.used); |
var name = _findName(id, allNames); |
- renames[id] = name; |
- |
- for (var s in scopes) s.used.add(name); |
+ for (var s in scopes) { |
+ s.used.add(name); |
+ s.renames[id] = name; |
+ } |
}); |
} |