From 175dba49777a4c63ff061289b8e1ebab2651d2e0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jul 2014 17:04:06 -0700 Subject: [PATCH] Ensuring local module names are unique in emit. Fixes #41 and #42. --- src/compiler/binder.ts | 1 + src/compiler/checker.ts | 43 +++++++++++++++++++++++++++++++++++++++++ src/compiler/types.ts | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ec67b496db6..691965b0ad7 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -33,6 +33,7 @@ module ts { var container: Declaration; var lastContainer: Declaration; var symbolCount = 0; + var lastLocals: Declaration; var Symbol = objectAllocator.getSymbolConstructor(); if (!file.locals) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6541a3641d8..8cb72980e74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6049,6 +6049,49 @@ module ts { Debug.fail("getLocalNameForSymbol failed"); } + function isNodeParentedBy(node: Node, parent: Node): boolean { + while (node) { + if (node === parent) return true; + node = node.parent; + } + return false; + } + + 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; + } + } + } + return true; + } + + 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; + } + links.localModuleName = name; + } + return links.localModuleName; + } + + function getLocalNameForSymbol(symbol: Symbol, location: Node): string { + var node = location; + while (node) { + if ((node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(node) === symbol) { + return getLocalNameOfContainer(node); + } + node = node.parent; + } + Debug.fail("getLocalNameForSymbol failed"); + } + function getExpressionNamePrefix(node: Identifier): string { var symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5decadcfe17..3820920dffa 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -691,7 +691,7 @@ module ts { ExportHasLocal = Function | Class | Enum | ValueModule, - HasLocals = Function | Module | Method | Constructor | Accessor | Signature, + HasLocals = Function | Enum | Module | Method | Constructor | Accessor | Signature, HasExports = Class | Enum | Module, HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,