Introduce NodeFlags.ExportContext

This commit is contained in:
Anders Hejlsberg
2015-03-17 06:15:23 -07:00
parent 1bb4a62988
commit c39dfdc238
3 changed files with 35 additions and 18 deletions
+34 -9
View File
@@ -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 : (<ModuleDeclaration>node).body;
if (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock) {
for (let stat of (<Block>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(<SourceFile>node);
if (isExternalModule(<SourceFile>node)) {
bindAnonymousDeclaration(<SourceFile>node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).fileName) + '"', /*isBlockScopeContainer*/ true);
break;
-9
View File
@@ -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);
+1
View File
@@ -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,