diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7c1e4c57a4c..edf5233e47d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -188,14 +188,6 @@ module ts { return symbol; } - function isAmbientContext(node: Node): boolean { - while (node) { - if (node.flags & NodeFlags.Ambient) return true; - node = node.parent; - } - return false; - } - function declareModuleMember(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { let hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export; if (symbolKind & SymbolFlags.Alias) { @@ -218,7 +210,7 @@ module ts { // 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol, // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. - if (hasExportModifier || isAmbientContext(container)) { + if (hasExportModifier || container.flags & NodeFlags.ExportContext) { let exportKind = (symbolKind & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | (symbolKind & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | (symbolKind & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); @@ -311,7 +303,39 @@ module ts { bindChildren(node, symbolKind, isBlockScopeContainer); } + function isAmbientContext(node: Node): boolean { + while (node) { + if (node.flags & NodeFlags.Ambient) return true; + node = node.parent; + } + return false; + } + + function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { + var body = node.kind === SyntaxKind.SourceFile ? node : (node).body; + if (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock) { + for (let stat of (body).statements) { + if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) { + return true; + } + } + } + return false; + } + + function setExportContextFlag(node: ModuleDeclaration | SourceFile) { + // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular + // declarations with export modifiers) is an export context in which declarations are implicitly exported. + if (isAmbientContext(node) && !hasExportDeclarations(node)) { + node.flags |= NodeFlags.ExportContext; + } + else { + node.flags &= ~NodeFlags.ExportContext; + } + } + function bindModuleDeclaration(node: ModuleDeclaration) { + setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); } @@ -516,6 +540,7 @@ module ts { bindChildren(node, 0, /*isBlockScopeContainer*/ false); break; case SyntaxKind.SourceFile: + setExportContextFlag(node); if (isExternalModule(node)) { bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"', /*isBlockScopeContainer*/ true); break; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0dacb20ece4..baeb1b59ba8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -784,15 +784,6 @@ module ts { } function getExportsForModule(moduleSymbol: Symbol): SymbolTable { - if (compilerOptions.target < ScriptTarget.ES6) { - // A default export hides all other exports in CommonJS and AMD modules - let defaultSymbol = getExportAssignmentSymbol(moduleSymbol); - if (defaultSymbol) { - return { - "default": defaultSymbol - }; - } - } let result: SymbolTable; let visitedSymbols: Symbol[] = []; visit(moduleSymbol); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c43591911ab..1631cc46a00 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -307,6 +307,7 @@ module ts { Let = 0x00001000, // Variable declaration Const = 0x00002000, // Variable declaration OctalLiteral = 0x00004000, + ExportContext = 0x00008000, // Export context (initialized by binding) Modifier = Export | Ambient | Public | Private | Protected | Static | Default, AccessibilityModifier = Public | Private | Protected,