From 393be4687cfacbe1c20180f7a6ee5f7460649335 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 19 Jul 2014 08:53:25 -0700 Subject: [PATCH] Improving code and addressing code review feedback. Binder now builds more generally useful linked list of all container declarations. Emitter uses original spelling when creating unique local container names. --- src/compiler/binder.ts | 41 +++++++++++++++++++---------------------- src/compiler/checker.ts | 18 ++++++++---------- src/compiler/types.ts | 4 ++-- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ad0a74f1079..ec67b496db6 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -31,8 +31,8 @@ module ts { var parent: Node; var container: Declaration; + var lastContainer: Declaration; var symbolCount = 0; - var lastLocals: Declaration; var Symbol = objectAllocator.getSymbolConstructor(); if (!file.locals) { @@ -163,12 +163,23 @@ module ts { } } - // All nodes with locals are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function + // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function // in the type checker to validate that the local name used for a container is unique. - function initializeLocals(node: Declaration) { - node.locals = {}; - if (lastLocals) lastLocals.nextLocals = node; - lastLocals = node; + function bindChildren(node: Declaration, symbolKind: SymbolFlags) { + if (symbolKind & SymbolFlags.HasLocals) { + node.locals = {}; + } + var saveParent = parent; + var saveContainer = container; + parent = node; + if (symbolKind & SymbolFlags.IsContainer) { + container = node; + if (lastContainer) lastContainer.nextContainer = container; + lastContainer = container; + } + forEachChild(node, bind); + container = saveContainer; + parent = saveParent; } function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { @@ -207,14 +218,7 @@ module ts { declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); break; } - if (symbolKind & SymbolFlags.HasLocals) initializeLocals(node); - var saveParent = parent; - var saveContainer = container; - parent = node; - if (symbolKind & SymbolFlags.IsContainer) container = node; - forEachChild(node, bind); - container = saveContainer; - parent = saveParent; + bindChildren(node, symbolKind); } function bindConstructorDeclaration(node: ConstructorDeclaration) { @@ -241,14 +245,7 @@ module ts { function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) { var symbol = createSymbol(symbolKind, name); addDeclarationToSymbol(symbol, node, symbolKind); - if (symbolKind & SymbolFlags.HasLocals) initializeLocals(node); - var saveParent = parent; - var saveContainer = container; - parent = node; - container = node; - forEachChild(node, bind); - container = saveContainer; - parent = saveParent; + bindChildren(node, symbolKind); } function bindCatchVariableDeclaration(node: CatchBlock) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6bb6a12903e..6541a3641d8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6017,12 +6017,9 @@ module ts { } function isUniqueLocalName(name: string, container: Node): boolean { - name = escapeIdentifier(name); - if (container.locals) { - for (var node = container; isNodeParentedBy(node, container); node = node.nextLocals) { - if (hasProperty(node.locals, name) && node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue)) { - return false; - } + for (var node = container; isNodeParentedBy(node, container); node = node.nextContainer) { + if (node.locals && hasProperty(node.locals, name) && node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue)) { + return false; } } return true; @@ -6031,11 +6028,12 @@ module ts { function getLocalNameOfContainer(container: Declaration): string { var links = getNodeLinks(container); if (!links.localModuleName) { - var name = container.name.text ? unescapeIdentifier(container.name.text) : "M"; - while (!isUniqueLocalName(name, container)) { - name = "_" + name; + var prefix = ""; + var name = unescapeIdentifier(container.name.text); + while (!isUniqueLocalName(escapeIdentifier(prefix + name), container)) { + prefix += "_"; } - links.localModuleName = name; + links.localModuleName = prefix + getSourceTextOfNode(container.name); } return links.localModuleName; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ee9a298b524..5decadcfe17 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -240,7 +240,7 @@ module ts { parent?: Node; // Parent node (initialized by binding) symbol?: Symbol; // Symbol declared by node (initialized by binding) locals?: SymbolTable; // Locals associated with node (initialized by binding) - nextLocals?: Node; // Next node in declaration order with locals (initialized by binding) + nextContainer?: Node; // Next container in declaration order (initialized by binding) } export interface NodeArray extends Array, TextRange { } @@ -691,7 +691,7 @@ module ts { ExportHasLocal = Function | Class | Enum | ValueModule, - HasLocals = Function | Enum | Module | Method | Constructor | Accessor | Signature, + HasLocals = Function | Module | Method | Constructor | Accessor | Signature, HasExports = Class | Enum | Module, HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,