From c5a353bf0dad1cf0ef407cf616b579417971ab69 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 8 Oct 2015 15:18:21 -0700 Subject: [PATCH 01/52] plumbing to start --- src/compiler/commandLineParser.ts | 7 ++ src/compiler/declarationEmitter.ts | 119 +++++++++++++++------------ src/compiler/diagnosticMessages.json | 9 +- src/compiler/program.ts | 4 + src/compiler/types.ts | 1 + 5 files changed, 88 insertions(+), 52 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 11062983aaa24..986d63c1b3125 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -246,6 +246,13 @@ namespace ts { }, description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic, + }, + { + name: "optimizationEntrypoint", + type: "string", + isFilePath: true, + description: Diagnostics.Specifies_the_script_file_used_as_the_entrypoint_for_optimizations, + paramType: Diagnostics.FILE } ]; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index c3d611f131c3d..d749ecabf7604 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -103,60 +103,73 @@ namespace ts { } } else { - // Emit references corresponding to this file - let emittedReferencedFiles: SourceFile[] = []; - let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; - forEach(host.getSourceFiles(), sourceFile => { - if (!isExternalModuleOrDeclarationFile(sourceFile)) { - noDeclare = false; - // Check what references need to be added - if (!compilerOptions.noResolve) { - forEach(sourceFile.referencedFiles, fileReference => { - let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference); - - // If the reference file is a declaration file or an external module, emit that reference - if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && - !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted - - writeReferencePath(referencedFile); - emittedReferencedFiles.push(referencedFile); - } - }); - } - - emitSourceFile(sourceFile); + if (compilerOptions.optimizationEntrypoint) { + let entrypoint = host.getSourceFile(compilerOptions.optimizationEntrypoint); + if (!entrypoint) { + diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, compilerOptions.optimizationEntrypoint)); + return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } - else if (isExternalModule(sourceFile)) { - noDeclare = true; - write(`declare module "${sourceFile.moduleName}" {`); - writeLine(); - increaseIndent(); - emitSourceFile(sourceFile); - decreaseIndent(); - write("}"); - writeLine(); + if (!isExternalModule(entrypoint)) { + diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, compilerOptions.optimizationEntrypoint)); + return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; + } + traverseEntrypoint(entrypoint); + } else { + // Emit references corresponding to this file + let emittedReferencedFiles: SourceFile[] = []; + let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; + forEach(host.getSourceFiles(), sourceFile => { + if (!isExternalModuleOrDeclarationFile(sourceFile)) { + noDeclare = false; + // Check what references need to be added + if (!compilerOptions.noResolve) { + forEach(sourceFile.referencedFiles, fileReference => { + let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference); + + // If the reference file is a declaration file or an external module, emit that reference + if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && + !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted + + writeReferencePath(referencedFile); + emittedReferencedFiles.push(referencedFile); + } + }); + } - // create asynchronous output for the importDeclarations - if (moduleElementDeclarationEmitInfo.length) { - let oldWriter = writer; - forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => { - if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) { - Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration); - createAndSetNewTextWriterWithSymbolWriter(); - Debug.assert(aliasEmitInfo.indent === 1); - increaseIndent(); - writeImportDeclaration(aliasEmitInfo.node); - aliasEmitInfo.asynchronousOutput = writer.getText(); - decreaseIndent(); - } - }); - setWriter(oldWriter); + emitSourceFile(sourceFile); } - prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo); - moduleElementDeclarationEmitInfo = []; - } - }); - moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo); + else if (isExternalModule(sourceFile)) { + noDeclare = true; + write(`declare module "${sourceFile.moduleName}" {`); + writeLine(); + increaseIndent(); + emitSourceFile(sourceFile); + decreaseIndent(); + write("}"); + writeLine(); + + // create asynchronous output for the importDeclarations + if (moduleElementDeclarationEmitInfo.length) { + let oldWriter = writer; + forEach(moduleElementDeclarationEmitInfo, aliasEmitInfo => { + if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) { + Debug.assert(aliasEmitInfo.node.kind === SyntaxKind.ImportDeclaration); + createAndSetNewTextWriterWithSymbolWriter(); + Debug.assert(aliasEmitInfo.indent === 1); + increaseIndent(); + writeImportDeclaration(aliasEmitInfo.node); + aliasEmitInfo.asynchronousOutput = writer.getText(); + decreaseIndent(); + } + }); + setWriter(oldWriter); + } + prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo); + moduleElementDeclarationEmitInfo = []; + } + }); + moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo); + } } return { @@ -166,6 +179,10 @@ namespace ts { referencePathsOutput, }; + function traverseEntrypoint(file: SourceFile) { + emitLines(file.statements) + } + function hasInternalAnnotation(range: CommentRange) { let text = currentSourceFile.text; let comment = text.substring(range.pos, range.end); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d5ea706e3e5a0..493769fab4e67 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2036,6 +2036,10 @@ "category": "Error", "code": 5033 }, + "Option '{0}' can only be specified with both options '{1}' and '{2}'.": { + "category": "Error", + "code": 5034 + }, "Option 'project' cannot be mixed with source files on a command line.": { "category": "Error", "code": 5042 @@ -2257,7 +2261,10 @@ "category": "Error", "code": 6063 }, - + "Specifies the script file used as the entrypoint for optimizations.": { + "category": "Error", + "code": 6064 + }, "Enables experimental support for ES7 decorators.": { "category": "Message", "code": 6065 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f8bb1e94da52f..74b60c83fe073 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1095,6 +1095,10 @@ namespace ts { options.target !== ScriptTarget.ES6) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower)); } + + if (options.optimizationEntrypoint && outFile && options.module) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_with_both_options_1_and_2, "optimizationEntrypoint", "module", "outFile")); + } } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 17156aee0f145..bc43286b713db 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2080,6 +2080,7 @@ namespace ts { experimentalAsyncFunctions?: boolean; emitDecoratorMetadata?: boolean; moduleResolution?: ModuleResolutionKind; + optimizationEntrypoint?: string; /* @internal */ stripInternal?: boolean; // Skip checking lib.d.ts to help speed up tests. From 719be34f5099eb2a348472ca1ece9308d63a8b63 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 9 Oct 2015 15:51:09 -0700 Subject: [PATCH 02/52] exported types can get flattened now --- src/compiler/checker.ts | 3 ++- src/compiler/declarationEmitter.ts | 31 +++++++++++++++++++++++++++--- src/compiler/program.ts | 2 +- src/compiler/types.ts | 1 + 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 228b1067bb01a..7cebdb86f8921 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14813,7 +14813,8 @@ namespace ts { collectLinkedAliases, getReferencedValueDeclaration, getTypeReferenceSerializationKind, - isOptionalParameter + isOptionalParameter, + getExportsOfModule: getExportsOfModuleAsArray }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d749ecabf7604..3578adfde1066 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -113,7 +113,22 @@ namespace ts { diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, compilerOptions.optimizationEntrypoint)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } - traverseEntrypoint(entrypoint); + let exports = collectExportedMembers(entrypoint); + let liftedDeclarations: Map = {}; + forEachValue(exports, collection => { // TODO: Resolve `import`ed types and rename(space) them + let realSourceFile = currentSourceFile; + currentSourceFile = collection.source; + forEach(collection.declarations, d => { + currentSourceFile = getSourceFileOfNode(d); + liftedDeclarations[d.symbol.name] = liftedDeclarations[d.symbol.name] || []; + liftedDeclarations[d.symbol.name].push(d); + let oldFlags = d.flags; + d.flags |= NodeFlags.Export; + emitModuleElement(d, /*isModuleElementVisible*/true); + d.flags = oldFlags; + }); + currentSourceFile = realSourceFile; + }); } else { // Emit references corresponding to this file let emittedReferencedFiles: SourceFile[] = []; @@ -179,8 +194,18 @@ namespace ts { referencePathsOutput, }; - function traverseEntrypoint(file: SourceFile) { - emitLines(file.statements) + type CollectedMembersMap = Map<{source: SourceFile, declarations: Declaration[]}>; + + function collectExportedMembers(file: SourceFile, result: CollectedMembersMap = {}): CollectedMembersMap { + let exportedMembers = resolver.getExportsOfModule(file.symbol); + forEach(exportedMembers, exported => { + forEach(exported.declarations, declaration => { + let subfile = getSourceFileOfNode(declaration); + result[subfile.symbol.name] = result[subfile.symbol.name] || {source: subfile, declarations: []}; + result[subfile.symbol.name].declarations.push(declaration); + }); + }); + return result; } function hasInternalAnnotation(range: CommentRange) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 74b60c83fe073..60720eb288e2f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1096,7 +1096,7 @@ namespace ts { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower)); } - if (options.optimizationEntrypoint && outFile && options.module) { + if (options.optimizationEntrypoint && !(outFile && options.module)) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_with_both_options_1_and_2, "optimizationEntrypoint", "module", "outFile")); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index eb78480a7567c..171d6b5d53387 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1601,6 +1601,7 @@ namespace ts { getReferencedValueDeclaration(reference: Identifier): Declaration; getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind; isOptionalParameter(node: ParameterDeclaration): boolean; + getExportsOfModule(symbol: Symbol): Symbol[]; } export const enum SymbolFlags { From 2ef2fc9cc7044a598d7b59201f8c7db28fe7962c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 9 Oct 2015 17:04:46 -0700 Subject: [PATCH 03/52] ehhh... getting there --- src/compiler/checker.ts | 3 +- src/compiler/declarationEmitter.ts | 77 +++++++++++++++++++++++------- src/compiler/types.ts | 1 + 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7cebdb86f8921..fddaabf1991b2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14814,7 +14814,8 @@ namespace ts { getReferencedValueDeclaration, getTypeReferenceSerializationKind, isOptionalParameter, - getExportsOfModule: getExportsOfModuleAsArray + getExportsOfModule: getExportsOfModuleAsArray, + getTypeOfSymbol }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 3578adfde1066..d885e6e4ffe91 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -113,15 +113,33 @@ namespace ts { diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, compilerOptions.optimizationEntrypoint)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } - let exports = collectExportedMembers(entrypoint); - let liftedDeclarations: Map = {}; - forEachValue(exports, collection => { // TODO: Resolve `import`ed types and rename(space) them + let types = collectExportedTypes(entrypoint); + let dependentTypes = collectDependentTypes(types); + + //TODO: Rename mapping in emitModuleElement + forEachValue(dependentTypes, type => { + let realSourceFile = currentSourceFile; + if (!type.symbol) { + return; + } + forEach(type.symbol.declarations, d => { + currentSourceFile = getSourceFileOfNode(d); + let oldFlags = d.flags; + if (oldFlags & NodeFlags.Export) { + d.flags -= NodeFlags.Export; + } + emitModuleElement(d, /*isModuleElementVisible*/true); + d.flags = oldFlags; + }); + currentSourceFile = realSourceFile; + }); + forEachValue(types, type => { let realSourceFile = currentSourceFile; - currentSourceFile = collection.source; - forEach(collection.declarations, d => { + if (!type.symbol) { + return; + } + forEach(type.symbol.declarations, d => { currentSourceFile = getSourceFileOfNode(d); - liftedDeclarations[d.symbol.name] = liftedDeclarations[d.symbol.name] || []; - liftedDeclarations[d.symbol.name].push(d); let oldFlags = d.flags; d.flags |= NodeFlags.Export; emitModuleElement(d, /*isModuleElementVisible*/true); @@ -196,16 +214,43 @@ namespace ts { type CollectedMembersMap = Map<{source: SourceFile, declarations: Declaration[]}>; - function collectExportedMembers(file: SourceFile, result: CollectedMembersMap = {}): CollectedMembersMap { + function collectExportedTypes(file: SourceFile): Map { let exportedMembers = resolver.getExportsOfModule(file.symbol); - forEach(exportedMembers, exported => { - forEach(exported.declarations, declaration => { - let subfile = getSourceFileOfNode(declaration); - result[subfile.symbol.name] = result[subfile.symbol.name] || {source: subfile, declarations: []}; - result[subfile.symbol.name].declarations.push(declaration); - }); - }); - return result; + return arrayToMap(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => (value.id + "")); + } + + function collectDependentTypes(exported: Map): Map { + let dependentTypes: Map = {}; + forEachValue(exported, type => visit(type)); + + return dependentTypes; + + function visit(type: Type): void { + let symbol = type.symbol; + if (!symbol) { + return; + } + if (symbol.flags & SymbolFlags.HasMembers) { + forEachValue(symbol.members, member => { // TODO: Check member visibility + let type = resolver.getTypeOfSymbol(member); + if (type.id in exported || type.id in dependentTypes) { + return; + } + dependentTypes[type.id] = type; + visit(type); + }); + } + if (symbol.flags & SymbolFlags.HasExports) { + forEachValue(symbol.exports, member => { + let type = resolver.getTypeOfSymbol(member); + if (type.id in exported || type.id in dependentTypes) { + return; + } + dependentTypes[type.id] = type; + visit(type); + }); + } + } } function hasInternalAnnotation(range: CommentRange) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 171d6b5d53387..a769cd5e0ff31 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1602,6 +1602,7 @@ namespace ts { getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind; isOptionalParameter(node: ParameterDeclaration): boolean; getExportsOfModule(symbol: Symbol): Symbol[]; + getTypeOfSymbol(symbol: Symbol): Type; } export const enum SymbolFlags { From cfcf24523798a4c77fa1814f4ef0d896daaf8676 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 9 Oct 2015 17:38:22 -0700 Subject: [PATCH 04/52] check member visibility for type visiting, use symbol id as key --- src/compiler/declarationEmitter.ts | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d885e6e4ffe91..24711834e63c5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -119,9 +119,6 @@ namespace ts { //TODO: Rename mapping in emitModuleElement forEachValue(dependentTypes, type => { let realSourceFile = currentSourceFile; - if (!type.symbol) { - return; - } forEach(type.symbol.declarations, d => { currentSourceFile = getSourceFileOfNode(d); let oldFlags = d.flags; @@ -135,9 +132,6 @@ namespace ts { }); forEachValue(types, type => { let realSourceFile = currentSourceFile; - if (!type.symbol) { - return; - } forEach(type.symbol.declarations, d => { currentSourceFile = getSourceFileOfNode(d); let oldFlags = d.flags; @@ -216,7 +210,7 @@ namespace ts { function collectExportedTypes(file: SourceFile): Map { let exportedMembers = resolver.getExportsOfModule(file.symbol); - return arrayToMap(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => (value.id + "")); + return arrayToMap(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => (value.symbol.id + "")); } function collectDependentTypes(exported: Map): Map { @@ -227,26 +221,34 @@ namespace ts { function visit(type: Type): void { let symbol = type.symbol; - if (!symbol) { - return; - } if (symbol.flags & SymbolFlags.HasMembers) { - forEachValue(symbol.members, member => { // TODO: Check member visibility + forEachValue(symbol.members, member => { + if (member.valueDeclaration && member.valueDeclaration.flags && member.valueDeclaration.flags & NodeFlags.Private) { + return; + } let type = resolver.getTypeOfSymbol(member); - if (type.id in exported || type.id in dependentTypes) { + if (!type.symbol) { + return; + } + let id = type.symbol.id; + if (id in exported || id in dependentTypes) { return; } - dependentTypes[type.id] = type; + dependentTypes[id] = type; visit(type); }); } if (symbol.flags & SymbolFlags.HasExports) { forEachValue(symbol.exports, member => { let type = resolver.getTypeOfSymbol(member); - if (type.id in exported || type.id in dependentTypes) { + if (!type.symbol) { + return; + } + let id = type.symbol.id; + if (id in exported || id in dependentTypes) { return; } - dependentTypes[type.id] = type; + dependentTypes[id] = type; visit(type); }); } From e57d37d8639791c177c7e392c4f904e8fb06d667 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 9 Oct 2015 18:38:38 -0700 Subject: [PATCH 05/52] Its messy, but type flattening it here --- src/compiler/checker.ts | 3 ++- src/compiler/declarationEmitter.ts | 32 +++++++++++++++++++++++++++--- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 5 +++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fddaabf1991b2..fc3469c4a0b20 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14815,7 +14815,8 @@ namespace ts { getTypeReferenceSerializationKind, isOptionalParameter, getExportsOfModule: getExportsOfModuleAsArray, - getTypeOfSymbol + getTypeOfSymbol, + resolveEntityName }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 24711834e63c5..1a926b84a109a 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -55,7 +55,8 @@ namespace ts { let errorNameNode: DeclarationName; let emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments; let emit = compilerOptions.stripInternal ? stripInternal : emitNode; - let noDeclare = !root; + let noDeclare = false; + let symbolGeneratedNameMap: Map = {}; let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[]; @@ -113,10 +114,29 @@ namespace ts { diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, compilerOptions.optimizationEntrypoint)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } + noDeclare = false; let types = collectExportedTypes(entrypoint); let dependentTypes = collectDependentTypes(types); + let symbolNameSet: Map = {}; + forEachValue(dependentTypes, type => { + let symbol = type.symbol; + if (symbol.name in symbolNameSet) { + let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; + symbolNameSet[symbol.name]++; + symbolGeneratedNameMap[symbol.id] = generatedName; + forEach(symbol.declarations, declaration => { + let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; + synthId.flags |= NodeFlags.Synthetic; + synthId.text = generatedName; + declaration.name = synthId; + }); + } + else { + symbolNameSet[symbol.name] = 1; + symbolGeneratedNameMap[symbol.id] = symbol.name; + } + }); - //TODO: Rename mapping in emitModuleElement forEachValue(dependentTypes, type => { let realSourceFile = currentSourceFile; forEach(type.symbol.declarations, d => { @@ -210,7 +230,7 @@ namespace ts { function collectExportedTypes(file: SourceFile): Map { let exportedMembers = resolver.getExportsOfModule(file.symbol); - return arrayToMap(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => (value.symbol.id + "")); + return arrayToMap(filter(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => !!value.symbol), value => (value.symbol.id + "")); } function collectDependentTypes(exported: Map): Map { @@ -496,6 +516,12 @@ namespace ts { } function writeEntityName(entityName: EntityName | Expression) { + // Lookup for renames + let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Namespace); + if (symbol && symbol.id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbol.id]); + return; + } if (entityName.kind === SyntaxKind.Identifier) { writeTextOfNode(currentSourceFile, entityName); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a769cd5e0ff31..6b5680bbdbed6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1603,6 +1603,7 @@ namespace ts { isOptionalParameter(node: ParameterDeclaration): boolean; getExportsOfModule(symbol: Symbol): Symbol[]; getTypeOfSymbol(symbol: Symbol): Type; + resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; } export const enum SymbolFlags { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c3d0aea6fc9ba..664798ef8d223 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -13,6 +13,7 @@ namespace ts { leadingCommentRanges?: CommentRange[]; trailingCommentRanges?: CommentRange[]; startsOnNewLine: boolean; + text?: string; } export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration { @@ -1757,6 +1758,10 @@ namespace ts { } function writeTextOfNode(sourceFile: SourceFile, node: Node) { + if (node.flags & NodeFlags.Synthetic) { + write((node as SynthesizedNode).text); + return; + } write(getSourceTextOfNodeFromSourceFile(sourceFile, node)); } From ecf64add3f9e32f36d8bd6ca2696737c1863b6c4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 10:20:10 -0700 Subject: [PATCH 06/52] add a test case --- .../cases/compiler/optimizationEntrypoint.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/cases/compiler/optimizationEntrypoint.ts diff --git a/tests/cases/compiler/optimizationEntrypoint.ts b/tests/cases/compiler/optimizationEntrypoint.ts new file mode 100644 index 0000000000000..fc949992d426a --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint.ts @@ -0,0 +1,25 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: index.ts + +// @filename: index.ts +export * from "./a"; + +// @filename: a.ts +import {Main as BaseMain} from "./b"; + +export class Main extends BaseMain { + memberc: string; +} + +// @filename: b.ts +import {Main as BaseMain} from "./c"; + +export class Main extends BaseMain { + member2: string; +} + +// @filename: c.ts +export class Main { + member1: string; +} \ No newline at end of file From 4516af1c7b189989a9163dee34eecff131ad0b3c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 12:02:35 -0700 Subject: [PATCH 07/52] Improve concatenated dts testing --- src/compiler/declarationEmitter.ts | 10 +++-- src/compiler/utilities.ts | 2 +- src/harness/compilerRunner.ts | 2 +- src/harness/harness.ts | 23 +++++++---- .../cases/compiler/optimizationEntrypoint.ts | 41 +++++++++++++++---- 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 1a926b84a109a..727dc91825c07 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -105,13 +105,14 @@ namespace ts { } else { if (compilerOptions.optimizationEntrypoint) { - let entrypoint = host.getSourceFile(compilerOptions.optimizationEntrypoint); + let path = compilerOptions.optimizationEntrypoint; + let entrypoint = host.getSourceFile(path); if (!entrypoint) { - diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, compilerOptions.optimizationEntrypoint)); + diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, path)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } if (!isExternalModule(entrypoint)) { - diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, compilerOptions.optimizationEntrypoint)); + diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, path)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } noDeclare = false; @@ -123,6 +124,7 @@ namespace ts { if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; symbolNameSet[symbol.name]++; + symbolNameSet[generatedName] = 1; symbolGeneratedNameMap[symbol.id] = generatedName; forEach(symbol.declarations, declaration => { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; @@ -517,7 +519,7 @@ namespace ts { function writeEntityName(entityName: EntityName | Expression) { // Lookup for renames - let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Namespace); + let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace); if (symbol && symbol.id in symbolGeneratedNameMap) { write(symbolGeneratedNameMap[symbol.id]); return; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 664798ef8d223..9d5a911c6c0d4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1758,7 +1758,7 @@ namespace ts { } function writeTextOfNode(sourceFile: SourceFile, node: Node) { - if (node.flags & NodeFlags.Synthetic) { + if (node && node.flags & NodeFlags.Synthetic) { write((node as SynthesizedNode).text); return; } diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 108c6f4518ae6..f006132afcd17 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -183,7 +183,7 @@ class CompilerBaselineRunner extends RunnerBase { jsCode += result.declFilesCode[i].code; } } - + options.optimizationEntrypoint = undefined; let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { harnessCompiler.setCompilerSettings(tcSettings); }, options); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index a37b647a12490..a34654eda6250 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1153,6 +1153,16 @@ namespace Harness { if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) { ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles)); ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles)); + let outFile = options.outFile || options.out; + if (outFile) { + let dTsFileName = ts.removeFileExtension(outFile) + ".d.ts"; + if (!findUnit(dTsFileName, declInputFiles) && !findUnit(dTsFileName, declOtherFiles)) { + let out = ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined); + if (out) { + declInputFiles.push({unitName: out.fileName, content: out.code}); + } + } + } this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; }, settingsCallback, options, currentDirectory); @@ -1175,8 +1185,7 @@ namespace Harness { assert(sourceFile, "Program has no source file with name '" + fileName + "'"); // Is this file going to be emitted separately let sourceFileName: string; - let outFile = options.outFile || options.out; - if (ts.isExternalModule(sourceFile) || !outFile) { + if (ts.isExternalModule(sourceFile)) { if (options.outDir) { let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram); sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), ""); @@ -1186,19 +1195,15 @@ namespace Harness { sourceFileName = sourceFile.fileName; } } - else { - // Goes to single --out file - sourceFileName = outFile; - } let dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts"; return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined); } + } - function findUnit(fileName: string, units: { unitName: string; content: string; }[]) { - return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined); - } + function findUnit(fileName: string, units: { unitName: string; content: string; }[]) { + return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined); } } } diff --git a/tests/cases/compiler/optimizationEntrypoint.ts b/tests/cases/compiler/optimizationEntrypoint.ts index fc949992d426a..d11cd86698216 100644 --- a/tests/cases/compiler/optimizationEntrypoint.ts +++ b/tests/cases/compiler/optimizationEntrypoint.ts @@ -1,25 +1,48 @@ // @module: amd // @outFile: bundled.js -// @optimizationEntrypoint: index.ts +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true -// @filename: index.ts +// @Filename: index.ts export * from "./a"; +export {Detail} from "./b"; -// @filename: a.ts -import {Main as BaseMain} from "./b"; +export interface Inner { + item4: number; +} + +// @Filename: a.ts +import {Main as BaseMain, Inner as Middle} from "./b"; export class Main extends BaseMain { - memberc: string; + memberc: Middle; } -// @filename: b.ts -import {Main as BaseMain} from "./c"; +export interface Inner { + item3: number; +} + +// @Filename: b.ts +import {Main as BaseMain, Inner as Innermost} from "./c"; export class Main extends BaseMain { - member2: string; + member2: Innermost; + details: Detail; +} + +export interface Inner { + item2: number; +} + +export interface Detail { + id: string; } -// @filename: c.ts +// @Filename: c.ts export class Main { member1: string; +} + +export interface Inner { + item: number; } \ No newline at end of file From 0267d0f8da11fd50da6fb9b501bce12d7ed97c96 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 12:29:09 -0700 Subject: [PATCH 08/52] old test behaviuor presrved --- src/harness/harness.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index a34654eda6250..77994303e6cd0 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1185,7 +1185,8 @@ namespace Harness { assert(sourceFile, "Program has no source file with name '" + fileName + "'"); // Is this file going to be emitted separately let sourceFileName: string; - if (ts.isExternalModule(sourceFile)) { + let outFile = options.outFile || options.out; + if (ts.isExternalModule(sourceFile) || !outFile) { if (options.outDir) { let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram); sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), ""); @@ -1195,6 +1196,9 @@ namespace Harness { sourceFileName = sourceFile.fileName; } } + else { + sourceFileName = outFile; + } let dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts"; From b2047f5ae56c92c6bff3b538701c99cee70e78ca Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 12:48:38 -0700 Subject: [PATCH 09/52] okay, now tests with optimization entrypoint run correctly --- src/harness/compilerRunner.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index f006132afcd17..8a3da33ff6314 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -185,6 +185,7 @@ class CompilerBaselineRunner extends RunnerBase { } options.optimizationEntrypoint = undefined; let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { + delete tcSettings["optimizationEntrypoint"]; harnessCompiler.setCompilerSettings(tcSettings); }, options); From 800124929c7deb5d849f9c29925f156c0274adbb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 15:34:59 -0700 Subject: [PATCH 10/52] _solid_ support for type flattening --- src/compiler/checker.ts | 12 +++++- src/compiler/declarationEmitter.ts | 59 +++++++++++++++++++----------- src/compiler/types.ts | 3 +- src/harness/typeWriter.ts | 16 ++++++-- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4226ec695f3a9..127772dcc2b1c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14839,7 +14839,17 @@ namespace ts { getTypeReferenceSerializationKind, isOptionalParameter, getExportsOfModule: getExportsOfModuleAsArray, - getTypeOfSymbol, + getDefiningTypeOfSymbol: (symbol: Symbol) => { + let valueType = getTypeOfSymbol(symbol); + if (valueType !== unknownType) { + return valueType; + } + let declaredType = getDeclaredTypeOfSymbol(symbol); + if (declaredType !== unknownType) { + return declaredType; + } + }, + getTypeAtLocation: getTypeOfNode, resolveEntityName }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 727dc91825c07..04e7123bc6394 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -119,6 +119,11 @@ namespace ts { let types = collectExportedTypes(entrypoint); let dependentTypes = collectDependentTypes(types); let symbolNameSet: Map = {}; + forEachValue(types, type => { + let symbol = type.symbol; + symbolNameSet[symbol.name] = 1; + symbolGeneratedNameMap[symbol.id] = symbol.name; + }); forEachValue(dependentTypes, type => { let symbol = type.symbol; if (symbol.name in symbolNameSet) { @@ -130,6 +135,7 @@ namespace ts { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; synthId.flags |= NodeFlags.Synthetic; synthId.text = generatedName; + synthId.parent = declaration; declaration.name = synthId; }); } @@ -228,11 +234,9 @@ namespace ts { referencePathsOutput, }; - type CollectedMembersMap = Map<{source: SourceFile, declarations: Declaration[]}>; - function collectExportedTypes(file: SourceFile): Map { let exportedMembers = resolver.getExportsOfModule(file.symbol); - return arrayToMap(filter(map(exportedMembers, exported => resolver.getTypeOfSymbol(exported)), value => !!value.symbol), value => (value.symbol.id + "")); + return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => !!value.symbol), value => (value.symbol.id + "")); } function collectDependentTypes(exported: Map): Map { @@ -248,33 +252,44 @@ namespace ts { if (member.valueDeclaration && member.valueDeclaration.flags && member.valueDeclaration.flags & NodeFlags.Private) { return; } - let type = resolver.getTypeOfSymbol(member); - if (!type.symbol) { - return; - } - let id = type.symbol.id; - if (id in exported || id in dependentTypes) { - return; - } - dependentTypes[id] = type; - visit(type); + inspectSymbol(member); }); } if (symbol.flags & SymbolFlags.HasExports) { forEachValue(symbol.exports, member => { - let type = resolver.getTypeOfSymbol(member); - if (!type.symbol) { - return; - } - let id = type.symbol.id; - if (id in exported || id in dependentTypes) { - return; + inspectSymbol(member); + }); + } + if (symbol.flags & SymbolFlags.Class || symbol.flags & SymbolFlags.Interface) { + forEach(symbol.declarations, declaration => { + if (isClassLike(declaration) || declaration.kind === SyntaxKind.InterfaceDeclaration) { + let clauses = (declaration as (ClassLikeDeclaration|InterfaceDeclaration)).heritageClauses; + forEach(clauses, clause => { + let types = clause.types; + forEach(types, typeExpression => { + let type = resolver.getTypeAtLocation(typeExpression); + if (type && type.symbol) { + inspectSymbol(type.symbol); + } + }); + }); } - dependentTypes[id] = type; - visit(type); }); } } + + function inspectSymbol(symbol: Symbol) { + let type = resolver.getDefiningTypeOfSymbol(symbol); + if (!type || !type.symbol) { + return; + } + let id = type.symbol.id; + if (id in exported || id in dependentTypes) { + return; + } + dependentTypes[id] = type; + visit(type); + } } function hasInternalAnnotation(range: CommentRange) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index da022868f38e7..de5fdc32eefbe 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1606,7 +1606,8 @@ namespace ts { getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind; isOptionalParameter(node: ParameterDeclaration): boolean; getExportsOfModule(symbol: Symbol): Symbol[]; - getTypeOfSymbol(symbol: Symbol): Type; + getDefiningTypeOfSymbol(symbol: Symbol): Type; + getTypeAtLocation(node: Node): Type; resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; } diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index 9db4fbcd41cac..f6761a721a8a3 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -37,9 +37,17 @@ class TypeWriterWalker { } private logTypeAndSymbol(node: ts.Node): void { - let actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); - let lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos); - let sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); + let sourceText: string; + let resultLine = 0; + if (node.flags & ts.NodeFlags.Synthetic) { + sourceText = (node as any).text; + } + else { + let actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); + let lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos); + resultLine = lineAndCharacter.line; + sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); + } // Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions // let type = this.checker.getTypeAtLocation(node); @@ -66,7 +74,7 @@ class TypeWriterWalker { } this.results.push({ - line: lineAndCharacter.line, + line: resultLine, syntaxKind: node.kind, sourceText: sourceText, type: typeString, From 7f218aba2304628a33dfef881864266a35d0ac90 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 15:55:08 -0700 Subject: [PATCH 11/52] export everything --- src/compiler/declarationEmitter.ts | 4 +- .../reference/optimizationEntrypoint.js | 193 ++++++++++++++++++ .../reference/optimizationEntrypoint.symbols | 82 ++++++++ .../reference/optimizationEntrypoint.types | 82 ++++++++ 4 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/optimizationEntrypoint.js create mode 100644 tests/baselines/reference/optimizationEntrypoint.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint.types diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 04e7123bc6394..19662f5a708f9 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -150,9 +150,7 @@ namespace ts { forEach(type.symbol.declarations, d => { currentSourceFile = getSourceFileOfNode(d); let oldFlags = d.flags; - if (oldFlags & NodeFlags.Export) { - d.flags -= NodeFlags.Export; - } + d.flags |= NodeFlags.Export; // TODO: Consider the implications of this emitModuleElement(d, /*isModuleElementVisible*/true); d.flags = oldFlags; }); diff --git a/tests/baselines/reference/optimizationEntrypoint.js b/tests/baselines/reference/optimizationEntrypoint.js new file mode 100644 index 0000000000000..5b7c4729c86f1 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint.js @@ -0,0 +1,193 @@ +//// [tests/cases/compiler/optimizationEntrypoint.ts] //// + +//// [index.ts] + +export * from "./a"; +export {Detail} from "./b"; + +export interface Inner { + item4: number; +} + +//// [a.ts] +import {Main as BaseMain, Inner as Middle} from "./b"; + +export class Main extends BaseMain { + memberc: Middle; +} + +export interface Inner { + item3: number; +} + +//// [b.ts] +import {Main as BaseMain, Inner as Innermost} from "./c"; + +export class Main extends BaseMain { + member2: Innermost; + details: Detail; +} + +export interface Inner { + item2: number; +} + +export interface Detail { + id: string; +} + +//// [c.ts] +export class Main { + member1: string; +} + +export interface Inner { + item: number; +} + +//// [c.js] +define(["require", "exports"], function (require, exports) { + var Main = (function () { + function Main() { + } + return Main; + })(); + exports.Main = Main; +}); +//// [b.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./c"], function (require, exports, c_1) { + var Main = (function (_super) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return Main; + })(c_1.Main); + exports.Main = Main; +}); +//// [a.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./b"], function (require, exports, b_1) { + var Main = (function (_super) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return Main; + })(b_1.Main); + exports.Main = Main; +}); +//// [index.js] +define(["require", "exports", "./a"], function (require, exports, a_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(a_1); +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/c", ["require", "exports"], function (require, exports) { + var Main = (function () { + function Main() { + } + return Main; + })(); + exports.Main = Main; +}); +define("tests/cases/compiler/b", ["require", "exports", "tests/cases/compiler/c"], function (require, exports, c_1) { + var Main = (function (_super) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return Main; + })(c_1.Main); + exports.Main = Main; +}); +define("tests/cases/compiler/a", ["require", "exports", "tests/cases/compiler/b"], function (require, exports, b_1) { + var Main = (function (_super) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return Main; + })(b_1.Main); + exports.Main = Main; +}); +define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/a"], function (require, exports, a_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(a_1); +}); + + +//// [c.d.ts] +export declare class Main { + member1: string; +} +export interface Inner { + item: number; +} +//// [b.d.ts] +import { Main as BaseMain, Inner as Innermost } from "./c"; +export declare class Main extends BaseMain { + member2: Innermost; + details: Detail; +} +export interface Inner { + item2: number; +} +export interface Detail { + id: string; +} +//// [a.d.ts] +import { Main as BaseMain, Inner as Middle } from "./b"; +export declare class Main extends BaseMain { + memberc: Middle; +} +export interface Inner { + item3: number; +} +//// [index.d.ts] +export * from "./a"; +export { Detail } from "./b"; +export interface Inner { + item4: number; +} +//// [bundled.d.ts] +export declare class Main_1 { + member1: string; +} +export interface Inner_1 { + item: number; +} +export declare class Main_2 extends Main_1 { + member2: Inner_1; + details: Detail; +} +export interface Inner_2 { + item2: number; +} +export interface Detail { + id: string; +} +export declare class Main extends Main_2 { + memberc: Inner_2; +} +export interface Inner { + item4: number; +} diff --git a/tests/baselines/reference/optimizationEntrypoint.symbols b/tests/baselines/reference/optimizationEntrypoint.symbols new file mode 100644 index 0000000000000..6441ea8b1f5df --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint.symbols @@ -0,0 +1,82 @@ +=== tests/cases/compiler/index.ts === + +export * from "./a"; +export {Detail} from "./b"; +>Detail : Symbol(Detail, Decl(index.ts, 2, 8)) + +export interface Inner { +>Inner : Symbol(Inner, Decl(index.ts, 2, 27)) + + item4: number; +>item4 : Symbol(item4, Decl(index.ts, 4, 24)) +} + +=== tests/cases/compiler/a.ts === +import {Main as BaseMain, Inner as Middle} from "./b"; +>Main : Symbol(BaseMain, Decl(a.ts, 0, 8)) +>BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) +>Inner : Symbol(Middle, Decl(a.ts, 0, 25)) +>Middle : Symbol(Middle, Decl(a.ts, 0, 25)) + +export class Main extends BaseMain { +>Main : Symbol(Main, Decl(a.ts, 0, 54)) +>BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) + + memberc: Middle; +>memberc : Symbol(memberc, Decl(a.ts, 2, 36)) +>Middle : Symbol(Middle, Decl(a.ts, 0, 25)) +} + +export interface Inner { +>Inner : Symbol(Inner, Decl(a.ts, 4, 1)) + + item3: number; +>item3 : Symbol(item3, Decl(a.ts, 6, 24)) +} + +=== tests/cases/compiler/b.ts === +import {Main as BaseMain, Inner as Innermost} from "./c"; +>Main : Symbol(BaseMain, Decl(b.ts, 0, 8)) +>BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) +>Inner : Symbol(Innermost, Decl(b.ts, 0, 25)) +>Innermost : Symbol(Innermost, Decl(b.ts, 0, 25)) +>Main_2 : Symbol((Missing), Decl(b.ts, 0, 57)) +>Inner_2 : Symbol((Missing), Decl(b.ts, 5, 1)) + +export class Main extends BaseMain { +>BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) + + member2: Innermost; +>member2 : Symbol(member2, Decl(b.ts, 2, 36)) +>Innermost : Symbol(Innermost, Decl(b.ts, 0, 25)) + + details: Detail; +>details : Symbol(details, Decl(b.ts, 3, 20)) +>Detail : Symbol(Detail, Decl(b.ts, 9, 1)) +} + +export interface Inner { + item2: number; +>item2 : Symbol(item2, Decl(b.ts, 7, 24)) +} + +export interface Detail { +>Detail : Symbol(Detail, Decl(b.ts, 9, 1)) + + id: string; +>id : Symbol(id, Decl(b.ts, 11, 25)) +} + +=== tests/cases/compiler/c.ts === +export class Main { +>Main_1 : Symbol((Missing), Decl(c.ts, 0, 0)) +>Inner_1 : Symbol((Missing), Decl(c.ts, 2, 1)) + + member1: string; +>member1 : Symbol(member1, Decl(c.ts, 0, 19)) +} + +export interface Inner { + item: number; +>item : Symbol(item, Decl(c.ts, 4, 24)) +} diff --git a/tests/baselines/reference/optimizationEntrypoint.types b/tests/baselines/reference/optimizationEntrypoint.types new file mode 100644 index 0000000000000..6b1c0637ad584 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint.types @@ -0,0 +1,82 @@ +=== tests/cases/compiler/index.ts === + +export * from "./a"; +export {Detail} from "./b"; +>Detail : any + +export interface Inner { +>Inner : Inner + + item4: number; +>item4 : number +} + +=== tests/cases/compiler/a.ts === +import {Main as BaseMain, Inner as Middle} from "./b"; +>Main : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Middle : any + +export class Main extends BaseMain { +>Main : Main +>BaseMain : BaseMain + + memberc: Middle; +>memberc : Middle +>Middle : Middle +} + +export interface Inner { +>Inner : Inner + + item3: number; +>item3 : number +} + +=== tests/cases/compiler/b.ts === +import {Main as BaseMain, Inner as Innermost} from "./c"; +>Main : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Innermost : any +>Main_2 : (Missing) +>Inner_2 : (Missing) + +export class Main extends BaseMain { +>BaseMain : BaseMain + + member2: Innermost; +>member2 : Innermost +>Innermost : Innermost + + details: Detail; +>details : Detail +>Detail : Detail +} + +export interface Inner { + item2: number; +>item2 : number +} + +export interface Detail { +>Detail : Detail + + id: string; +>id : string +} + +=== tests/cases/compiler/c.ts === +export class Main { +>Main_1 : (Missing) +>Inner_1 : (Missing) + + member1: string; +>member1 : string +} + +export interface Inner { + item: number; +>item : number +} From 9ac5fa832425975f5fdc642a249aeb9bca366482 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 16:57:27 -0700 Subject: [PATCH 12/52] fix lint, accept broken scoped baselines --- src/compiler/declarationEmitter.ts | 9 +- .../reference/optimizationEntrypoint.js | 82 ++++++++++++++++++- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 19662f5a708f9..ebbd1cc6b036b 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -150,7 +150,9 @@ namespace ts { forEach(type.symbol.declarations, d => { currentSourceFile = getSourceFileOfNode(d); let oldFlags = d.flags; - d.flags |= NodeFlags.Export; // TODO: Consider the implications of this + if (oldFlags & NodeFlags.Export) { + d.flags -= NodeFlags.Export; + } emitModuleElement(d, /*isModuleElementVisible*/true); d.flags = oldFlags; }); @@ -167,7 +169,8 @@ namespace ts { }); currentSourceFile = realSourceFile; }); - } else { + } + else { // Emit references corresponding to this file let emittedReferencedFiles: SourceFile[] = []; let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; @@ -275,7 +278,7 @@ namespace ts { }); } } - + function inspectSymbol(symbol: Symbol) { let type = resolver.getDefiningTypeOfSymbol(symbol); if (!type || !type.symbol) { diff --git a/tests/baselines/reference/optimizationEntrypoint.js b/tests/baselines/reference/optimizationEntrypoint.js index 5b7c4729c86f1..c859824db49e0 100644 --- a/tests/baselines/reference/optimizationEntrypoint.js +++ b/tests/baselines/reference/optimizationEntrypoint.js @@ -169,17 +169,17 @@ export interface Inner { item4: number; } //// [bundled.d.ts] -export declare class Main_1 { +declare class Main_1 { member1: string; } -export interface Inner_1 { +interface Inner_1 { item: number; } -export declare class Main_2 extends Main_1 { +declare class Main_2 extends Main_1 { member2: Inner_1; details: Detail; } -export interface Inner_2 { +interface Inner_2 { item2: number; } export interface Detail { @@ -191,3 +191,77 @@ export declare class Main extends Main_2 { export interface Inner { item4: number; } + + +//// [DtsFileErrors] + + +bundled.d.ts(17,35): error TS4020: Extends clause of exported class 'Main' has or is using private name 'Main_2'. +bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. + + +==== tests/cases/compiler/index.d.ts (0 errors) ==== + export * from "./a"; + export { Detail } from "./b"; + export interface Inner { + item4: number; + } + +==== tests/cases/compiler/a.d.ts (0 errors) ==== + import { Main as BaseMain, Inner as Middle } from "./b"; + export declare class Main extends BaseMain { + memberc: Middle; + } + export interface Inner { + item3: number; + } + +==== tests/cases/compiler/b.d.ts (0 errors) ==== + import { Main as BaseMain, Inner as Innermost } from "./c"; + export declare class Main extends BaseMain { + member2: Innermost; + details: Detail; + } + export interface Inner { + item2: number; + } + export interface Detail { + id: string; + } + +==== tests/cases/compiler/c.d.ts (0 errors) ==== + export declare class Main { + member1: string; + } + export interface Inner { + item: number; + } + +==== bundled.d.ts (2 errors) ==== + declare class Main_1 { + member1: string; + } + interface Inner_1 { + item: number; + } + declare class Main_2 extends Main_1 { + member2: Inner_1; + details: Detail; + } + interface Inner_2 { + item2: number; + } + export interface Detail { + id: string; + } + export declare class Main extends Main_2 { + ~~~~~~ +!!! error TS4020: Extends clause of exported class 'Main' has or is using private name 'Main_2'. + memberc: Inner_2; + ~~~~~~~ +!!! error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. + } + export interface Inner { + item4: number; + } + \ No newline at end of file From 7802f220d4e8341d14ff5f9f5ac3c507c90d0815 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Oct 2015 18:02:28 -0700 Subject: [PATCH 13/52] start attempting to handle default exports --- src/compiler/declarationEmitter.ts | 54 ++++++++++++++----- .../cases/compiler/optimizationEntrypoint.ts | 10 ++-- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index ebbd1cc6b036b..15edf3220801b 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -116,13 +116,41 @@ namespace ts { return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } noDeclare = false; - let types = collectExportedTypes(entrypoint); + + let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); + let types = collectExportedTypes(entrypoint, exportedMembers); let dependentTypes = collectDependentTypes(types); let symbolNameSet: Map = {}; - forEachValue(types, type => { + let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); + let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { + forEach(symbol.declarations, declaration => { + let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; + synthId.flags |= NodeFlags.Synthetic; + synthId.text = generatedName; + synthId.parent = declaration; + declaration.name = synthId; + }); + }; + let defaultExport: boolean; + forEach(aliasMapping, (type, index) => { + let exportedSymbol = exportedMembers[index]; let symbol = type.symbol; - symbolNameSet[symbol.name] = 1; - symbolGeneratedNameMap[symbol.id] = symbol.name; + if (symbol) { // use the name from the exported symbol, but the id from the internal one + if (symbol.name !== exportedSymbol.name) { + if (exportedSymbol.name === "default") { + let name = "default_1"; + createSynthIdentifiers(symbol, name); + symbolNameSet[name] = 1; + symbolGeneratedNameMap[symbol.id] = name; + defaultExport = true; + } + else { + createSynthIdentifiers(symbol, exportedSymbol.name); + symbolNameSet[exportedSymbol.name] = 1; + symbolGeneratedNameMap[symbol.id] = exportedSymbol.name; + } + } + } }); forEachValue(dependentTypes, type => { let symbol = type.symbol; @@ -131,13 +159,7 @@ namespace ts { symbolNameSet[symbol.name]++; symbolNameSet[generatedName] = 1; symbolGeneratedNameMap[symbol.id] = generatedName; - forEach(symbol.declarations, declaration => { - let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; - synthId.flags |= NodeFlags.Synthetic; - synthId.text = generatedName; - synthId.parent = declaration; - declaration.name = synthId; - }); + createSynthIdentifiers(symbol, generatedName); } else { symbolNameSet[symbol.name] = 1; @@ -164,11 +186,18 @@ namespace ts { currentSourceFile = getSourceFileOfNode(d); let oldFlags = d.flags; d.flags |= NodeFlags.Export; + if (oldFlags & NodeFlags.Default) { + d.flags -= NodeFlags.Default; + } emitModuleElement(d, /*isModuleElementVisible*/true); d.flags = oldFlags; }); currentSourceFile = realSourceFile; }); + if (defaultExport) { + writeLine(); + write("export default default_1;"); + } } else { // Emit references corresponding to this file @@ -235,8 +264,7 @@ namespace ts { referencePathsOutput, }; - function collectExportedTypes(file: SourceFile): Map { - let exportedMembers = resolver.getExportsOfModule(file.symbol); + function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => !!value.symbol), value => (value.symbol.id + "")); } diff --git a/tests/cases/compiler/optimizationEntrypoint.ts b/tests/cases/compiler/optimizationEntrypoint.ts index d11cd86698216..ceb6ada77aa8e 100644 --- a/tests/cases/compiler/optimizationEntrypoint.ts +++ b/tests/cases/compiler/optimizationEntrypoint.ts @@ -11,10 +11,14 @@ export interface Inner { item4: number; } +export {Main as BBaseMain, Main as default, Inner as Middle} from "./b"; +export {Main as CBaseMain, Inner as Innermost} from "./c"; +export {default as Main} from "./a"; + // @Filename: a.ts import {Main as BaseMain, Inner as Middle} from "./b"; -export class Main extends BaseMain { +export default class Main extends BaseMain { memberc: Middle; } @@ -25,7 +29,7 @@ export interface Inner { // @Filename: b.ts import {Main as BaseMain, Inner as Innermost} from "./c"; -export class Main extends BaseMain { +export default class Main extends BaseMain { member2: Innermost; details: Detail; } @@ -39,7 +43,7 @@ export interface Detail { } // @Filename: c.ts -export class Main { +export default class Main { member1: string; } From b8d3d9c21aeb532e3df3383c0bfaf143c72694cb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 13:35:50 -0700 Subject: [PATCH 14/52] handling defaults correctly, now for generics --- src/compiler/declarationEmitter.ts | 100 +++++++++++------- .../cases/compiler/optimizationEntrypoint.ts | 14 ++- .../cases/compiler/optimizationEntrypoint2.ts | 24 +++++ 3 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 tests/cases/compiler/optimizationEntrypoint2.ts diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 15edf3220801b..b227687a5f236 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -122,34 +122,48 @@ namespace ts { let dependentTypes = collectDependentTypes(types); let symbolNameSet: Map = {}; let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); + let undoSynthNodesStack: (() => void)[] = []; let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { forEach(symbol.declarations, declaration => { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; synthId.flags |= NodeFlags.Synthetic; synthId.text = generatedName; synthId.parent = declaration; + let oldName = declaration.name; + undoSynthNodesStack.push(() => declaration.name = oldName); declaration.name = synthId; }); }; - let defaultExport: boolean; + let createSymbolEntry = (name: string, id: number) => { + symbolNameSet[name] = 1; + symbolGeneratedNameMap[id] = name; + }; + let createDefaultExportAlias = (): string => undefined; forEach(aliasMapping, (type, index) => { + if (!type) { + return; + } let exportedSymbol = exportedMembers[index]; let symbol = type.symbol; if (symbol) { // use the name from the exported symbol, but the id from the internal one - if (symbol.name !== exportedSymbol.name) { - if (exportedSymbol.name === "default") { + if (exportedSymbol.name === "default") { + createDefaultExportAlias = () => { let name = "default_1"; + while (!!symbolNameSet[name]) { + name += "_1"; + } + createSymbolEntry(name, symbol.id); createSynthIdentifiers(symbol, name); - symbolNameSet[name] = 1; - symbolGeneratedNameMap[symbol.id] = name; - defaultExport = true; - } - else { - createSynthIdentifiers(symbol, exportedSymbol.name); - symbolNameSet[exportedSymbol.name] = 1; - symbolGeneratedNameMap[symbol.id] = exportedSymbol.name; + return name; } } + else if (symbol.name !== exportedSymbol.name) { + createSynthIdentifiers(symbol, exportedSymbol.name); + createSymbolEntry(exportedSymbol.name, symbol.id); + } + else { + createSymbolEntry(exportedSymbol.name, symbol.id); + } } }); forEachValue(dependentTypes, type => { @@ -157,47 +171,61 @@ namespace ts { if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; symbolNameSet[symbol.name]++; - symbolNameSet[generatedName] = 1; - symbolGeneratedNameMap[symbol.id] = generatedName; + createSymbolEntry(generatedName, symbol.id); createSynthIdentifiers(symbol, generatedName); } else { - symbolNameSet[symbol.name] = 1; - symbolGeneratedNameMap[symbol.id] = symbol.name; + createSymbolEntry(symbol.name, symbol.id); } }); - forEachValue(dependentTypes, type => { - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => { - currentSourceFile = getSourceFileOfNode(d); - let oldFlags = d.flags; + let alias = createDefaultExportAlias(); + let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { + currentSourceFile = getSourceFileOfNode(d); + if (isDeclarationFile(currentSourceFile)) { + return; + } + let oldFlags = d.flags; + if (shouldExport) { + d.flags |= NodeFlags.Export; + } + else { if (oldFlags & NodeFlags.Export) { d.flags -= NodeFlags.Export; } - emitModuleElement(d, /*isModuleElementVisible*/true); - d.flags = oldFlags; - }); + } + if (oldFlags & NodeFlags.Default) { + d.flags -= NodeFlags.Default; + } + switch (d.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.VariableStatement: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.ModuleDeclaration: + writeModuleElement(d); + default: + /// Declaration doesn't contribute to module exports (eg, TypeParameter) + } + d.flags = oldFlags; + } + forEachValue(dependentTypes, type => { + let realSourceFile = currentSourceFile; + forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); currentSourceFile = realSourceFile; }); forEachValue(types, type => { let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => { - currentSourceFile = getSourceFileOfNode(d); - let oldFlags = d.flags; - d.flags |= NodeFlags.Export; - if (oldFlags & NodeFlags.Default) { - d.flags -= NodeFlags.Default; - } - emitModuleElement(d, /*isModuleElementVisible*/true); - d.flags = oldFlags; - }); + forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); currentSourceFile = realSourceFile; }); - if (defaultExport) { + if (alias) { writeLine(); - write("export default default_1;"); + write(`export default ${alias};`); } + forEach(undoSynthNodesStack, undo => undo()); // So we don't ruin the tree } else { // Emit references corresponding to this file @@ -265,7 +293,7 @@ namespace ts { }; function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { - return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => !!value.symbol), value => (value.symbol.id + "")); + return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => value && !!value.symbol), value => (value.symbol.id + "")); } function collectDependentTypes(exported: Map): Map { diff --git a/tests/cases/compiler/optimizationEntrypoint.ts b/tests/cases/compiler/optimizationEntrypoint.ts index ceb6ada77aa8e..fe7f68457c213 100644 --- a/tests/cases/compiler/optimizationEntrypoint.ts +++ b/tests/cases/compiler/optimizationEntrypoint.ts @@ -11,12 +11,16 @@ export interface Inner { item4: number; } -export {Main as BBaseMain, Main as default, Inner as Middle} from "./b"; -export {Main as CBaseMain, Inner as Innermost} from "./c"; -export {default as Main} from "./a"; +export interface default_1 { // make sure generated names don't clash + number: number; +} + +export {default as BBaseMain, Inner as Middle} from "./b"; +export {default as CBaseMain, Inner as Innermost} from "./c"; +export {default} from "./a"; // @Filename: a.ts -import {Main as BaseMain, Inner as Middle} from "./b"; +import {default as BaseMain, Inner as Middle} from "./b"; export default class Main extends BaseMain { memberc: Middle; @@ -27,7 +31,7 @@ export interface Inner { } // @Filename: b.ts -import {Main as BaseMain, Inner as Innermost} from "./c"; +import {default as BaseMain, Inner as Innermost} from "./c"; export default class Main extends BaseMain { member2: Innermost; diff --git a/tests/cases/compiler/optimizationEntrypoint2.ts b/tests/cases/compiler/optimizationEntrypoint2.ts new file mode 100644 index 0000000000000..1f66acf87d640 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint2.ts @@ -0,0 +1,24 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true + +// @Filename: index.ts +import * as t from "./foo"; + +export = t; + +// @Filename: foo.ts +export * from "./bar"; + +export class Foo extends Array { + self: this; +} + +// @Filename: bar.ts + +import {Foo} from "./foo"; + +export class Bar extends Foo> { + primary: Foo; +} \ No newline at end of file From 2d70da1f2c150304cb1b3a977a53bb611685b2de Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 13:43:25 -0700 Subject: [PATCH 15/52] refactor a bit --- src/compiler/declarationEmitter.ts | 316 +++++++++++++++-------------- 1 file changed, 161 insertions(+), 155 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index b227687a5f236..d02cb514f03a5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -117,115 +117,7 @@ namespace ts { } noDeclare = false; - let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); - let types = collectExportedTypes(entrypoint, exportedMembers); - let dependentTypes = collectDependentTypes(types); - let symbolNameSet: Map = {}; - let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); - let undoSynthNodesStack: (() => void)[] = []; - let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { - forEach(symbol.declarations, declaration => { - let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; - synthId.flags |= NodeFlags.Synthetic; - synthId.text = generatedName; - synthId.parent = declaration; - let oldName = declaration.name; - undoSynthNodesStack.push(() => declaration.name = oldName); - declaration.name = synthId; - }); - }; - let createSymbolEntry = (name: string, id: number) => { - symbolNameSet[name] = 1; - symbolGeneratedNameMap[id] = name; - }; - let createDefaultExportAlias = (): string => undefined; - forEach(aliasMapping, (type, index) => { - if (!type) { - return; - } - let exportedSymbol = exportedMembers[index]; - let symbol = type.symbol; - if (symbol) { // use the name from the exported symbol, but the id from the internal one - if (exportedSymbol.name === "default") { - createDefaultExportAlias = () => { - let name = "default_1"; - while (!!symbolNameSet[name]) { - name += "_1"; - } - createSymbolEntry(name, symbol.id); - createSynthIdentifiers(symbol, name); - return name; - } - } - else if (symbol.name !== exportedSymbol.name) { - createSynthIdentifiers(symbol, exportedSymbol.name); - createSymbolEntry(exportedSymbol.name, symbol.id); - } - else { - createSymbolEntry(exportedSymbol.name, symbol.id); - } - } - }); - forEachValue(dependentTypes, type => { - let symbol = type.symbol; - if (symbol.name in symbolNameSet) { - let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; - symbolNameSet[symbol.name]++; - createSymbolEntry(generatedName, symbol.id); - createSynthIdentifiers(symbol, generatedName); - } - else { - createSymbolEntry(symbol.name, symbol.id); - } - }); - - let alias = createDefaultExportAlias(); - let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { - currentSourceFile = getSourceFileOfNode(d); - if (isDeclarationFile(currentSourceFile)) { - return; - } - let oldFlags = d.flags; - if (shouldExport) { - d.flags |= NodeFlags.Export; - } - else { - if (oldFlags & NodeFlags.Export) { - d.flags -= NodeFlags.Export; - } - } - if (oldFlags & NodeFlags.Default) { - d.flags -= NodeFlags.Default; - } - switch (d.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - writeModuleElement(d); - default: - /// Declaration doesn't contribute to module exports (eg, TypeParameter) - } - d.flags = oldFlags; - } - forEachValue(dependentTypes, type => { - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); - currentSourceFile = realSourceFile; - }); - forEachValue(types, type => { - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); - currentSourceFile = realSourceFile; - }); - if (alias) { - writeLine(); - write(`export default ${alias};`); - } - forEach(undoSynthNodesStack, undo => undo()); // So we don't ruin the tree + emitFlattenedTypeDefinitions(entrypoint); } else { // Emit references corresponding to this file @@ -291,61 +183,175 @@ namespace ts { synchronousDeclarationOutput: writer.getText(), referencePathsOutput, }; - - function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { - return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => value && !!value.symbol), value => (value.symbol.id + "")); - } - - function collectDependentTypes(exported: Map): Map { - let dependentTypes: Map = {}; - forEachValue(exported, type => visit(type)); - - return dependentTypes; - - function visit(type: Type): void { + + function emitFlattenedTypeDefinitions(entrypoint: SourceFile) { + let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); + let types = collectExportedTypes(entrypoint, exportedMembers); + let dependentTypes = collectDependentTypes(types); + let symbolNameSet: Map = {}; + let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); + let undoSynthNodesStack: (() => void)[] = []; + let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { + forEach(symbol.declarations, declaration => { + let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; + synthId.flags |= NodeFlags.Synthetic; + synthId.text = generatedName; + synthId.parent = declaration; + let oldName = declaration.name; + undoSynthNodesStack.push(() => declaration.name = oldName); + declaration.name = synthId; + }); + }; + let createSymbolEntry = (name: string, id: number) => { + symbolNameSet[name] = 1; + symbolGeneratedNameMap[id] = name; + }; + let createDefaultExportAlias = (): string => undefined; + forEach(aliasMapping, (type, index) => { + if (!type) { + return; + } + let exportedSymbol = exportedMembers[index]; let symbol = type.symbol; - if (symbol.flags & SymbolFlags.HasMembers) { - forEachValue(symbol.members, member => { - if (member.valueDeclaration && member.valueDeclaration.flags && member.valueDeclaration.flags & NodeFlags.Private) { - return; + if (symbol) { // use the name from the exported symbol, but the id from the internal one + if (exportedSymbol.name === "default") { + createDefaultExportAlias = () => { + let name = "default_1"; + while (!!symbolNameSet[name]) { + name += "_1"; + } + createSymbolEntry(name, symbol.id); + createSynthIdentifiers(symbol, name); + return name; } - inspectSymbol(member); - }); + } + else if (symbol.name !== exportedSymbol.name) { + createSynthIdentifiers(symbol, exportedSymbol.name); + createSymbolEntry(exportedSymbol.name, symbol.id); + } + else { + createSymbolEntry(exportedSymbol.name, symbol.id); + } } - if (symbol.flags & SymbolFlags.HasExports) { - forEachValue(symbol.exports, member => { - inspectSymbol(member); - }); + }); + forEachValue(dependentTypes, type => { + let symbol = type.symbol; + if (symbol.name in symbolNameSet) { + let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; + symbolNameSet[symbol.name]++; + createSymbolEntry(generatedName, symbol.id); + createSynthIdentifiers(symbol, generatedName); } - if (symbol.flags & SymbolFlags.Class || symbol.flags & SymbolFlags.Interface) { - forEach(symbol.declarations, declaration => { - if (isClassLike(declaration) || declaration.kind === SyntaxKind.InterfaceDeclaration) { - let clauses = (declaration as (ClassLikeDeclaration|InterfaceDeclaration)).heritageClauses; - forEach(clauses, clause => { - let types = clause.types; - forEach(types, typeExpression => { - let type = resolver.getTypeAtLocation(typeExpression); - if (type && type.symbol) { - inspectSymbol(type.symbol); - } - }); - }); - } - }); + else { + createSymbolEntry(symbol.name, symbol.id); } - } + }); - function inspectSymbol(symbol: Symbol) { - let type = resolver.getDefiningTypeOfSymbol(symbol); - if (!type || !type.symbol) { + let alias = createDefaultExportAlias(); + let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { + currentSourceFile = getSourceFileOfNode(d); + if (isDeclarationFile(currentSourceFile)) { return; } - let id = type.symbol.id; - if (id in exported || id in dependentTypes) { - return; + let oldFlags = d.flags; + if (shouldExport) { + d.flags |= NodeFlags.Export; + } + else { + if (oldFlags & NodeFlags.Export) { + d.flags -= NodeFlags.Export; + } + } + if (oldFlags & NodeFlags.Default) { + d.flags -= NodeFlags.Default; + } + switch (d.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.VariableStatement: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.ModuleDeclaration: + writeModuleElement(d); + default: + /// Declaration doesn't contribute to module exports (eg, TypeParameter) + } + d.flags = oldFlags; + } + forEachValue(dependentTypes, type => { + let realSourceFile = currentSourceFile; + forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); + currentSourceFile = realSourceFile; + }); + forEachValue(types, type => { + let realSourceFile = currentSourceFile; + forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); + currentSourceFile = realSourceFile; + }); + if (alias) { + writeLine(); + write(`export default ${alias};`); + } + forEach(undoSynthNodesStack, undo => undo()); // So we don't ruin the tree + + return; + + function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { + return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => value && !!value.symbol), value => (value.symbol.id + "")); + } + + function collectDependentTypes(exported: Map): Map { + let dependentTypes: Map = {}; + forEachValue(exported, type => visit(type)); + + return dependentTypes; + + function visit(type: Type): void { + let symbol = type.symbol; + if (symbol.flags & SymbolFlags.HasMembers) { + forEachValue(symbol.members, member => { + if (member.valueDeclaration && member.valueDeclaration.flags && member.valueDeclaration.flags & NodeFlags.Private) { + return; + } + inspectSymbol(member); + }); + } + if (symbol.flags & SymbolFlags.HasExports) { + forEachValue(symbol.exports, member => { + inspectSymbol(member); + }); + } + if (symbol.flags & SymbolFlags.Class || symbol.flags & SymbolFlags.Interface) { + forEach(symbol.declarations, declaration => { + if (isClassLike(declaration) || declaration.kind === SyntaxKind.InterfaceDeclaration) { + let clauses = (declaration as (ClassLikeDeclaration|InterfaceDeclaration)).heritageClauses; + forEach(clauses, clause => { + let types = clause.types; + forEach(types, typeExpression => { + let type = resolver.getTypeAtLocation(typeExpression); + if (type && type.symbol) { + inspectSymbol(type.symbol); + } + }); + }); + } + }); + } + } + + function inspectSymbol(symbol: Symbol) { + let type = resolver.getDefiningTypeOfSymbol(symbol); + if (!type || !type.symbol) { + return; + } + let id = type.symbol.id; + if (id in exported || id in dependentTypes) { + return; + } + dependentTypes[id] = type; + visit(type); } - dependentTypes[id] = type; - visit(type); } } From 483c7d92eebb22870a0cf49f08e9ea3aa367e9d1 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 14:46:02 -0700 Subject: [PATCH 16/52] handle export assignments --- src/compiler/declarationEmitter.ts | 34 ++++++++++++++----- ...trypoint.ts => optimizationEntrypoint1.ts} | 0 .../cases/compiler/optimizationEntrypoint3.ts | 19 +++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) rename tests/cases/compiler/{optimizationEntrypoint.ts => optimizationEntrypoint1.ts} (100%) create mode 100644 tests/cases/compiler/optimizationEntrypoint3.ts diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d02cb514f03a5..4cb6a5931f940 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -184,7 +184,7 @@ namespace ts { referencePathsOutput, }; - function emitFlattenedTypeDefinitions(entrypoint: SourceFile) { + function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); let types = collectExportedTypes(entrypoint, exportedMembers); let dependentTypes = collectDependentTypes(types); @@ -207,6 +207,8 @@ namespace ts { symbolGeneratedNameMap[id] = name; }; let createDefaultExportAlias = (): string => undefined; + let reentry: SourceFile; + let exportEquals: Type; forEach(aliasMapping, (type, index) => { if (!type) { return; @@ -214,8 +216,14 @@ namespace ts { let exportedSymbol = exportedMembers[index]; let symbol = type.symbol; if (symbol) { // use the name from the exported symbol, but the id from the internal one - if (exportedSymbol.name === "default") { - createDefaultExportAlias = () => { + if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { // export= import case (effectively entrypoint redirection) + reentry = symbol.valueDeclaration as SourceFile; + } + else if (exportedSymbol.name === "export=") { // Special case all the things + exportEquals = type; + } + else if (exportedSymbol.name === "default") { + createDefaultExportAlias = () => { // delay making the alias until after all exported names are collected let name = "default_1"; while (!!symbolNameSet[name]) { name += "_1"; @@ -234,6 +242,9 @@ namespace ts { } } }); + if (reentry) { + return emitFlattenedTypeDefinitions(reentry); + } forEachValue(dependentTypes, type => { let symbol = type.symbol; if (symbol.name in symbolNameSet) { @@ -284,11 +295,18 @@ namespace ts { forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); currentSourceFile = realSourceFile; }); - forEachValue(types, type => { - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); - currentSourceFile = realSourceFile; - }); + if (exportEquals) { + forEach(exportEquals.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); + writeLine(); + write(`export = ${exportEquals.symbol.name};`); + } + else { + forEachValue(types, type => { + let realSourceFile = currentSourceFile; + forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); + currentSourceFile = realSourceFile; + }); + } if (alias) { writeLine(); write(`export default ${alias};`); diff --git a/tests/cases/compiler/optimizationEntrypoint.ts b/tests/cases/compiler/optimizationEntrypoint1.ts similarity index 100% rename from tests/cases/compiler/optimizationEntrypoint.ts rename to tests/cases/compiler/optimizationEntrypoint1.ts diff --git a/tests/cases/compiler/optimizationEntrypoint3.ts b/tests/cases/compiler/optimizationEntrypoint3.ts new file mode 100644 index 0000000000000..c224a141d04bd --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint3.ts @@ -0,0 +1,19 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true + +// @Filename: index.ts +import {Foo} from "./foo"; + +class Bar extends Foo> { + primary: Foo; +} + +export = Bar; + +// @Filename: foo.ts + +export class Foo extends Array { + self: this; +} From 68ae4b3d5e0f675209537fa1cdb1fcbac00ed53a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 15:44:18 -0700 Subject: [PATCH 17/52] more tests --- .../cases/compiler/optimizationEntrypoint4.ts | 19 +++++++++++ .../cases/compiler/optimizationEntrypoint5.ts | 33 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/cases/compiler/optimizationEntrypoint4.ts create mode 100644 tests/cases/compiler/optimizationEntrypoint5.ts diff --git a/tests/cases/compiler/optimizationEntrypoint4.ts b/tests/cases/compiler/optimizationEntrypoint4.ts new file mode 100644 index 0000000000000..0a6c722f1d5a9 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint4.ts @@ -0,0 +1,19 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true + +// @Filename: index.ts +import Foo = require("./foo"); + +export class Bar { + field2: typeof Foo.field; +} + +// @Filename: foo.ts + +class Foo { + static field: {name: string} +} + +export = Foo; \ No newline at end of file diff --git a/tests/cases/compiler/optimizationEntrypoint5.ts b/tests/cases/compiler/optimizationEntrypoint5.ts new file mode 100644 index 0000000000000..ccab110225402 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint5.ts @@ -0,0 +1,33 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true + +// @Filename: index.ts +import * as foo from "./foo"; +export * from "./foo"; + +export class Main { + a: foo.A; + b: [foo.B]; + c: (foo.C); + d: foo.D[]; + e: foo.E | foo.E2; + f: foo.F & foo.F2; + g: foo.GAlias; + h: {item: foo.H}; +} + +// @Filename: foo.ts + +export class A {} +export class B {} +export class C {} +export class D {} +export class E {} +export class F {} +export class E2 {} +export class F2 {} +export class G {} +export type GAlias = G; +export class H {} From 362599023cfe07e014e1bbd7335c36c459cf0996 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 18:10:21 -0700 Subject: [PATCH 18/52] Type walk is pretty beatuiful now, still not exporting aliases right, though --- src/compiler/checker.ts | 138 ++++++++++++++++++++++++++++- src/compiler/declarationEmitter.ts | 59 ++++-------- src/compiler/types.ts | 8 ++ 3 files changed, 159 insertions(+), 46 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 127772dcc2b1c..85c2e03957401 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -94,7 +94,8 @@ namespace ts { getJsxElementAttributesType, getJsxIntrinsicTagNames, - isOptionalParameter + isOptionalParameter, + getTypeWalker }; let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); @@ -2022,6 +2023,138 @@ namespace ts { }); } + function getTypeWalker(accept: (type: Type) => boolean = () => true): TypeWalker { + let visited: Type[] = []; + let visitedSymbols: Symbol[] = []; + function visitType(type: Type): void { + if (contains(visited, type)) { + return; + } + visited.push(type); + if (!accept(type)) { + return; + } + + // Visit the type's related types, if any + if (type.flags & TypeFlags.Reference) { + visitTypeReference(type as TypeReference); + } + else if (type.flags & TypeFlags.TypeParameter) { + visitTypeParameter(type as TypeParameter); + } + else if (type.flags & TypeFlags.Tuple) { + visitTupleType(type as TupleType); + } + else if (type.flags & TypeFlags.UnionOrIntersection) { + visitUnionOrIntersectionType(type as UnionOrIntersectionType); + } + else if (type.flags & (TypeFlags.Class | TypeFlags.Interface)) { + visitInterfaceType(type as InterfaceType); + } + else if (type.flags & TypeFlags.Anonymous) { + visitObjectType(type as ObjectType); + } + } + + function visitTypeList(types: Type[]): void { + for (let i = 0; i < types.length; i++) { + visitType(types[i]); + } + } + + function visitTypeReference(type: TypeReference): void { + visitType(type.target); + let typeArguments: Type[] = type.typeArguments || emptyArray; + if (type.target === globalArrayType) { // Shortcut + visitType(typeArguments[0]); + } + else { + visitTypeList(typeArguments); + } + } + + function visitTypeParameter(type: TypeParameter): void { + visitType(type.constraint); + } + + function visitTupleType(type: TupleType): void { + visitTypeList(type.elementTypes); + } + + function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void { + visitTypeList(type.types); + } + + function visitSignature(signature: Signature): void { + visitType(signature.typePredicate.type); + visitTypeList(signature.typeParameters); + } + + function visitInterfaceType(interfaceT: InterfaceType): void { + visitObjectType(interfaceT); + if (interfaceT.typeParameters) { + visitTypeList(interfaceT.typeParameters); + } + if (interfaceT.resolvedBaseTypes) { + visitTypeList(interfaceT.resolvedBaseTypes); + } + } + + function visitObjectType(type: ObjectType): void { + let resolved = resolveStructuredTypeMembers(type); + + if (resolved.stringIndexType) { + visitType(resolved.stringIndexType); + } + if (resolved.numberIndexType) { + visitType(resolved.numberIndexType); + } + for (let signature of resolved.callSignatures) { + visitSignature(signature); + } + for (let signature of resolved.constructSignatures) { + visitSignature(signature); + } + for (let p of resolved.properties) { + visitTypeFromSymbol(p); + } + } + + function visitTypeFromSymbol(symbol: Symbol): void { + if (contains(visitedSymbols, symbol)) { + return; + } + visitedSymbols.push(symbol); + let t = getTypeOfSymbol(symbol); + visitType(t); // Should handle members on classes and such + if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { + let signatures = getSignaturesOfType(t, SignatureKind.Call); + for (let signature of signatures) { + visitSignature(signature); + } + } + if (symbol.flags & SymbolFlags.Class) { + let signatures = getSignaturesOfType(t, SignatureKind.Construct); + for (let signature of signatures) { + visitSignature(signature); + } + } + if (symbol.flags & SymbolFlags.HasExports) { + forEachValue(symbol.exports, visitTypeFromSymbol); + } + } + + return { + visitType, + visitTypeFromSymbol, + reset: (newCallback: (type: Type) => boolean = () => true) => { + accept = newCallback; + visited = []; + visitedSymbols = []; + } + }; + } + function isDeclarationVisible(node: Declaration): boolean { function getContainingExternalModule(node: Node) { for (; node; node = node.parent) { @@ -14850,7 +14983,8 @@ namespace ts { } }, getTypeAtLocation: getTypeOfNode, - resolveEntityName + resolveEntityName, + getTypeWalker }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 4cb6a5931f940..b010770b8f109 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -321,54 +321,25 @@ namespace ts { function collectDependentTypes(exported: Map): Map { let dependentTypes: Map = {}; - forEachValue(exported, type => visit(type)); - + let walker = resolver.getTypeWalker(inspectType); + forEachValue(exported, type => walker.visitType(type)); + return dependentTypes; - - function visit(type: Type): void { + + function inspectType(type: Type): boolean { let symbol = type.symbol; - if (symbol.flags & SymbolFlags.HasMembers) { - forEachValue(symbol.members, member => { - if (member.valueDeclaration && member.valueDeclaration.flags && member.valueDeclaration.flags & NodeFlags.Private) { - return; - } - inspectSymbol(member); - }); - } - if (symbol.flags & SymbolFlags.HasExports) { - forEachValue(symbol.exports, member => { - inspectSymbol(member); - }); - } - if (symbol.flags & SymbolFlags.Class || symbol.flags & SymbolFlags.Interface) { - forEach(symbol.declarations, declaration => { - if (isClassLike(declaration) || declaration.kind === SyntaxKind.InterfaceDeclaration) { - let clauses = (declaration as (ClassLikeDeclaration|InterfaceDeclaration)).heritageClauses; - forEach(clauses, clause => { - let types = clause.types; - forEach(types, typeExpression => { - let type = resolver.getTypeAtLocation(typeExpression); - if (type && type.symbol) { - inspectSymbol(type.symbol); - } - }); - }); + if (symbol) { + if (symbol.valueDeclaration && symbol.valueDeclaration.flags && symbol.valueDeclaration.flags & NodeFlags.Private) { + return false; + } else { + let id = symbol.id; + if (id in exported || id in dependentTypes) { + return false; } - }); - } - } - - function inspectSymbol(symbol: Symbol) { - let type = resolver.getDefiningTypeOfSymbol(symbol); - if (!type || !type.symbol) { - return; - } - let id = type.symbol.id; - if (id in exported || id in dependentTypes) { - return; + dependentTypes[id] = type; + } } - dependentTypes[id] = type; - visit(type); + return true; } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index de5fdc32eefbe..8aeeea3f1b678 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1434,6 +1434,7 @@ namespace ts { getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): ObjectType[]; getReturnTypeOfSignature(signature: Signature): Type; + getTypeWalker(accept?: (type: Type) => boolean): TypeWalker; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -1609,6 +1610,13 @@ namespace ts { getDefiningTypeOfSymbol(symbol: Symbol): Type; getTypeAtLocation(node: Node): Type; resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; + getTypeWalker(accept?: (type: Type) => boolean): TypeWalker; + } + + export interface TypeWalker { + visitType(type: Type): void; + visitTypeFromSymbol(symbol: Symbol): void; + reset(accept?: (type: Type) => boolean): void; } export const enum SymbolFlags { From 8a04d40a77151e9087820a45bd91bca18f99c893 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 19:19:47 -0700 Subject: [PATCH 19/52] i now know whye everyone hates self referential type aliases --- src/compiler/checker.ts | 22 ++++++++++------ src/compiler/declarationEmitter.ts | 25 ++++++++++++++----- .../cases/compiler/optimizationEntrypoint5.ts | 9 ++++++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 85c2e03957401..eb192e03606bb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2057,6 +2057,9 @@ namespace ts { } function visitTypeList(types: Type[]): void { + if (!types) { + return; + } for (let i = 0; i < types.length; i++) { visitType(types[i]); } @@ -2086,8 +2089,12 @@ namespace ts { } function visitSignature(signature: Signature): void { - visitType(signature.typePredicate.type); + if (signature.typePredicate) { + visitType(signature.typePredicate.type); + } visitTypeList(signature.typeParameters); + visitType(getReturnTypeOfSignature(signature)); + visitType(getRestTypeOfSignature(signature)); } function visitInterfaceType(interfaceT: InterfaceType): void { @@ -2095,9 +2102,8 @@ namespace ts { if (interfaceT.typeParameters) { visitTypeList(interfaceT.typeParameters); } - if (interfaceT.resolvedBaseTypes) { - visitTypeList(interfaceT.resolvedBaseTypes); - } + visitTypeList(getBaseTypes(interfaceT)); + visitType(interfaceT.thisType); } function visitObjectType(type: ObjectType): void { @@ -14973,14 +14979,14 @@ namespace ts { isOptionalParameter, getExportsOfModule: getExportsOfModuleAsArray, getDefiningTypeOfSymbol: (symbol: Symbol) => { - let valueType = getTypeOfSymbol(symbol); - if (valueType !== unknownType) { - return valueType; - } let declaredType = getDeclaredTypeOfSymbol(symbol); if (declaredType !== unknownType) { return declaredType; } + let valueType = getTypeOfSymbol(symbol); + if (valueType !== unknownType) { + return valueType; + } }, getTypeAtLocation: getTypeOfNode, resolveEntityName, diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index b010770b8f109..f202b34d56bf9 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -185,12 +185,12 @@ namespace ts { }; function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { + let undoActions: (() => void)[] = []; + let symbolNameSet: Map = {}; let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); let types = collectExportedTypes(entrypoint, exportedMembers); let dependentTypes = collectDependentTypes(types); - let symbolNameSet: Map = {}; let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); - let undoSynthNodesStack: (() => void)[] = []; let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { forEach(symbol.declarations, declaration => { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; @@ -198,7 +198,7 @@ namespace ts { synthId.text = generatedName; synthId.parent = declaration; let oldName = declaration.name; - undoSynthNodesStack.push(() => declaration.name = oldName); + undoActions.push(() => declaration.name = oldName); declaration.name = synthId; }); }; @@ -277,11 +277,11 @@ namespace ts { d.flags -= NodeFlags.Default; } switch (d.kind) { + case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.FunctionDeclaration: case SyntaxKind.VariableStatement: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.ClassDeclaration: - case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.ModuleDeclaration: writeModuleElement(d); @@ -290,7 +290,9 @@ namespace ts { } d.flags = oldFlags; } + let privateTypes = 0; forEachValue(dependentTypes, type => { + privateTypes++; let realSourceFile = currentSourceFile; forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); currentSourceFile = realSourceFile; @@ -311,12 +313,23 @@ namespace ts { writeLine(); write(`export default ${alias};`); } - forEach(undoSynthNodesStack, undo => undo()); // So we don't ruin the tree + if (privateTypes && !exportEquals) { + writeLine(); + write("export {};"); + } + forEach(undoActions, undo => undo()); // So we don't ruin the tree return; function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { - return arrayToMap(filter(map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)), value => value && !!value.symbol), value => (value.symbol.id + "")); + return arrayToMap(filter(map(exportedMembers, exported => { + let type = resolver.getDefiningTypeOfSymbol(exported); + if (type && exported.flags & SymbolFlags.TypeAlias) { + let oldSymbol = type.symbol; + type.symbol = exported; // Preserves type aliases if they're exported + } + return type; + }), value => value && !!value.symbol), value => (value.symbol.id + "")); } function collectDependentTypes(exported: Map): Map { diff --git a/tests/cases/compiler/optimizationEntrypoint5.ts b/tests/cases/compiler/optimizationEntrypoint5.ts index ccab110225402..27dc3777dcc45 100644 --- a/tests/cases/compiler/optimizationEntrypoint5.ts +++ b/tests/cases/compiler/optimizationEntrypoint5.ts @@ -16,6 +16,9 @@ export class Main { f: foo.F & foo.F2; g: foo.GAlias; h: {item: foo.H}; + i: foo.IAlias; + j: foo.J; + jj: foo.AnyJ; } // @Filename: foo.ts @@ -29,5 +32,9 @@ export class F {} export class E2 {} export class F2 {} export class G {} -export type GAlias = G; +export type GAlias = G | A; export class H {} +export class I {} +export type IAlias = I; +export class J {} +export type AnyJ = J; From b08dc4e7c64cc5d7dac430d5e5bcb0265caaf381 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Oct 2015 22:43:38 -0700 Subject: [PATCH 20/52] changeup traversal a bit, still cant do aliases or type queries right --- src/compiler/checker.ts | 16 ++++++++++------ src/compiler/declarationEmitter.ts | 6 ++++-- tests/cases/compiler/optimizationEntrypoint4.ts | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eb192e03606bb..6d830936d5962 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2039,19 +2039,19 @@ namespace ts { if (type.flags & TypeFlags.Reference) { visitTypeReference(type as TypeReference); } - else if (type.flags & TypeFlags.TypeParameter) { + if (type.flags & TypeFlags.TypeParameter) { visitTypeParameter(type as TypeParameter); } - else if (type.flags & TypeFlags.Tuple) { + if (type.flags & TypeFlags.Tuple) { visitTupleType(type as TupleType); } - else if (type.flags & TypeFlags.UnionOrIntersection) { + if (type.flags & TypeFlags.UnionOrIntersection) { visitUnionOrIntersectionType(type as UnionOrIntersectionType); } - else if (type.flags & (TypeFlags.Class | TypeFlags.Interface)) { + if (type.flags & (TypeFlags.Class | TypeFlags.Interface)) { visitInterfaceType(type as InterfaceType); } - else if (type.flags & TypeFlags.Anonymous) { + if (type.flags & TypeFlags.Anonymous) { visitObjectType(type as ObjectType); } } @@ -2093,8 +2093,12 @@ namespace ts { visitType(signature.typePredicate.type); } visitTypeList(signature.typeParameters); - visitType(getReturnTypeOfSignature(signature)); + + for (let parameter of signature.parameters){ + visitTypeFromSymbol(parameter); + } visitType(getRestTypeOfSignature(signature)); + visitType(getReturnTypeOfSignature(signature)); } function visitInterfaceType(interfaceT: InterfaceType): void { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index f202b34d56bf9..7d5e910b2b4c8 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -335,7 +335,9 @@ namespace ts { function collectDependentTypes(exported: Map): Map { let dependentTypes: Map = {}; let walker = resolver.getTypeWalker(inspectType); - forEachValue(exported, type => walker.visitType(type)); + forEachValue(exported, type => { + walker.visitType(type); + }); return dependentTypes; @@ -347,7 +349,7 @@ namespace ts { } else { let id = symbol.id; if (id in exported || id in dependentTypes) { - return false; + return true; } dependentTypes[id] = type; } diff --git a/tests/cases/compiler/optimizationEntrypoint4.ts b/tests/cases/compiler/optimizationEntrypoint4.ts index 0a6c722f1d5a9..436bb73b10ef5 100644 --- a/tests/cases/compiler/optimizationEntrypoint4.ts +++ b/tests/cases/compiler/optimizationEntrypoint4.ts @@ -16,4 +16,6 @@ class Foo { static field: {name: string} } +namespace Foo {} + export = Foo; \ No newline at end of file From 818b89b0e5ab48e924d6dead9f2578baf8d25691 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Oct 2015 17:00:58 -0700 Subject: [PATCH 21/52] We now find higher level declarations for nested types so typeof expressions resolve --- src/compiler/checker.ts | 3 +++ src/compiler/declarationEmitter.ts | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6d830936d5962..5afc470dc1751 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2027,6 +2027,9 @@ namespace ts { let visited: Type[] = []; let visitedSymbols: Symbol[] = []; function visitType(type: Type): void { + if (!type) { + return; + } if (contains(visited, type)) { return; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 7d5e910b2b4c8..73993090efd28 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -320,7 +320,7 @@ namespace ts { forEach(undoActions, undo => undo()); // So we don't ruin the tree return; - + function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { return arrayToMap(filter(map(exportedMembers, exported => { let type = resolver.getDefiningTypeOfSymbol(exported); @@ -352,6 +352,14 @@ namespace ts { return true; } dependentTypes[id] = type; + // Add containing declarations if we've navigated to a nested type. + forEach(symbol.declarations, d => { + let containingDeclaration: Node = d; + while ((containingDeclaration = containingDeclaration.parent) && (!containingDeclaration.symbol || !(containingDeclaration.symbol.flags & (SymbolFlags.HasMembers | SymbolFlags.HasExports)))); + if (containingDeclaration !== d && containingDeclaration.symbol && containingDeclaration.kind !== SyntaxKind.SourceFile && containingDeclaration.kind !== SyntaxKind.ModuleDeclaration) { + walker.visitTypeFromSymbol(containingDeclaration.symbol); + } + }); } } return true; From 2e1bccedbb9a5ce8701263d452fe39788647ffa5 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Oct 2015 18:11:50 -0700 Subject: [PATCH 22/52] move comments --- src/compiler/declarationEmitter.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 73993090efd28..79a2063753c97 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -215,15 +215,21 @@ namespace ts { } let exportedSymbol = exportedMembers[index]; let symbol = type.symbol; - if (symbol) { // use the name from the exported symbol, but the id from the internal one - if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { // export= import case (effectively entrypoint redirection) + + // use the name from the exported symbol, but the id from the internal one + if (symbol) { + + // export= import case (effectively entrypoint redirection) + if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { reentry = symbol.valueDeclaration as SourceFile; } - else if (exportedSymbol.name === "export=") { // Special case all the things + // Special case all the things + else if (exportedSymbol.name === "export=") { exportEquals = type; } else if (exportedSymbol.name === "default") { - createDefaultExportAlias = () => { // delay making the alias until after all exported names are collected + // delay making the alias until after all exported names are collected + createDefaultExportAlias = () => { let name = "default_1"; while (!!symbolNameSet[name]) { name += "_1"; @@ -356,7 +362,7 @@ namespace ts { forEach(symbol.declarations, d => { let containingDeclaration: Node = d; while ((containingDeclaration = containingDeclaration.parent) && (!containingDeclaration.symbol || !(containingDeclaration.symbol.flags & (SymbolFlags.HasMembers | SymbolFlags.HasExports)))); - if (containingDeclaration !== d && containingDeclaration.symbol && containingDeclaration.kind !== SyntaxKind.SourceFile && containingDeclaration.kind !== SyntaxKind.ModuleDeclaration) { + if (containingDeclaration && containingDeclaration !== d && containingDeclaration.symbol && containingDeclaration.kind !== SyntaxKind.SourceFile && containingDeclaration.kind !== SyntaxKind.ModuleDeclaration) { walker.visitTypeFromSymbol(containingDeclaration.symbol); } }); From 0d6c19450464700b497c46dbba7ae2e84a8d8d98 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Oct 2015 18:14:00 -0700 Subject: [PATCH 23/52] break early on export =, not that there should be toher declarations --- src/compiler/declarationEmitter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 79a2063753c97..7f0e31dca329c 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -222,6 +222,7 @@ namespace ts { // export= import case (effectively entrypoint redirection) if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { reentry = symbol.valueDeclaration as SourceFile; + return true; // Break early } // Special case all the things else if (exportedSymbol.name === "export=") { From 066ffa9ca5844944b33283e2196934de3495dffa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Oct 2015 18:23:22 -0700 Subject: [PATCH 24/52] Fix things, awwww yis --- src/compiler/declarationEmitter.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 7f0e31dca329c..a79741f68d0f7 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -241,8 +241,12 @@ namespace ts { } } else if (symbol.name !== exportedSymbol.name) { - createSynthIdentifiers(symbol, exportedSymbol.name); - createSymbolEntry(exportedSymbol.name, symbol.id); + // check if this symbol is defined by another exported symbol + if (!contains(exportedMembers, symbol)) { + // If so, _don't_ mangle its name! (Because we don't need to) + createSynthIdentifiers(symbol, exportedSymbol.name); + createSymbolEntry(exportedSymbol.name, symbol.id); + } } else { createSymbolEntry(exportedSymbol.name, symbol.id); From 4d669876a35d5bfb819d03793d67d17ddea52b21 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 16:09:36 -0700 Subject: [PATCH 25/52] collect declarations to begin with, rather than types --- src/compiler/declarationEmitter.ts | 256 +++++++++++------- .../cases/compiler/optimizationEntrypoint1.ts | 2 +- 2 files changed, 152 insertions(+), 106 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index a79741f68d0f7..1fda505b3b84a 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -116,7 +116,6 @@ namespace ts { return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } noDeclare = false; - emitFlattenedTypeDefinitions(entrypoint); } else { @@ -186,11 +185,16 @@ namespace ts { function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { let undoActions: (() => void)[] = []; + let aliasEmits: (() => void)[] = []; let symbolNameSet: Map = {}; let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); - let types = collectExportedTypes(entrypoint, exportedMembers); - let dependentTypes = collectDependentTypes(types); - let aliasMapping = map(exportedMembers, exported => resolver.getDefiningTypeOfSymbol(exported)); + + // Handle an export=import as soon as possible + let maybeRedirectionType = exportedMembers.length && resolver.getDefiningTypeOfSymbol(exportedMembers[0]); + if (maybeRedirectionType && maybeRedirectionType.symbol && exportedMembers[0].name === "export=" && maybeRedirectionType.symbol.valueDeclaration && maybeRedirectionType.symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { + return emitFlattenedTypeDefinitions(maybeRedirectionType.symbol.valueDeclaration as SourceFile); + } + let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { forEach(symbol.declarations, declaration => { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; @@ -207,57 +211,13 @@ namespace ts { symbolGeneratedNameMap[id] = name; }; let createDefaultExportAlias = (): string => undefined; - let reentry: SourceFile; - let exportEquals: Type; - forEach(aliasMapping, (type, index) => { - if (!type) { - return; - } - let exportedSymbol = exportedMembers[index]; - let symbol = type.symbol; - // use the name from the exported symbol, but the id from the internal one - if (symbol) { + let exportEquals: Type; + let declarations = collectExportedDeclarations(exportedMembers); + let dependentDeclarations = collectDependentDeclarations(exportedMembers); - // export= import case (effectively entrypoint redirection) - if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { - reentry = symbol.valueDeclaration as SourceFile; - return true; // Break early - } - // Special case all the things - else if (exportedSymbol.name === "export=") { - exportEquals = type; - } - else if (exportedSymbol.name === "default") { - // delay making the alias until after all exported names are collected - createDefaultExportAlias = () => { - let name = "default_1"; - while (!!symbolNameSet[name]) { - name += "_1"; - } - createSymbolEntry(name, symbol.id); - createSynthIdentifiers(symbol, name); - return name; - } - } - else if (symbol.name !== exportedSymbol.name) { - // check if this symbol is defined by another exported symbol - if (!contains(exportedMembers, symbol)) { - // If so, _don't_ mangle its name! (Because we don't need to) - createSynthIdentifiers(symbol, exportedSymbol.name); - createSymbolEntry(exportedSymbol.name, symbol.id); - } - } - else { - createSymbolEntry(exportedSymbol.name, symbol.id); - } - } - }); - if (reentry) { - return emitFlattenedTypeDefinitions(reentry); - } - forEachValue(dependentTypes, type => { - let symbol = type.symbol; + forEachValue(dependentDeclarations, d => { + let symbol = d.symbol; if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; symbolNameSet[symbol.name]++; @@ -271,10 +231,8 @@ namespace ts { let alias = createDefaultExportAlias(); let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { + let realSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); - if (isDeclarationFile(currentSourceFile)) { - return; - } let oldFlags = d.flags; if (shouldExport) { d.flags |= NodeFlags.Export; @@ -287,70 +245,147 @@ namespace ts { if (oldFlags & NodeFlags.Default) { d.flags -= NodeFlags.Default; } - switch (d.kind) { - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - writeModuleElement(d); - default: - /// Declaration doesn't contribute to module exports (eg, TypeParameter) - } + writeModuleElement(d); d.flags = oldFlags; - } - let privateTypes = 0; - forEachValue(dependentTypes, type => { - privateTypes++; - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); currentSourceFile = realSourceFile; + } + let privateDeclarations = 0; + forEachValue(dependentDeclarations, d => { + privateDeclarations++; + emitModuleLevelDeclaration(d, /*shouldExport*/false); }); if (exportEquals) { - forEach(exportEquals.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/false)); writeLine(); write(`export = ${exportEquals.symbol.name};`); } else { - forEachValue(types, type => { - let realSourceFile = currentSourceFile; - forEach(type.symbol.declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); - currentSourceFile = realSourceFile; - }); + forEachValue(declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); } if (alias) { writeLine(); write(`export default ${alias};`); } - if (privateTypes && !exportEquals) { + if (aliasEmits.length) { + writeLine(); + write("export {"); writeLine(); - write("export {};"); + increaseIndent(); + forEach(aliasEmits, alias => { + alias(); + write(","); + writeLine(); + }); + decreaseIndent(); + write("}"); } forEach(undoActions, undo => undo()); // So we don't ruin the tree return; - function collectExportedTypes(file: SourceFile, exportedMembers: Symbol[]): Map { - return arrayToMap(filter(map(exportedMembers, exported => { + function isModuleLevelDeclaration(node: Node) { + switch (node.kind) { + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.VariableStatement: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.ModuleDeclaration: + return true; + default: + return false; + } + } + + function collectExportedDeclarations(exportedMembers: Symbol[]): Map { + const result: Map = {}; + for (let exported of exportedMembers) { + for (let declaration of exported.declarations) { + if (isModuleLevelDeclaration(declaration)) { // skips export specifiers + result[declaration.id] = declaration; + } + else { + // inline the declaration referred to by an export specifier with the specified name + if (declaration.kind === SyntaxKind.ExportSpecifier) { + let d = declaration as ExportSpecifier; + let symbol = d.symbol; + // If we already export the symbol being aliased, add a block to add the alias at the end, or inline + if (contains(exportedMembers, symbol)) { + if (!d.propertyName) { + // Inline the declaration referenced, rather than emitting an alias + let type = resolver.getDefiningTypeOfSymbol(symbol); + if (type && type.symbol) { + exportedMembers.push(type.symbol); + } + } + else { + aliasEmits.push(((d: ExportSpecifier) => () => { + let oldSourceFile = currentSourceFile; + currentSourceFile = getSourceFileOfNode(d); + let symbol = resolver.getDefiningTypeOfSymbol(d.symbol).symbol; + if (symbol && symbol.id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbol.id]); + } + else { + // This probably? should never happen + writeTextOfNode(currentSourceFile, d.propertyName); + } + write(" as "); + writeTextOfNode(currentSourceFile, d.name); + currentSourceFile = oldSourceFile; + })(d)); + } + } + } + } + } + let type = resolver.getDefiningTypeOfSymbol(exported); - if (type && exported.flags & SymbolFlags.TypeAlias) { - let oldSymbol = type.symbol; - type.symbol = exported; // Preserves type aliases if they're exported + // Special case all the things + if (exported.name === "export=") { + exportEquals = type; + continue; + } + else if (exported.name === "default") { + // delay making the alias until after all exported names are collected + createDefaultExportAlias = ((exported: Symbol, type: Type) => () => { + let name = "default_1"; + while (!!symbolNameSet[name]) { + name += "_1"; + } + createSymbolEntry(name, exported.id); + let symbol = type.symbol; + if (symbol) { + createSymbolEntry(name, symbol.id); + createSynthIdentifiers(symbol, name); + } + return name; + })(exported, type); + continue; } - return type; - }), value => value && !!value.symbol), value => (value.symbol.id + "")); - } - function collectDependentTypes(exported: Map): Map { - let dependentTypes: Map = {}; - let walker = resolver.getTypeWalker(inspectType); - forEachValue(exported, type => { - walker.visitType(type); - }); + if (type.symbol) { + let symbol = type.symbol; + if (symbol.name !== exported.name) { + // check if this symbol is defined by another exported symbol + if (!contains(exportedMembers, symbol)) { + // If not, mangle its name to the exported symbol's name + createSynthIdentifiers(symbol, exported.name); + } + } + createSymbolEntry(symbol.name, symbol.id); + } + createSymbolEntry(exported.name, exported.id); + } + return result; + } + + function collectDependentDeclarations(exportedMembers: Symbol[]): Map { + const dependentDeclarations: Map = {}; + const walker = resolver.getTypeWalker(inspectType); + forEach(exportedMembers, symbol => walker.visitTypeFromSymbol(symbol)); - return dependentTypes; + return dependentDeclarations; function inspectType(type: Type): boolean { let symbol = type.symbol; @@ -358,13 +393,16 @@ namespace ts { if (symbol.valueDeclaration && symbol.valueDeclaration.flags && symbol.valueDeclaration.flags & NodeFlags.Private) { return false; } else { - let id = symbol.id; - if (id in exported || id in dependentTypes) { - return true; - } - dependentTypes[id] = type; // Add containing declarations if we've navigated to a nested type. forEach(symbol.declarations, d => { + // No need to collect declarations not in our own code + if (isDeclarationFile(getSourceFileOfNode(d))) { + return; + } + if (!(d.id in dependentDeclarations || d.id in declarations) && isModuleLevelDeclaration(d)) { + // Don't need to collect declarations which are not module-level + dependentDeclarations[d.id] = d; + } let containingDeclaration: Node = d; while ((containingDeclaration = containingDeclaration.parent) && (!containingDeclaration.symbol || !(containingDeclaration.symbol.flags & (SymbolFlags.HasMembers | SymbolFlags.HasExports)))); if (containingDeclaration && containingDeclaration !== d && containingDeclaration.symbol && containingDeclaration.kind !== SyntaxKind.SourceFile && containingDeclaration.kind !== SyntaxKind.ModuleDeclaration) { @@ -578,6 +616,15 @@ namespace ts { emitType(type); } + function writeEntityNameIfRenamed(entityName: EntityName | Expression): boolean { + let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value); + if (symbol && symbol.id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbol.id]); + return true; + } + return false; + } + function emitType(type: TypeNode | Identifier | QualifiedName) { switch (type.kind) { case SyntaxKind.AnyKeyword: @@ -620,9 +667,8 @@ namespace ts { function writeEntityName(entityName: EntityName | Expression) { // Lookup for renames - let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace); - if (symbol && symbol.id in symbolGeneratedNameMap) { - write(symbolGeneratedNameMap[symbol.id]); + let written = writeEntityNameIfRenamed(entityName); + if (written) { return; } if (entityName.kind === SyntaxKind.Identifier) { diff --git a/tests/cases/compiler/optimizationEntrypoint1.ts b/tests/cases/compiler/optimizationEntrypoint1.ts index fe7f68457c213..ce62160620a08 100644 --- a/tests/cases/compiler/optimizationEntrypoint1.ts +++ b/tests/cases/compiler/optimizationEntrypoint1.ts @@ -5,7 +5,7 @@ // @Filename: index.ts export * from "./a"; -export {Detail} from "./b"; +export {Detail, Detail as DetailMock, Detail as DetailReal} from "./b"; export interface Inner { item4: number; From 93eee777539dba9eb132cbc79e4a87b180f1f35d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 16:50:58 -0700 Subject: [PATCH 26/52] re-correct the name mangling of default exports --- src/compiler/declarationEmitter.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 1fda505b3b84a..35287284abc2a 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -216,10 +216,14 @@ namespace ts { let declarations = collectExportedDeclarations(exportedMembers); let dependentDeclarations = collectDependentDeclarations(exportedMembers); + let alias = createDefaultExportAlias(); forEachValue(dependentDeclarations, d => { let symbol = d.symbol; if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; + while (!!symbolNameSet[generatedName]) { + generatedName = `${symbol.name}_${++symbolNameSet[symbol.name]}`; + } symbolNameSet[symbol.name]++; createSymbolEntry(generatedName, symbol.id); createSynthIdentifiers(symbol, generatedName); @@ -229,7 +233,6 @@ namespace ts { } }); - let alias = createDefaultExportAlias(); let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { let realSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); @@ -327,8 +330,7 @@ namespace ts { write(symbolGeneratedNameMap[symbol.id]); } else { - // This probably? should never happen - writeTextOfNode(currentSourceFile, d.propertyName); + Debug.fail("Encountered export alias of untraversed type when flattening."); } write(" as "); writeTextOfNode(currentSourceFile, d.name); From 39abdb6e3121f3a693dbc142451e65ae9a1031a4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 16:53:28 -0700 Subject: [PATCH 27/52] lint fixes --- src/compiler/declarationEmitter.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 35287284abc2a..944238dd1a057 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -182,7 +182,7 @@ namespace ts { synchronousDeclarationOutput: writer.getText(), referencePathsOutput, }; - + function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { let undoActions: (() => void)[] = []; let aliasEmits: (() => void)[] = []; @@ -226,7 +226,7 @@ namespace ts { } symbolNameSet[symbol.name]++; createSymbolEntry(generatedName, symbol.id); - createSynthIdentifiers(symbol, generatedName); + createSynthIdentifiers(symbol, generatedName); } else { createSymbolEntry(symbol.name, symbol.id); @@ -251,7 +251,7 @@ namespace ts { writeModuleElement(d); d.flags = oldFlags; currentSourceFile = realSourceFile; - } + }; let privateDeclarations = 0; forEachValue(dependentDeclarations, d => { privateDeclarations++; @@ -365,7 +365,7 @@ namespace ts { })(exported, type); continue; } - + if (type.symbol) { let symbol = type.symbol; if (symbol.name !== exported.name) { @@ -394,7 +394,8 @@ namespace ts { if (symbol) { if (symbol.valueDeclaration && symbol.valueDeclaration.flags && symbol.valueDeclaration.flags & NodeFlags.Private) { return false; - } else { + } + else { // Add containing declarations if we've navigated to a nested type. forEach(symbol.declarations, d => { // No need to collect declarations not in our own code From 63a967365b01ec12b97c29fd4fa57c4da7044775 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 17:05:38 -0700 Subject: [PATCH 28/52] accept new test baselines --- src/compiler/declarationEmitter.ts | 2 +- .../reference/optimizationEntrypoint.symbols | 82 ----- .../reference/optimizationEntrypoint.types | 82 ----- ...trypoint.js => optimizationEntrypoint1.js} | 146 ++++++--- .../reference/optimizationEntrypoint1.symbols | 108 +++++++ .../reference/optimizationEntrypoint1.types | 108 +++++++ .../reference/optimizationEntrypoint2.js | 118 +++++++ .../reference/optimizationEntrypoint2.symbols | 35 ++ .../reference/optimizationEntrypoint2.types | 35 ++ .../reference/optimizationEntrypoint3.js | 132 ++++++++ .../reference/optimizationEntrypoint3.symbols | 30 ++ .../reference/optimizationEntrypoint3.types | 30 ++ .../reference/optimizationEntrypoint4.js | 122 +++++++ .../reference/optimizationEntrypoint4.symbols | 32 ++ .../reference/optimizationEntrypoint4.types | 32 ++ .../reference/optimizationEntrypoint5.js | 306 ++++++++++++++++++ .../reference/optimizationEntrypoint5.symbols | 123 +++++++ .../reference/optimizationEntrypoint5.types | 123 +++++++ 18 files changed, 1438 insertions(+), 208 deletions(-) delete mode 100644 tests/baselines/reference/optimizationEntrypoint.symbols delete mode 100644 tests/baselines/reference/optimizationEntrypoint.types rename tests/baselines/reference/{optimizationEntrypoint.js => optimizationEntrypoint1.js} (51%) create mode 100644 tests/baselines/reference/optimizationEntrypoint1.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint1.types create mode 100644 tests/baselines/reference/optimizationEntrypoint2.js create mode 100644 tests/baselines/reference/optimizationEntrypoint2.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint2.types create mode 100644 tests/baselines/reference/optimizationEntrypoint3.js create mode 100644 tests/baselines/reference/optimizationEntrypoint3.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint3.types create mode 100644 tests/baselines/reference/optimizationEntrypoint4.js create mode 100644 tests/baselines/reference/optimizationEntrypoint4.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint4.types create mode 100644 tests/baselines/reference/optimizationEntrypoint5.js create mode 100644 tests/baselines/reference/optimizationEntrypoint5.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint5.types diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 944238dd1a057..5a464cdf891b6 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -268,7 +268,7 @@ namespace ts { writeLine(); write(`export default ${alias};`); } - if (aliasEmits.length) { + if ((privateDeclarations && !exportEquals) || aliasEmits.length) { writeLine(); write("export {"); writeLine(); diff --git a/tests/baselines/reference/optimizationEntrypoint.symbols b/tests/baselines/reference/optimizationEntrypoint.symbols deleted file mode 100644 index 6441ea8b1f5df..0000000000000 --- a/tests/baselines/reference/optimizationEntrypoint.symbols +++ /dev/null @@ -1,82 +0,0 @@ -=== tests/cases/compiler/index.ts === - -export * from "./a"; -export {Detail} from "./b"; ->Detail : Symbol(Detail, Decl(index.ts, 2, 8)) - -export interface Inner { ->Inner : Symbol(Inner, Decl(index.ts, 2, 27)) - - item4: number; ->item4 : Symbol(item4, Decl(index.ts, 4, 24)) -} - -=== tests/cases/compiler/a.ts === -import {Main as BaseMain, Inner as Middle} from "./b"; ->Main : Symbol(BaseMain, Decl(a.ts, 0, 8)) ->BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) ->Inner : Symbol(Middle, Decl(a.ts, 0, 25)) ->Middle : Symbol(Middle, Decl(a.ts, 0, 25)) - -export class Main extends BaseMain { ->Main : Symbol(Main, Decl(a.ts, 0, 54)) ->BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) - - memberc: Middle; ->memberc : Symbol(memberc, Decl(a.ts, 2, 36)) ->Middle : Symbol(Middle, Decl(a.ts, 0, 25)) -} - -export interface Inner { ->Inner : Symbol(Inner, Decl(a.ts, 4, 1)) - - item3: number; ->item3 : Symbol(item3, Decl(a.ts, 6, 24)) -} - -=== tests/cases/compiler/b.ts === -import {Main as BaseMain, Inner as Innermost} from "./c"; ->Main : Symbol(BaseMain, Decl(b.ts, 0, 8)) ->BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) ->Inner : Symbol(Innermost, Decl(b.ts, 0, 25)) ->Innermost : Symbol(Innermost, Decl(b.ts, 0, 25)) ->Main_2 : Symbol((Missing), Decl(b.ts, 0, 57)) ->Inner_2 : Symbol((Missing), Decl(b.ts, 5, 1)) - -export class Main extends BaseMain { ->BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) - - member2: Innermost; ->member2 : Symbol(member2, Decl(b.ts, 2, 36)) ->Innermost : Symbol(Innermost, Decl(b.ts, 0, 25)) - - details: Detail; ->details : Symbol(details, Decl(b.ts, 3, 20)) ->Detail : Symbol(Detail, Decl(b.ts, 9, 1)) -} - -export interface Inner { - item2: number; ->item2 : Symbol(item2, Decl(b.ts, 7, 24)) -} - -export interface Detail { ->Detail : Symbol(Detail, Decl(b.ts, 9, 1)) - - id: string; ->id : Symbol(id, Decl(b.ts, 11, 25)) -} - -=== tests/cases/compiler/c.ts === -export class Main { ->Main_1 : Symbol((Missing), Decl(c.ts, 0, 0)) ->Inner_1 : Symbol((Missing), Decl(c.ts, 2, 1)) - - member1: string; ->member1 : Symbol(member1, Decl(c.ts, 0, 19)) -} - -export interface Inner { - item: number; ->item : Symbol(item, Decl(c.ts, 4, 24)) -} diff --git a/tests/baselines/reference/optimizationEntrypoint.types b/tests/baselines/reference/optimizationEntrypoint.types deleted file mode 100644 index 6b1c0637ad584..0000000000000 --- a/tests/baselines/reference/optimizationEntrypoint.types +++ /dev/null @@ -1,82 +0,0 @@ -=== tests/cases/compiler/index.ts === - -export * from "./a"; -export {Detail} from "./b"; ->Detail : any - -export interface Inner { ->Inner : Inner - - item4: number; ->item4 : number -} - -=== tests/cases/compiler/a.ts === -import {Main as BaseMain, Inner as Middle} from "./b"; ->Main : typeof BaseMain ->BaseMain : typeof BaseMain ->Inner : any ->Middle : any - -export class Main extends BaseMain { ->Main : Main ->BaseMain : BaseMain - - memberc: Middle; ->memberc : Middle ->Middle : Middle -} - -export interface Inner { ->Inner : Inner - - item3: number; ->item3 : number -} - -=== tests/cases/compiler/b.ts === -import {Main as BaseMain, Inner as Innermost} from "./c"; ->Main : typeof BaseMain ->BaseMain : typeof BaseMain ->Inner : any ->Innermost : any ->Main_2 : (Missing) ->Inner_2 : (Missing) - -export class Main extends BaseMain { ->BaseMain : BaseMain - - member2: Innermost; ->member2 : Innermost ->Innermost : Innermost - - details: Detail; ->details : Detail ->Detail : Detail -} - -export interface Inner { - item2: number; ->item2 : number -} - -export interface Detail { ->Detail : Detail - - id: string; ->id : string -} - -=== tests/cases/compiler/c.ts === -export class Main { ->Main_1 : (Missing) ->Inner_1 : (Missing) - - member1: string; ->member1 : string -} - -export interface Inner { - item: number; ->item : number -} diff --git a/tests/baselines/reference/optimizationEntrypoint.js b/tests/baselines/reference/optimizationEntrypoint1.js similarity index 51% rename from tests/baselines/reference/optimizationEntrypoint.js rename to tests/baselines/reference/optimizationEntrypoint1.js index c859824db49e0..802fa52ab4092 100644 --- a/tests/baselines/reference/optimizationEntrypoint.js +++ b/tests/baselines/reference/optimizationEntrypoint1.js @@ -1,18 +1,26 @@ -//// [tests/cases/compiler/optimizationEntrypoint.ts] //// +//// [tests/cases/compiler/optimizationEntrypoint1.ts] //// //// [index.ts] export * from "./a"; -export {Detail} from "./b"; +export {Detail, Detail as DetailMock, Detail as DetailReal} from "./b"; export interface Inner { item4: number; } + +export interface default_1 { // make sure generated names don't clash + number: number; +} + +export {default as BBaseMain, Inner as Middle} from "./b"; +export {default as CBaseMain, Inner as Innermost} from "./c"; +export {default} from "./a"; //// [a.ts] -import {Main as BaseMain, Inner as Middle} from "./b"; +import {default as BaseMain, Inner as Middle} from "./b"; -export class Main extends BaseMain { +export default class Main extends BaseMain { memberc: Middle; } @@ -21,9 +29,9 @@ export interface Inner { } //// [b.ts] -import {Main as BaseMain, Inner as Innermost} from "./c"; +import {default as BaseMain, Inner as Innermost} from "./c"; -export class Main extends BaseMain { +export default class Main extends BaseMain { member2: Innermost; details: Detail; } @@ -37,7 +45,7 @@ export interface Detail { } //// [c.ts] -export class Main { +export default class Main { member1: string; } @@ -52,7 +60,8 @@ define(["require", "exports"], function (require, exports) { } return Main; })(); - exports.Main = Main; + exports.__esModule = true; + exports["default"] = Main; }); //// [b.js] var __extends = (this && this.__extends) || function (d, b) { @@ -67,8 +76,9 @@ define(["require", "exports", "./c"], function (require, exports, c_1) { _super.apply(this, arguments); } return Main; - })(c_1.Main); - exports.Main = Main; + })(c_1["default"]); + exports.__esModule = true; + exports["default"] = Main; }); //// [a.js] var __extends = (this && this.__extends) || function (d, b) { @@ -83,15 +93,19 @@ define(["require", "exports", "./b"], function (require, exports, b_1) { _super.apply(this, arguments); } return Main; - })(b_1.Main); - exports.Main = Main; + })(b_1["default"]); + exports.__esModule = true; + exports["default"] = Main; }); //// [index.js] -define(["require", "exports", "./a"], function (require, exports, a_1) { +define(["require", "exports", "./a", "./b", "./c", "./a"], function (require, exports, a_1, b_1, c_1, a_2) { function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } __export(a_1); + exports.BBaseMain = b_1.default; + exports.CBaseMain = c_1.default; + exports.default = a_2.default; }); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { @@ -105,7 +119,8 @@ define("tests/cases/compiler/c", ["require", "exports"], function (require, expo } return Main; })(); - exports.Main = Main; + exports.__esModule = true; + exports["default"] = Main; }); define("tests/cases/compiler/b", ["require", "exports", "tests/cases/compiler/c"], function (require, exports, c_1) { var Main = (function (_super) { @@ -114,8 +129,9 @@ define("tests/cases/compiler/b", ["require", "exports", "tests/cases/compiler/c" _super.apply(this, arguments); } return Main; - })(c_1.Main); - exports.Main = Main; + })(c_1["default"]); + exports.__esModule = true; + exports["default"] = Main; }); define("tests/cases/compiler/a", ["require", "exports", "tests/cases/compiler/b"], function (require, exports, b_1) { var Main = (function (_super) { @@ -124,27 +140,31 @@ define("tests/cases/compiler/a", ["require", "exports", "tests/cases/compiler/b" _super.apply(this, arguments); } return Main; - })(b_1.Main); - exports.Main = Main; + })(b_1["default"]); + exports.__esModule = true; + exports["default"] = Main; }); -define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/a"], function (require, exports, a_1) { +define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/a", "tests/cases/compiler/b", "tests/cases/compiler/c", "tests/cases/compiler/a"], function (require, exports, a_1, b_2, c_2, a_2) { function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } __export(a_1); + exports.BBaseMain = b_2.default; + exports.CBaseMain = c_2.default; + exports.default = a_2.default; }); //// [c.d.ts] -export declare class Main { +export default class Main { member1: string; } export interface Inner { item: number; } //// [b.d.ts] -import { Main as BaseMain, Inner as Innermost } from "./c"; -export declare class Main extends BaseMain { +import { default as BaseMain, Inner as Innermost } from "./c"; +export default class Main extends BaseMain { member2: Innermost; details: Detail; } @@ -155,8 +175,8 @@ export interface Detail { id: string; } //// [a.d.ts] -import { Main as BaseMain, Inner as Middle } from "./b"; -export declare class Main extends BaseMain { +import { default as BaseMain, Inner as Middle } from "./b"; +export default class Main extends BaseMain { memberc: Middle; } export interface Inner { @@ -164,18 +184,24 @@ export interface Inner { } //// [index.d.ts] export * from "./a"; -export { Detail } from "./b"; +export { Detail, Detail as DetailMock, Detail as DetailReal } from "./b"; export interface Inner { item4: number; } +export interface default_1 { + number: number; +} +export { default as BBaseMain, Inner as Middle } from "./b"; +export { default as CBaseMain, Inner as Innermost } from "./c"; +export { default } from "./a"; //// [bundled.d.ts] -declare class Main_1 { +declare class default_2 { member1: string; } interface Inner_1 { item: number; } -declare class Main_2 extends Main_1 { +declare class default_3 extends default_2 { member2: Inner_1; details: Detail; } @@ -185,31 +211,50 @@ interface Inner_2 { export interface Detail { id: string; } -export declare class Main extends Main_2 { +export declare class default_1_1 extends default_3 { memberc: Inner_2; } export interface Inner { item4: number; } - +export interface default_1 { + number: number; +} +export default default_1_1; +export { + Detail as DetailMock, + Detail as DetailReal, + default_3 as BBaseMain, + Inner_2 as Middle, + default_2 as CBaseMain, + Inner_1 as Innermost, +} //// [DtsFileErrors] -bundled.d.ts(17,35): error TS4020: Extends clause of exported class 'Main' has or is using private name 'Main_2'. +bundled.d.ts(7,33): error TS4020: Extends clause of exported class 'default_3' has or is using private name 'default_2'. +bundled.d.ts(8,14): error TS4031: Public property 'member2' of exported class has or is using private name 'Inner_1'. +bundled.d.ts(17,42): error TS4020: Extends clause of exported class 'default_1_1' has or is using private name 'default_3'. bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. ==== tests/cases/compiler/index.d.ts (0 errors) ==== export * from "./a"; - export { Detail } from "./b"; + export { Detail, Detail as DetailMock, Detail as DetailReal } from "./b"; export interface Inner { item4: number; } + export interface default_1 { + number: number; + } + export { default as BBaseMain, Inner as Middle } from "./b"; + export { default as CBaseMain, Inner as Innermost } from "./c"; + export { default } from "./a"; ==== tests/cases/compiler/a.d.ts (0 errors) ==== - import { Main as BaseMain, Inner as Middle } from "./b"; - export declare class Main extends BaseMain { + import { default as BaseMain, Inner as Middle } from "./b"; + export default class Main extends BaseMain { memberc: Middle; } export interface Inner { @@ -217,8 +262,8 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h } ==== tests/cases/compiler/b.d.ts (0 errors) ==== - import { Main as BaseMain, Inner as Innermost } from "./c"; - export declare class Main extends BaseMain { + import { default as BaseMain, Inner as Innermost } from "./c"; + export default class Main extends BaseMain { member2: Innermost; details: Detail; } @@ -230,22 +275,26 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h } ==== tests/cases/compiler/c.d.ts (0 errors) ==== - export declare class Main { + export default class Main { member1: string; } export interface Inner { item: number; } -==== bundled.d.ts (2 errors) ==== - declare class Main_1 { +==== bundled.d.ts (4 errors) ==== + declare class default_2 { member1: string; } interface Inner_1 { item: number; } - declare class Main_2 extends Main_1 { + declare class default_3 extends default_2 { + ~~~~~~~~~ +!!! error TS4020: Extends clause of exported class 'default_3' has or is using private name 'default_2'. member2: Inner_1; + ~~~~~~~ +!!! error TS4031: Public property 'member2' of exported class has or is using private name 'Inner_1'. details: Detail; } interface Inner_2 { @@ -254,9 +303,9 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h export interface Detail { id: string; } - export declare class Main extends Main_2 { - ~~~~~~ -!!! error TS4020: Extends clause of exported class 'Main' has or is using private name 'Main_2'. + export declare class default_1_1 extends default_3 { + ~~~~~~~~~ +!!! error TS4020: Extends clause of exported class 'default_1_1' has or is using private name 'default_3'. memberc: Inner_2; ~~~~~~~ !!! error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. @@ -264,4 +313,15 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h export interface Inner { item4: number; } - \ No newline at end of file + export interface default_1 { + number: number; + } + export default default_1_1; + export { + Detail as DetailMock, + Detail as DetailReal, + default_3 as BBaseMain, + Inner_2 as Middle, + default_2 as CBaseMain, + Inner_1 as Innermost, + } \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint1.symbols b/tests/baselines/reference/optimizationEntrypoint1.symbols new file mode 100644 index 0000000000000..2573d492487aa --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint1.symbols @@ -0,0 +1,108 @@ +=== tests/cases/compiler/index.ts === + +export * from "./a"; +export {Detail, Detail as DetailMock, Detail as DetailReal} from "./b"; +>Detail : Symbol(Detail, Decl(index.ts, 2, 8)) +>Detail : Symbol(DetailMock, Decl(index.ts, 2, 15)) +>DetailMock : Symbol(DetailMock, Decl(index.ts, 2, 15)) +>Detail : Symbol(DetailReal, Decl(index.ts, 2, 37)) +>DetailReal : Symbol(DetailReal, Decl(index.ts, 2, 37)) + +export interface Inner { +>Inner : Symbol(Inner, Decl(index.ts, 2, 71)) + + item4: number; +>item4 : Symbol(item4, Decl(index.ts, 4, 24)) +} + +export interface default_1 { // make sure generated names don't clash +>default_1 : Symbol(default_1, Decl(index.ts, 6, 1)) + + number: number; +>number : Symbol(number, Decl(index.ts, 8, 28)) +} + +export {default as BBaseMain, Inner as Middle} from "./b"; +>default : Symbol(BBaseMain, Decl(index.ts, 12, 8)) +>BBaseMain : Symbol(BBaseMain, Decl(index.ts, 12, 8)) +>Inner : Symbol(Middle, Decl(index.ts, 12, 29)) +>Middle : Symbol(Middle, Decl(index.ts, 12, 29)) + +export {default as CBaseMain, Inner as Innermost} from "./c"; +>default : Symbol(CBaseMain, Decl(index.ts, 13, 8)) +>CBaseMain : Symbol(CBaseMain, Decl(index.ts, 13, 8)) +>Inner : Symbol(Innermost, Decl(index.ts, 13, 29)) +>Innermost : Symbol(Innermost, Decl(index.ts, 13, 29)) + +export {default} from "./a"; +>default : Symbol(default, Decl(index.ts, 14, 8)) + +=== tests/cases/compiler/a.ts === +import {default as BaseMain, Inner as Middle} from "./b"; +>default : Symbol(BaseMain, Decl(a.ts, 0, 8)) +>BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) +>Inner : Symbol(Middle, Decl(a.ts, 0, 28)) +>Middle : Symbol(Middle, Decl(a.ts, 0, 28)) +>default_1_1 : Symbol((Missing), Decl(a.ts, 0, 57)) + +export default class Main extends BaseMain { +>BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) + + memberc: Middle; +>memberc : Symbol(memberc, Decl(a.ts, 2, 44)) +>Middle : Symbol(Middle, Decl(a.ts, 0, 28)) +} + +export interface Inner { +>Inner : Symbol(Inner, Decl(a.ts, 4, 1)) + + item3: number; +>item3 : Symbol(item3, Decl(a.ts, 6, 24)) +} + +=== tests/cases/compiler/b.ts === +import {default as BaseMain, Inner as Innermost} from "./c"; +>default : Symbol(BaseMain, Decl(b.ts, 0, 8)) +>BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) +>Inner : Symbol(Innermost, Decl(b.ts, 0, 28)) +>Innermost : Symbol(Innermost, Decl(b.ts, 0, 28)) +>Inner_2 : Symbol((Missing), Decl(b.ts, 5, 1)) + +export default class Main extends BaseMain { +>Main : Symbol(Main, Decl(b.ts, 0, 60)) +>BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) + + member2: Innermost; +>member2 : Symbol(member2, Decl(b.ts, 2, 44)) +>Innermost : Symbol(Innermost, Decl(b.ts, 0, 28)) + + details: Detail; +>details : Symbol(details, Decl(b.ts, 3, 20)) +>Detail : Symbol(Detail, Decl(b.ts, 9, 1)) +} + +export interface Inner { + item2: number; +>item2 : Symbol(item2, Decl(b.ts, 7, 24)) +} + +export interface Detail { +>Detail : Symbol(Detail, Decl(b.ts, 9, 1)) + + id: string; +>id : Symbol(id, Decl(b.ts, 11, 25)) +} + +=== tests/cases/compiler/c.ts === +export default class Main { +>default_2 : Symbol((Missing), Decl(c.ts, 0, 0)) +>Inner_1 : Symbol((Missing), Decl(c.ts, 2, 1)) + + member1: string; +>member1 : Symbol(member1, Decl(c.ts, 0, 27)) +} + +export interface Inner { + item: number; +>item : Symbol(item, Decl(c.ts, 4, 24)) +} diff --git a/tests/baselines/reference/optimizationEntrypoint1.types b/tests/baselines/reference/optimizationEntrypoint1.types new file mode 100644 index 0000000000000..87dd10efdcf9c --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint1.types @@ -0,0 +1,108 @@ +=== tests/cases/compiler/index.ts === + +export * from "./a"; +export {Detail, Detail as DetailMock, Detail as DetailReal} from "./b"; +>Detail : any +>Detail : any +>DetailMock : any +>Detail : any +>DetailReal : any + +export interface Inner { +>Inner : Inner + + item4: number; +>item4 : number +} + +export interface default_1 { // make sure generated names don't clash +>default_1 : default_1 + + number: number; +>number : number +} + +export {default as BBaseMain, Inner as Middle} from "./b"; +>default : typeof Main +>BBaseMain : typeof Main +>Inner : any +>Middle : any + +export {default as CBaseMain, Inner as Innermost} from "./c"; +>default : typeof (Missing) +>CBaseMain : typeof (Missing) +>Inner : any +>Innermost : any + +export {default} from "./a"; +>default : typeof (Missing) + +=== tests/cases/compiler/a.ts === +import {default as BaseMain, Inner as Middle} from "./b"; +>default : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Middle : any +>default_1_1 : (Missing) + +export default class Main extends BaseMain { +>BaseMain : BaseMain + + memberc: Middle; +>memberc : Middle +>Middle : Middle +} + +export interface Inner { +>Inner : Inner + + item3: number; +>item3 : number +} + +=== tests/cases/compiler/b.ts === +import {default as BaseMain, Inner as Innermost} from "./c"; +>default : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Innermost : any +>Inner_2 : (Missing) + +export default class Main extends BaseMain { +>Main : Main +>BaseMain : BaseMain + + member2: Innermost; +>member2 : Innermost +>Innermost : Innermost + + details: Detail; +>details : Detail +>Detail : Detail +} + +export interface Inner { + item2: number; +>item2 : number +} + +export interface Detail { +>Detail : Detail + + id: string; +>id : string +} + +=== tests/cases/compiler/c.ts === +export default class Main { +>default_2 : (Missing) +>Inner_1 : (Missing) + + member1: string; +>member1 : string +} + +export interface Inner { + item: number; +>item : number +} diff --git a/tests/baselines/reference/optimizationEntrypoint2.js b/tests/baselines/reference/optimizationEntrypoint2.js new file mode 100644 index 0000000000000..bf34995dea2b4 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint2.js @@ -0,0 +1,118 @@ +//// [tests/cases/compiler/optimizationEntrypoint2.ts] //// + +//// [index.ts] + +import * as t from "./foo"; + +export = t; + +//// [foo.ts] +export * from "./bar"; + +export class Foo extends Array { + self: this; +} + +//// [bar.ts] + +import {Foo} from "./foo"; + +export class Bar extends Foo> { + primary: Foo; +} + +//// [bar.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./foo"], function (require, exports, foo_1) { + var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + return Bar; + })(foo_1.Foo); + exports.Bar = Bar; +}); +//// [foo.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./bar"], function (require, exports, bar_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(bar_1); + var Foo = (function (_super) { + __extends(Foo, _super); + function Foo() { + _super.apply(this, arguments); + } + return Foo; + })(Array); + exports.Foo = Foo; +}); +//// [index.js] +define(["require", "exports", "./foo"], function (require, exports, t) { + return t; +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/bar", ["require", "exports", "tests/cases/compiler/foo"], function (require, exports, foo_1) { + var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + return Bar; + })(foo_1.Foo); + exports.Bar = Bar; +}); +define("tests/cases/compiler/foo", ["require", "exports", "tests/cases/compiler/bar"], function (require, exports, bar_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(bar_1); + var Foo = (function (_super) { + __extends(Foo, _super); + function Foo() { + _super.apply(this, arguments); + } + return Foo; + })(Array); + exports.Foo = Foo; +}); +define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/foo"], function (require, exports, t) { + return t; +}); + + +//// [bar.d.ts] +import { Foo } from "./foo"; +export declare class Bar extends Foo> { + primary: Foo; +} +//// [foo.d.ts] +export * from "./bar"; +export declare class Foo extends Array { + self: this; +} +//// [index.d.ts] +import * as t from "./foo"; +export = t; +//// [bundled.d.ts] +export declare class Bar extends Foo> { + primary: Foo; +} +export declare class Foo extends Array { + self: this; +} diff --git a/tests/baselines/reference/optimizationEntrypoint2.symbols b/tests/baselines/reference/optimizationEntrypoint2.symbols new file mode 100644 index 0000000000000..f80245e8a14b4 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint2.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/index.ts === + +import * as t from "./foo"; +>t : Symbol(t, Decl(index.ts, 1, 6)) + +export = t; +>t : Symbol(t, Decl(index.ts, 1, 6)) + +=== tests/cases/compiler/foo.ts === +export * from "./bar"; + +export class Foo extends Array { +>Foo : Symbol(Foo, Decl(foo.ts, 0, 22)) +>T : Symbol(T, Decl(foo.ts, 2, 17)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(foo.ts, 2, 17)) + + self: this; +>self : Symbol(self, Decl(foo.ts, 2, 38)) +} + +=== tests/cases/compiler/bar.ts === + +import {Foo} from "./foo"; +>Foo : Symbol(Foo, Decl(bar.ts, 1, 8)) + +export class Bar extends Foo> { +>Bar : Symbol(Bar, Decl(bar.ts, 1, 26)) +>Foo : Symbol(Foo, Decl(bar.ts, 1, 8)) +>Foo : Symbol(Foo, Decl(bar.ts, 1, 8)) + + primary: Foo; +>primary : Symbol(primary, Decl(bar.ts, 3, 43)) +>Foo : Symbol(Foo, Decl(bar.ts, 1, 8)) +} diff --git a/tests/baselines/reference/optimizationEntrypoint2.types b/tests/baselines/reference/optimizationEntrypoint2.types new file mode 100644 index 0000000000000..1fea197ea271d --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint2.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/index.ts === + +import * as t from "./foo"; +>t : typeof t + +export = t; +>t : typeof t + +=== tests/cases/compiler/foo.ts === +export * from "./bar"; + +export class Foo extends Array { +>Foo : Foo +>T : T +>Array : T[] +>T : T + + self: this; +>self : this +} + +=== tests/cases/compiler/bar.ts === + +import {Foo} from "./foo"; +>Foo : typeof Foo + +export class Bar extends Foo> { +>Bar : Bar +>Foo : Foo> +>Foo : Foo + + primary: Foo; +>primary : Foo +>Foo : Foo +} diff --git a/tests/baselines/reference/optimizationEntrypoint3.js b/tests/baselines/reference/optimizationEntrypoint3.js new file mode 100644 index 0000000000000..5bec906626d5b --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint3.js @@ -0,0 +1,132 @@ +//// [tests/cases/compiler/optimizationEntrypoint3.ts] //// + +//// [index.ts] + +import {Foo} from "./foo"; + +class Bar extends Foo> { + primary: Foo; +} + +export = Bar; + +//// [foo.ts] + +export class Foo extends Array { + self: this; +} + + +//// [foo.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports"], function (require, exports) { + var Foo = (function (_super) { + __extends(Foo, _super); + function Foo() { + _super.apply(this, arguments); + } + return Foo; + })(Array); + exports.Foo = Foo; +}); +//// [index.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./foo"], function (require, exports, foo_1) { + var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + return Bar; + })(foo_1.Foo); + return Bar; +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/foo", ["require", "exports"], function (require, exports) { + var Foo = (function (_super) { + __extends(Foo, _super); + function Foo() { + _super.apply(this, arguments); + } + return Foo; + })(Array); + exports.Foo = Foo; +}); +define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/foo"], function (require, exports, foo_1) { + var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + return Bar; + })(foo_1.Foo); + return Bar; +}); + + +//// [foo.d.ts] +export declare class Foo extends Array { + self: this; +} +//// [index.d.ts] +import { Foo } from "./foo"; +declare class Bar extends Foo> { + primary: Foo; +} +export = Bar; +//// [bundled.d.ts] +declare class Foo extends Array { + self: this; +} +declare class Bar extends Foo> { + primary: Foo; +} +export = Bar; + +//// [DtsFileErrors] + + +bundled.d.ts(4,27): error TS4020: Extends clause of exported class 'Bar' has or is using private name 'Foo'. +bundled.d.ts(4,31): error TS4020: Extends clause of exported class 'Bar' has or is using private name 'Foo'. +bundled.d.ts(5,14): error TS4031: Public property 'primary' of exported class has or is using private name 'Foo'. + + +==== tests/cases/compiler/index.d.ts (0 errors) ==== + import { Foo } from "./foo"; + declare class Bar extends Foo> { + primary: Foo; + } + export = Bar; + +==== tests/cases/compiler/foo.d.ts (0 errors) ==== + export declare class Foo extends Array { + self: this; + } + +==== bundled.d.ts (3 errors) ==== + declare class Foo extends Array { + self: this; + } + declare class Bar extends Foo> { + ~~~ +!!! error TS4020: Extends clause of exported class 'Bar' has or is using private name 'Foo'. + ~~~ +!!! error TS4020: Extends clause of exported class 'Bar' has or is using private name 'Foo'. + primary: Foo; + ~~~ +!!! error TS4031: Public property 'primary' of exported class has or is using private name 'Foo'. + } + export = Bar; \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint3.symbols b/tests/baselines/reference/optimizationEntrypoint3.symbols new file mode 100644 index 0000000000000..75dfd932a294f --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint3.symbols @@ -0,0 +1,30 @@ +=== tests/cases/compiler/index.ts === + +import {Foo} from "./foo"; +>Foo : Symbol(Foo, Decl(index.ts, 1, 8)) + +class Bar extends Foo> { +>Bar : Symbol(Bar, Decl(index.ts, 1, 26)) +>Foo : Symbol(Foo, Decl(index.ts, 1, 8)) +>Foo : Symbol(Foo, Decl(index.ts, 1, 8)) + + primary: Foo; +>primary : Symbol(primary, Decl(index.ts, 3, 36)) +>Foo : Symbol(Foo, Decl(index.ts, 1, 8)) +} + +export = Bar; +>Bar : Symbol(Bar, Decl(index.ts, 1, 26)) + +=== tests/cases/compiler/foo.ts === + +export class Foo extends Array { +>Foo : Symbol(Foo, Decl(foo.ts, 0, 0)) +>T : Symbol(T, Decl(foo.ts, 1, 17)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(foo.ts, 1, 17)) + + self: this; +>self : Symbol(self, Decl(foo.ts, 1, 38)) +} + diff --git a/tests/baselines/reference/optimizationEntrypoint3.types b/tests/baselines/reference/optimizationEntrypoint3.types new file mode 100644 index 0000000000000..cb02b1dd51bc6 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint3.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/index.ts === + +import {Foo} from "./foo"; +>Foo : typeof Foo + +class Bar extends Foo> { +>Bar : Bar +>Foo : Foo> +>Foo : Foo + + primary: Foo; +>primary : Foo +>Foo : Foo +} + +export = Bar; +>Bar : Bar + +=== tests/cases/compiler/foo.ts === + +export class Foo extends Array { +>Foo : Foo +>T : T +>Array : T[] +>T : T + + self: this; +>self : this +} + diff --git a/tests/baselines/reference/optimizationEntrypoint4.js b/tests/baselines/reference/optimizationEntrypoint4.js new file mode 100644 index 0000000000000..29e7b8353583d --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.js @@ -0,0 +1,122 @@ +//// [tests/cases/compiler/optimizationEntrypoint4.ts] //// + +//// [index.ts] + +import Foo = require("./foo"); + +export class Bar { + field2: typeof Foo.field; +} + +//// [foo.ts] + +class Foo { + static field: {name: string} +} + +namespace Foo {} + +export = Foo; + +//// [foo.js] +define(["require", "exports"], function (require, exports) { + var Foo = (function () { + function Foo() { + } + return Foo; + })(); + return Foo; +}); +//// [index.js] +define(["require", "exports"], function (require, exports) { + var Bar = (function () { + function Bar() { + } + return Bar; + })(); + exports.Bar = Bar; +}); +//// [bundled.js] +define("tests/cases/compiler/foo", ["require", "exports"], function (require, exports) { + var Foo = (function () { + function Foo() { + } + return Foo; + })(); + return Foo; +}); +define("tests/cases/compiler/index", ["require", "exports"], function (require, exports) { + var Bar = (function () { + function Bar() { + } + return Bar; + })(); + exports.Bar = Bar; +}); + + +//// [foo.d.ts] +declare class Foo { + static field: { + name: string; + }; +} +declare namespace Foo { +} +export = Foo; +//// [index.d.ts] +import Foo = require("./foo"); +export declare class Bar { + field2: typeof Foo.field; +} +//// [bundled.d.ts] +declare class Foo_1 { + static field: { + name: string; + }; +} +declare namespace Foo_1 { +} +export declare class Bar { + field2: typeof Foo_1.field; +} +export { +} + +//// [DtsFileErrors] + + +bundled.d.ts(9,20): error TS4031: Public property 'field2' of exported class has or is using private name 'Foo_1'. + + +==== tests/cases/compiler/index.d.ts (0 errors) ==== + import Foo = require("./foo"); + export declare class Bar { + field2: typeof Foo.field; + } + +==== tests/cases/compiler/foo.d.ts (0 errors) ==== + declare class Foo { + static field: { + name: string; + }; + } + declare namespace Foo { + } + export = Foo; + +==== bundled.d.ts (1 errors) ==== + declare class Foo_1 { + static field: { + name: string; + }; + } + declare namespace Foo_1 { + } + export declare class Bar { + field2: typeof Foo_1.field; + ~~~~~ +!!! error TS4031: Public property 'field2' of exported class has or is using private name 'Foo_1'. + } + export { + } \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint4.symbols b/tests/baselines/reference/optimizationEntrypoint4.symbols new file mode 100644 index 0000000000000..34d503834eec6 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/index.ts === + +import Foo = require("./foo"); +>Foo : Symbol(Foo, Decl(index.ts, 0, 0)) + +export class Bar { +>Bar : Symbol(Bar, Decl(index.ts, 1, 30)) + + field2: typeof Foo.field; +>field2 : Symbol(field2, Decl(index.ts, 3, 18)) +>Foo.field : Symbol(Foo.field, Decl(foo.ts, 1, 11)) +>Foo : Symbol(Foo, Decl(index.ts, 0, 0)) +>field : Symbol(Foo.field, Decl(foo.ts, 1, 11)) +} + +=== tests/cases/compiler/foo.ts === + +>Foo_1 : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) + +class Foo { +>Foo : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) + + static field: {name: string} +>field : Symbol(Foo.field, Decl(foo.ts, 1, 11)) +>name : Symbol(name, Decl(foo.ts, 2, 16)) +} + +namespace Foo {} + +export = Foo; +>Foo : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) + diff --git a/tests/baselines/reference/optimizationEntrypoint4.types b/tests/baselines/reference/optimizationEntrypoint4.types new file mode 100644 index 0000000000000..5dbc10fc5292a --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/index.ts === + +import Foo = require("./foo"); +>Foo : typeof Foo + +export class Bar { +>Bar : Bar + + field2: typeof Foo.field; +>field2 : { name: string; } +>Foo.field : { name: string; } +>Foo : typeof Foo +>field : { name: string; } +} + +=== tests/cases/compiler/foo.ts === + +>Foo_1 : typeof Foo + +class Foo { +>Foo : Foo + + static field: {name: string} +>field : { name: string; } +>name : string +} + +namespace Foo {} + +export = Foo; +>Foo : Foo + diff --git a/tests/baselines/reference/optimizationEntrypoint5.js b/tests/baselines/reference/optimizationEntrypoint5.js new file mode 100644 index 0000000000000..32240f31c3f04 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint5.js @@ -0,0 +1,306 @@ +//// [tests/cases/compiler/optimizationEntrypoint5.ts] //// + +//// [index.ts] + +import * as foo from "./foo"; +export * from "./foo"; + +export class Main { + a: foo.A; + b: [foo.B]; + c: (foo.C); + d: foo.D[]; + e: foo.E | foo.E2; + f: foo.F & foo.F2; + g: foo.GAlias; + h: {item: foo.H}; + i: foo.IAlias; + j: foo.J; + jj: foo.AnyJ; +} + +//// [foo.ts] + +export class A {} +export class B {} +export class C {} +export class D {} +export class E {} +export class F {} +export class E2 {} +export class F2 {} +export class G {} +export type GAlias = G | A; +export class H {} +export class I {} +export type IAlias = I; +export class J {} +export type AnyJ = J; + + +//// [foo.js] +define(["require", "exports"], function (require, exports) { + var A = (function () { + function A() { + } + return A; + })(); + exports.A = A; + var B = (function () { + function B() { + } + return B; + })(); + exports.B = B; + var C = (function () { + function C() { + } + return C; + })(); + exports.C = C; + var D = (function () { + function D() { + } + return D; + })(); + exports.D = D; + var E = (function () { + function E() { + } + return E; + })(); + exports.E = E; + var F = (function () { + function F() { + } + return F; + })(); + exports.F = F; + var E2 = (function () { + function E2() { + } + return E2; + })(); + exports.E2 = E2; + var F2 = (function () { + function F2() { + } + return F2; + })(); + exports.F2 = F2; + var G = (function () { + function G() { + } + return G; + })(); + exports.G = G; + var H = (function () { + function H() { + } + return H; + })(); + exports.H = H; + var I = (function () { + function I() { + } + return I; + })(); + exports.I = I; + var J = (function () { + function J() { + } + return J; + })(); + exports.J = J; +}); +//// [index.js] +define(["require", "exports", "./foo"], function (require, exports, foo_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foo_1); + var Main = (function () { + function Main() { + } + return Main; + })(); + exports.Main = Main; +}); +//// [bundled.js] +define("tests/cases/compiler/foo", ["require", "exports"], function (require, exports) { + var A = (function () { + function A() { + } + return A; + })(); + exports.A = A; + var B = (function () { + function B() { + } + return B; + })(); + exports.B = B; + var C = (function () { + function C() { + } + return C; + })(); + exports.C = C; + var D = (function () { + function D() { + } + return D; + })(); + exports.D = D; + var E = (function () { + function E() { + } + return E; + })(); + exports.E = E; + var F = (function () { + function F() { + } + return F; + })(); + exports.F = F; + var E2 = (function () { + function E2() { + } + return E2; + })(); + exports.E2 = E2; + var F2 = (function () { + function F2() { + } + return F2; + })(); + exports.F2 = F2; + var G = (function () { + function G() { + } + return G; + })(); + exports.G = G; + var H = (function () { + function H() { + } + return H; + })(); + exports.H = H; + var I = (function () { + function I() { + } + return I; + })(); + exports.I = I; + var J = (function () { + function J() { + } + return J; + })(); + exports.J = J; +}); +define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compiler/foo"], function (require, exports, foo_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foo_1); + var Main = (function () { + function Main() { + } + return Main; + })(); + exports.Main = Main; +}); + + +//// [foo.d.ts] +export declare class A { +} +export declare class B { +} +export declare class C { +} +export declare class D { +} +export declare class E { +} +export declare class F { +} +export declare class E2 { +} +export declare class F2 { +} +export declare class G { +} +export declare type GAlias = G | A; +export declare class H { +} +export declare class I { +} +export declare type IAlias = I; +export declare class J { +} +export declare type AnyJ = J; +//// [index.d.ts] +import * as foo from "./foo"; +export * from "./foo"; +export declare class Main { + a: foo.A; + b: [foo.B]; + c: (foo.C); + d: foo.D[]; + e: foo.E | foo.E2; + f: foo.F & foo.F2; + g: foo.GAlias; + h: { + item: foo.H; + }; + i: foo.IAlias; + j: foo.J; + jj: foo.AnyJ; +} +//// [bundled.d.ts] +export declare class A { +} +export declare class B { +} +export declare class C { +} +export declare class D { +} +export declare class E { +} +export declare class F { +} +export declare class E2 { +} +export declare class F2 { +} +export declare class G { +} +export declare class H { +} +export declare class I { +} +export declare class J { +} +export declare type GAlias = G | A; +export declare type IAlias = I; +export declare type AnyJ = J; +export declare class Main { + a: A; + b: [B]; + c: (C); + d: D[]; + e: E | E2; + f: F & F2; + g: GAlias; + h: { + item: H; + }; + i: IAlias; + j: J; + jj: AnyJ; +} diff --git a/tests/baselines/reference/optimizationEntrypoint5.symbols b/tests/baselines/reference/optimizationEntrypoint5.symbols new file mode 100644 index 0000000000000..e4e92e03ae34a --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint5.symbols @@ -0,0 +1,123 @@ +=== tests/cases/compiler/index.ts === + +import * as foo from "./foo"; +>foo : Symbol(foo, Decl(index.ts, 1, 6)) + +export * from "./foo"; + +export class Main { +>Main : Symbol(Main, Decl(index.ts, 2, 22)) + + a: foo.A; +>a : Symbol(a, Decl(index.ts, 4, 19)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>A : Symbol(foo.A, Decl(foo.ts, 0, 0)) + + b: [foo.B]; +>b : Symbol(b, Decl(index.ts, 5, 10)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>B : Symbol(foo.B, Decl(foo.ts, 1, 17)) + + c: (foo.C); +>c : Symbol(c, Decl(index.ts, 6, 12)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>C : Symbol(foo.C, Decl(foo.ts, 2, 17)) + + d: foo.D[]; +>d : Symbol(d, Decl(index.ts, 7, 12)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>D : Symbol(foo.D, Decl(foo.ts, 3, 17)) + + e: foo.E | foo.E2; +>e : Symbol(e, Decl(index.ts, 8, 12)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>E : Symbol(foo.E, Decl(foo.ts, 4, 17)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>E2 : Symbol(foo.E2, Decl(foo.ts, 6, 17)) + + f: foo.F & foo.F2; +>f : Symbol(f, Decl(index.ts, 9, 19)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>F : Symbol(foo.F, Decl(foo.ts, 5, 17)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>F2 : Symbol(foo.F2, Decl(foo.ts, 7, 18)) + + g: foo.GAlias; +>g : Symbol(g, Decl(index.ts, 10, 19)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>GAlias : Symbol(foo.GAlias, Decl(foo.ts, 9, 17)) + + h: {item: foo.H}; +>h : Symbol(h, Decl(index.ts, 11, 15)) +>item : Symbol(item, Decl(index.ts, 12, 5)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>H : Symbol(foo.H, Decl(foo.ts, 10, 27)) + + i: foo.IAlias; +>i : Symbol(i, Decl(index.ts, 12, 18)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>IAlias : Symbol(foo.IAlias, Decl(foo.ts, 12, 17)) + + j: foo.J; +>j : Symbol(j, Decl(index.ts, 13, 15)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>J : Symbol(foo.J, Decl(foo.ts, 13, 23)) + + jj: foo.AnyJ; +>jj : Symbol(jj, Decl(index.ts, 14, 18)) +>foo : Symbol(foo, Decl(index.ts, 1, 6)) +>AnyJ : Symbol(foo.AnyJ, Decl(foo.ts, 14, 20)) +} + +=== tests/cases/compiler/foo.ts === + +export class A {} +>A : Symbol(A, Decl(foo.ts, 0, 0)) + +export class B {} +>B : Symbol(B, Decl(foo.ts, 1, 17)) + +export class C {} +>C : Symbol(C, Decl(foo.ts, 2, 17)) + +export class D {} +>D : Symbol(D, Decl(foo.ts, 3, 17)) + +export class E {} +>E : Symbol(E, Decl(foo.ts, 4, 17)) + +export class F {} +>F : Symbol(F, Decl(foo.ts, 5, 17)) + +export class E2 {} +>E2 : Symbol(E2, Decl(foo.ts, 6, 17)) + +export class F2 {} +>F2 : Symbol(F2, Decl(foo.ts, 7, 18)) + +export class G {} +>G : Symbol(G, Decl(foo.ts, 8, 18)) + +export type GAlias = G | A; +>GAlias : Symbol(GAlias, Decl(foo.ts, 9, 17)) +>G : Symbol(G, Decl(foo.ts, 8, 18)) +>A : Symbol(A, Decl(foo.ts, 0, 0)) + +export class H {} +>H : Symbol(H, Decl(foo.ts, 10, 27)) + +export class I {} +>I : Symbol(I, Decl(foo.ts, 11, 17)) + +export type IAlias = I; +>IAlias : Symbol(IAlias, Decl(foo.ts, 12, 17)) +>I : Symbol(I, Decl(foo.ts, 11, 17)) + +export class J {} +>J : Symbol(J, Decl(foo.ts, 13, 23)) +>T : Symbol(T, Decl(foo.ts, 14, 15)) + +export type AnyJ = J; +>AnyJ : Symbol(AnyJ, Decl(foo.ts, 14, 20)) +>J : Symbol(J, Decl(foo.ts, 13, 23)) + diff --git a/tests/baselines/reference/optimizationEntrypoint5.types b/tests/baselines/reference/optimizationEntrypoint5.types new file mode 100644 index 0000000000000..5025260558c73 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint5.types @@ -0,0 +1,123 @@ +=== tests/cases/compiler/index.ts === + +import * as foo from "./foo"; +>foo : typeof foo + +export * from "./foo"; + +export class Main { +>Main : Main + + a: foo.A; +>a : foo.A +>foo : any +>A : foo.A + + b: [foo.B]; +>b : [foo.B] +>foo : any +>B : foo.B + + c: (foo.C); +>c : foo.C +>foo : any +>C : foo.C + + d: foo.D[]; +>d : foo.D[] +>foo : any +>D : foo.D + + e: foo.E | foo.E2; +>e : foo.E | foo.E2 +>foo : any +>E : foo.E +>foo : any +>E2 : foo.E2 + + f: foo.F & foo.F2; +>f : foo.F & foo.F2 +>foo : any +>F : foo.F +>foo : any +>F2 : foo.F2 + + g: foo.GAlias; +>g : foo.G | foo.A +>foo : any +>GAlias : foo.G | foo.A + + h: {item: foo.H}; +>h : { item: foo.H; } +>item : foo.H +>foo : any +>H : foo.H + + i: foo.IAlias; +>i : foo.I +>foo : any +>IAlias : foo.I + + j: foo.J; +>j : foo.J +>foo : any +>J : foo.J + + jj: foo.AnyJ; +>jj : foo.J +>foo : any +>AnyJ : foo.J +} + +=== tests/cases/compiler/foo.ts === + +export class A {} +>A : A + +export class B {} +>B : B + +export class C {} +>C : C + +export class D {} +>D : D + +export class E {} +>E : E + +export class F {} +>F : F + +export class E2 {} +>E2 : E2 + +export class F2 {} +>F2 : F2 + +export class G {} +>G : G + +export type GAlias = G | A; +>GAlias : G | A +>G : G +>A : A + +export class H {} +>H : H + +export class I {} +>I : I + +export type IAlias = I; +>IAlias : I +>I : I + +export class J {} +>J : J +>T : T + +export type AnyJ = J; +>AnyJ : J +>J : J + From 3aada1362d0a7dece273334ed751e9c41fe5f764 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 18:04:22 -0700 Subject: [PATCH 29/52] Add a test with export default expressions and types from dtses --- .../cases/compiler/optimizationEntrypoint6.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/cases/compiler/optimizationEntrypoint6.ts diff --git a/tests/cases/compiler/optimizationEntrypoint6.ts b/tests/cases/compiler/optimizationEntrypoint6.ts new file mode 100644 index 0000000000000..3b0004aa59e65 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint6.ts @@ -0,0 +1,31 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true +// @Filename: index.ts +export * from "./interop/index"; +export default 2+2; + +// @Filename: interop/index.ts +export * from "./foo"; +export * from "./bar"; + +// @Filename: interop/foo.ts +import {Dependency} from "foo"; + +export class FooDependency extends Dependency {} + +// @Filename: interop/bar.ts +import {Dependency} from "bar"; + +export class BarDependency extends Dependency {} + +// @Filename: typings/foo/index.d.ts +declare module "foo" { + export class Dependency {} +} + +// @Filename: typings/bar/index.d.ts +declare module "bar" { + export class Dependency {} +} \ No newline at end of file From 84ec5bf1258a4542077f743c310d82de7605dfb7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 18:40:19 -0700 Subject: [PATCH 30/52] note: the last file in a test cannot be a dts or badness ensues --- .../cases/compiler/optimizationEntrypoint6.ts | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/cases/compiler/optimizationEntrypoint6.ts b/tests/cases/compiler/optimizationEntrypoint6.ts index 3b0004aa59e65..14006c630efe6 100644 --- a/tests/cases/compiler/optimizationEntrypoint6.ts +++ b/tests/cases/compiler/optimizationEntrypoint6.ts @@ -1,31 +1,33 @@ // @module: amd // @outFile: bundled.js -// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @optimizationEntrypoint: tests/cases/compiler/main.ts // @declaration: true -// @Filename: index.ts + +// @Filename: typings/foo/index.d.ts +declare module "foo" { + export class Dependency {} +} + +// @Filename: typings/bar/index.d.ts +declare module "bar" { + export class Dependency {} +} + +// @Filename: main.ts export * from "./interop/index"; export default 2+2; +export class Meh {} // @Filename: interop/index.ts -export * from "./foo"; -export * from "./bar"; +export * from "./foodep"; +export * from "./bardep"; -// @Filename: interop/foo.ts +// @Filename: interop/foodep.ts import {Dependency} from "foo"; export class FooDependency extends Dependency {} -// @Filename: interop/bar.ts +// @Filename: interop/bardep.ts import {Dependency} from "bar"; export class BarDependency extends Dependency {} - -// @Filename: typings/foo/index.d.ts -declare module "foo" { - export class Dependency {} -} - -// @Filename: typings/bar/index.d.ts -declare module "bar" { - export class Dependency {} -} \ No newline at end of file From 9284aea1e4b43af808002fce7e9693d66fda9b83 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 19:01:59 -0700 Subject: [PATCH 31/52] handles export assignment expressions correctly now --- src/compiler/declarationEmitter.ts | 46 ++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 5a464cdf891b6..f3134ca0f9a81 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -210,7 +210,15 @@ namespace ts { symbolNameSet[name] = 1; symbolGeneratedNameMap[id] = name; }; - let createDefaultExportAlias = (): string => undefined; + let createDefaultExportAlias = (): string => { + let name = "default_1"; + while (!!symbolNameSet[name]) { + name += "_1"; + } + symbolNameSet[name] = 1; + return name; + }; + let writeExportAssignment = (tempname: string): void => undefined; let exportEquals: Type; let declarations = collectExportedDeclarations(exportedMembers); @@ -257,17 +265,13 @@ namespace ts { privateDeclarations++; emitModuleLevelDeclaration(d, /*shouldExport*/false); }); - if (exportEquals) { + if (writeExportAssignment) { writeLine(); - write(`export = ${exportEquals.symbol.name};`); + writeExportAssignment(alias); } - else { + if (!exportEquals) { forEachValue(declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); } - if (alias) { - writeLine(); - write(`export default ${alias};`); - } if ((privateDeclarations && !exportEquals) || aliasEmits.length) { writeLine(); write("export {"); @@ -339,6 +343,32 @@ namespace ts { } } } + // Handle export assignments + else if (declaration.kind === SyntaxKind.ExportAssignment) { + let assignment = declaration as ExportAssignment; + if (assignment.expression.kind === SyntaxKind.Identifier) { + writeExportAssignment = ((assignment: ExportAssignment) => (alias: string) => { + write(assignment.isExportEquals ? "export = " : "export default "); + write(alias); + write(";"); + writeLine(); + })(assignment); + } + else { + writeExportAssignment = ((assignment: ExportAssignment) => (alias: string) => { + write("declare var "); + write(alias); + write(": "); + resolver.writeTypeOfExpression(assignment.expression, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer); + write(";"); + writeLine(); + write(assignment.isExportEquals ? "export = " : "export default "); + write(alias); + write(";"); + writeLine(); + })(assignment); + } + } } } From a50f078242e2de4260c7d00838d7cabdfcfd76c0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 19:29:44 -0700 Subject: [PATCH 32/52] move some bits around which fixes a test --- src/compiler/declarationEmitter.ts | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index f3134ca0f9a81..c0a0294b872a2 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -265,13 +265,10 @@ namespace ts { privateDeclarations++; emitModuleLevelDeclaration(d, /*shouldExport*/false); }); - if (writeExportAssignment) { - writeLine(); - writeExportAssignment(alias); - } if (!exportEquals) { forEachValue(declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); } + writeExportAssignment(alias); if ((privateDeclarations && !exportEquals) || aliasEmits.length) { writeLine(); write("export {"); @@ -306,7 +303,9 @@ namespace ts { function collectExportedDeclarations(exportedMembers: Symbol[]): Map { const result: Map = {}; + const originalExportAssignment = writeExportAssignment; for (let exported of exportedMembers) { + const type = resolver.getDefiningTypeOfSymbol(exported); for (let declaration of exported.declarations) { if (isModuleLevelDeclaration(declaration)) { // skips export specifiers result[declaration.id] = declaration; @@ -314,22 +313,22 @@ namespace ts { else { // inline the declaration referred to by an export specifier with the specified name if (declaration.kind === SyntaxKind.ExportSpecifier) { - let d = declaration as ExportSpecifier; - let symbol = d.symbol; + const d = declaration as ExportSpecifier; + const symbol = d.symbol; // If we already export the symbol being aliased, add a block to add the alias at the end, or inline if (contains(exportedMembers, symbol)) { if (!d.propertyName) { // Inline the declaration referenced, rather than emitting an alias - let type = resolver.getDefiningTypeOfSymbol(symbol); - if (type && type.symbol) { - exportedMembers.push(type.symbol); + const innertype = resolver.getDefiningTypeOfSymbol(symbol); + if (innertype && innertype.symbol) { + exportedMembers.push(innertype.symbol); } } else { aliasEmits.push(((d: ExportSpecifier) => () => { - let oldSourceFile = currentSourceFile; + const oldSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); - let symbol = resolver.getDefiningTypeOfSymbol(d.symbol).symbol; + const symbol = resolver.getDefiningTypeOfSymbol(d.symbol).symbol; if (symbol && symbol.id in symbolGeneratedNameMap) { write(symbolGeneratedNameMap[symbol.id]); } @@ -345,7 +344,7 @@ namespace ts { } // Handle export assignments else if (declaration.kind === SyntaxKind.ExportAssignment) { - let assignment = declaration as ExportAssignment; + const assignment = declaration as ExportAssignment; if (assignment.expression.kind === SyntaxKind.Identifier) { writeExportAssignment = ((assignment: ExportAssignment) => (alias: string) => { write(assignment.isExportEquals ? "export = " : "export default "); @@ -372,10 +371,10 @@ namespace ts { } } - let type = resolver.getDefiningTypeOfSymbol(exported); // Special case all the things if (exported.name === "export=") { exportEquals = type; + createDefaultExportAlias = ((value: string) => () => value)(type.symbol.name); continue; } else if (exported.name === "default") { @@ -393,6 +392,13 @@ namespace ts { } return name; })(exported, type); + if (originalExportAssignment === writeExportAssignment) { + // We're adding an export assignment despite never seeing one in the original file + writeExportAssignment = (alias: string) => { + write(`export default ${alias};`); + writeLine(); + } + } continue; } From 40a42a2c625b6709d5385ab70bff689520ff63b3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Oct 2015 19:32:02 -0700 Subject: [PATCH 33/52] Meh is unbecomingish --- tests/cases/compiler/optimizationEntrypoint6.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/compiler/optimizationEntrypoint6.ts b/tests/cases/compiler/optimizationEntrypoint6.ts index 14006c630efe6..cb772b604c6d2 100644 --- a/tests/cases/compiler/optimizationEntrypoint6.ts +++ b/tests/cases/compiler/optimizationEntrypoint6.ts @@ -16,7 +16,7 @@ declare module "bar" { // @Filename: main.ts export * from "./interop/index"; export default 2+2; -export class Meh {} +export class Baz {} // @Filename: interop/index.ts export * from "./foodep"; From a2d93fe803b0f7a7696b53791d37089cda049f94 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 12:04:15 -0700 Subject: [PATCH 34/52] imports are awesome --- src/compiler/declarationEmitter.ts | 127 +++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 25 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index c0a0294b872a2..d0a27210fb8b1 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -116,6 +116,12 @@ namespace ts { return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } noDeclare = false; + let emittedReferencedFiles: SourceFile[] = []; + forEach(host.getSourceFiles(), sourceFile => { + if (!isDeclarationFile(sourceFile)) { + emitReferences(sourceFile, emittedReferencedFiles); + } + }); emitFlattenedTypeDefinitions(entrypoint); } else { @@ -125,25 +131,12 @@ namespace ts { forEach(host.getSourceFiles(), sourceFile => { if (!isExternalModuleOrDeclarationFile(sourceFile)) { noDeclare = false; - // Check what references need to be added - if (!compilerOptions.noResolve) { - forEach(sourceFile.referencedFiles, fileReference => { - let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference); - - // If the reference file is a declaration file or an external module, emit that reference - if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && - !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted - - writeReferencePath(referencedFile); - emittedReferencedFiles.push(referencedFile); - } - }); - } - + emitReferences(sourceFile, emittedReferencedFiles); emitSourceFile(sourceFile); } else if (isExternalModule(sourceFile)) { noDeclare = true; + emitReferences(sourceFile, emittedReferencedFiles); write(`declare module "${sourceFile.moduleName}" {`); writeLine(); increaseIndent(); @@ -183,10 +176,28 @@ namespace ts { referencePathsOutput, }; + function emitReferences(sourceFile: SourceFile, emittedReferencedFiles: FileReference[]) { + // Check what references need to be added + if (!compilerOptions.noResolve) { + forEach(sourceFile.referencedFiles, fileReference => { + let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference); + + // If the reference file is a declaration file or an external module, emit that reference + if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && + !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted + + writeReferencePath(referencedFile); + emittedReferencedFiles.push(referencedFile); + } + }); + } + } + function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { let undoActions: (() => void)[] = []; let aliasEmits: (() => void)[] = []; let symbolNameSet: Map = {}; + let imports: Map = {}; let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); // Handle an export=import as soon as possible @@ -195,7 +206,7 @@ namespace ts { return emitFlattenedTypeDefinitions(maybeRedirectionType.symbol.valueDeclaration as SourceFile); } - let createSynthIdentifiers = (symbol: Symbol, generatedName: string) => { + let createSyntheticIdentifiers = (symbol: Symbol, generatedName: string) => { forEach(symbol.declarations, declaration => { let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; synthId.flags |= NodeFlags.Synthetic; @@ -223,10 +234,7 @@ namespace ts { let exportEquals: Type; let declarations = collectExportedDeclarations(exportedMembers); let dependentDeclarations = collectDependentDeclarations(exportedMembers); - - let alias = createDefaultExportAlias(); - forEachValue(dependentDeclarations, d => { - let symbol = d.symbol; + let generateName = (symbol: Symbol): string => { if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; while (!!symbolNameSet[generatedName]) { @@ -234,11 +242,40 @@ namespace ts { } symbolNameSet[symbol.name]++; createSymbolEntry(generatedName, symbol.id); - createSynthIdentifiers(symbol, generatedName); + createSyntheticIdentifiers(symbol, generatedName); + return generatedName; } else { createSymbolEntry(symbol.name, symbol.id); + return symbol.name; } + } + + let alias = createDefaultExportAlias(); + forEachValue(dependentDeclarations, d => { + generateName(d.symbol); + }); + + // TODO: Handle external dts where we use their export= complex type (requiring `import v = require()` or `import * as v from ""`) + // TODO: Map module identifiers back to module names (rather than using absolute paths) + forEachKey(imports, filename => { + write("import {"); + writeLine(); + increaseIndent(); + forEach(imports[filename], declaration => { + let symbol = declaration.symbol; + if (!symbol) { + return; + } + // Alias the import if need be + let name = generateName(symbol); + write(symbol.name !== name ? `${symbol.name} as ${name},` : `${symbol.name},`); + writeLine(); + }); + decreaseIndent(); + // Handle module identifiers + write(filename.match(/^('|")/) ? `} from ${filename}` : `} from "${filename}"`); + writeLine(); }); let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { @@ -388,7 +425,7 @@ namespace ts { let symbol = type.symbol; if (symbol) { createSymbolEntry(name, symbol.id); - createSynthIdentifiers(symbol, name); + createSyntheticIdentifiers(symbol, name); } return name; })(exported, type); @@ -408,7 +445,7 @@ namespace ts { // check if this symbol is defined by another exported symbol if (!contains(exportedMembers, symbol)) { // If not, mangle its name to the exported symbol's name - createSynthIdentifiers(symbol, exported.name); + createSyntheticIdentifiers(symbol, exported.name); } } createSymbolEntry(symbol.name, symbol.id); @@ -434,8 +471,36 @@ namespace ts { else { // Add containing declarations if we've navigated to a nested type. forEach(symbol.declarations, d => { - // No need to collect declarations not in our own code - if (isDeclarationFile(getSourceFileOfNode(d))) { + // Collect declarations + let sourceFile = getSourceFileOfNode(d); + if (isDeclarationFile(sourceFile)) { + // If the declaration is from an external module dts, we need to create an import for it + if (isExternalModule(sourceFile)) { + imports[sourceFile.fileName] = imports[sourceFile.fileName] || []; + // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) + let declarationStack = findDeclarationStack(d); + // Get the topmost declaration from that stack of nodes + let declaration = declarationStack.pop(); + // Add that outer declaration to the list of things which need to be imported from an external source + if (!contains(imports[sourceFile.fileName], declaration)) { + imports[sourceFile.fileName].push(declaration); + } + } + else { + let declarationStack = findDeclarationStack(d); + // Check if this type comes from an ambient external module declaration + let moduleDeclaration = declarationStack.pop(); + if (moduleDeclaration.kind === SyntaxKind.ModuleDeclaration) { + // If so, add said ambient external module to the imports list, and the next declaration in the stack to the set of imports + let declaration = declarationStack.pop(); + let moduleName = (moduleDeclaration as ModuleDeclaration).name.text; + imports[moduleName] = imports[moduleName] || []; + if (!contains(imports[moduleName], declaration)) { + imports[moduleName].push(declaration); + } + } + } + // Otherwise we can elide it, as its from the stdlib or a triple-slash reference return; } if (!(d.id in dependentDeclarations || d.id in declarations) && isModuleLevelDeclaration(d)) { @@ -452,6 +517,18 @@ namespace ts { } return true; } + + function findDeclarationStack(d: Declaration): Declaration[] { + let outermostNode: Node = d; + let visited: Node[] = [d]; + // Find all the nodes between this declaration and the top of the file + // In most cases, this will _never_ even execute a single iteration as the declaration we have is likely already top-level + while (outermostNode.parent && outermostNode.parent.kind !== SyntaxKind.SourceFile) { + outermostNode = outermostNode.parent; + visited.push(outermostNode); + } + return filter(visited, node => isDeclaration(node)) as Declaration[]; + } } } From f14091e1c86a6e4930ade0fcde82cb528f5ae029 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 12:41:38 -0700 Subject: [PATCH 35/52] add triple slash refs to test --- tests/cases/compiler/optimizationEntrypoint6.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cases/compiler/optimizationEntrypoint6.ts b/tests/cases/compiler/optimizationEntrypoint6.ts index cb772b604c6d2..c9300a4f4ef67 100644 --- a/tests/cases/compiler/optimizationEntrypoint6.ts +++ b/tests/cases/compiler/optimizationEntrypoint6.ts @@ -14,6 +14,8 @@ declare module "bar" { } // @Filename: main.ts +/// +/// export * from "./interop/index"; export default 2+2; export class Baz {} From c67cff8149bd7da3bd5ba2b367effa144056631e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 12:44:58 -0700 Subject: [PATCH 36/52] Add node_modules test --- .../cases/compiler/optimizationEntrypoint7.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/cases/compiler/optimizationEntrypoint7.ts diff --git a/tests/cases/compiler/optimizationEntrypoint7.ts b/tests/cases/compiler/optimizationEntrypoint7.ts new file mode 100644 index 0000000000000..199e969ce9710 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint7.ts @@ -0,0 +1,29 @@ +// @module: amd +// @moduleResolution: node +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/main.ts +// @declaration: true + +// @Filename: node_modules/foo/index.d.ts +export class Dependency {} + +// @Filename: node_modules/bar/index.d.ts +export class Dependency {} + +// @Filename: main.ts +export * from "./interop"; +export class Baz {} + +// @Filename: interop/index.ts +export * from "./foodep"; +export * from "./bardep"; + +// @Filename: interop/foodep.ts +import {Dependency} from "foo"; + +export class FooDependency extends Dependency {} + +// @Filename: interop/bardep.ts +import {Dependency} from "bar"; + +export class BarDependency extends Dependency {} From d7f73851dfe26908a26a12c026b76cf3640b3893 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 13:06:28 -0700 Subject: [PATCH 37/52] handles module identifiers --- src/compiler/declarationEmitter.ts | 55 ++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d0a27210fb8b1..6ed751daf83b8 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -221,19 +221,6 @@ namespace ts { symbolNameSet[name] = 1; symbolGeneratedNameMap[id] = name; }; - let createDefaultExportAlias = (): string => { - let name = "default_1"; - while (!!symbolNameSet[name]) { - name += "_1"; - } - symbolNameSet[name] = 1; - return name; - }; - let writeExportAssignment = (tempname: string): void => undefined; - - let exportEquals: Type; - let declarations = collectExportedDeclarations(exportedMembers); - let dependentDeclarations = collectDependentDeclarations(exportedMembers); let generateName = (symbol: Symbol): string => { if (symbol.name in symbolNameSet) { let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; @@ -249,7 +236,21 @@ namespace ts { createSymbolEntry(symbol.name, symbol.id); return symbol.name; } - } + }; + let createDefaultExportAlias = (): string => { + let name = "default_1"; + while (!!symbolNameSet[name]) { + name += "_1"; + } + symbolNameSet[name] = 1; + return name; + }; + let writeExportAssignment = (tempname: string): void => undefined; + + let exportEquals: Type; + let moduleIdReverseLookup = buildModuleDtsReverseLookupTable(entrypoint); + let declarations = collectExportedDeclarations(exportedMembers); + let dependentDeclarations = collectDependentDeclarations(exportedMembers); let alias = createDefaultExportAlias(); forEachValue(dependentDeclarations, d => { @@ -323,6 +324,22 @@ namespace ts { return; + function buildModuleDtsReverseLookupTable(entrypoint: SourceFile, table: Map = {}, visited: Map = {}) { + visited[entrypoint.fileName] = entrypoint; + forEachKey(entrypoint.resolvedModules, name => { + // Skip relative paths and rooted paths (look at module identifiers only) + let filename = entrypoint.resolvedModules[name].resolvedFileName; + if (!name.match(/(\.|\/)/)) { + table[filename] = name; + } + let file = host.getSourceFile(filename); + if (!visited[file.fileName]) { + buildModuleDtsReverseLookupTable(file, table, visited); + } + }); + return table; + } + function isModuleLevelDeclaration(node: Node) { switch (node.kind) { case SyntaxKind.TypeAliasDeclaration: @@ -434,7 +451,7 @@ namespace ts { writeExportAssignment = (alias: string) => { write(`export default ${alias};`); writeLine(); - } + }; } continue; } @@ -476,14 +493,16 @@ namespace ts { if (isDeclarationFile(sourceFile)) { // If the declaration is from an external module dts, we need to create an import for it if (isExternalModule(sourceFile)) { - imports[sourceFile.fileName] = imports[sourceFile.fileName] || []; + // First, try to reverse lookup a module identifier + let fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; + imports[fileName] = imports[fileName] || []; // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) let declarationStack = findDeclarationStack(d); // Get the topmost declaration from that stack of nodes let declaration = declarationStack.pop(); // Add that outer declaration to the list of things which need to be imported from an external source - if (!contains(imports[sourceFile.fileName], declaration)) { - imports[sourceFile.fileName].push(declaration); + if (!contains(imports[fileName], declaration)) { + imports[fileName].push(declaration); } } else { From c0c02dd18d13904cf35b6390f1bf43bd7ae5b9b0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 13:19:43 -0700 Subject: [PATCH 38/52] small fix, accept new baselines --- src/compiler/declarationEmitter.ts | 4 + .../reference/optimizationEntrypoint3.js | 4 +- .../reference/optimizationEntrypoint6.js | 179 ++++++++++++++ .../reference/optimizationEntrypoint6.symbols | 41 ++++ .../reference/optimizationEntrypoint6.types | 45 ++++ .../reference/optimizationEntrypoint7.js | 225 ++++++++++++++++++ .../reference/optimizationEntrypoint7.symbols | 34 +++ .../reference/optimizationEntrypoint7.types | 34 +++ 8 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/optimizationEntrypoint6.js create mode 100644 tests/baselines/reference/optimizationEntrypoint6.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint6.types create mode 100644 tests/baselines/reference/optimizationEntrypoint7.js create mode 100644 tests/baselines/reference/optimizationEntrypoint7.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint7.types diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 6ed751daf83b8..8afc189b6a337 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -327,6 +327,10 @@ namespace ts { function buildModuleDtsReverseLookupTable(entrypoint: SourceFile, table: Map = {}, visited: Map = {}) { visited[entrypoint.fileName] = entrypoint; forEachKey(entrypoint.resolvedModules, name => { + // Skip unresolved modules + if (!entrypoint.resolvedModules[name]) { + return; + } // Skip relative paths and rooted paths (look at module identifiers only) let filename = entrypoint.resolvedModules[name].resolvedFileName; if (!name.match(/(\.|\/)/)) { diff --git a/tests/baselines/reference/optimizationEntrypoint3.js b/tests/baselines/reference/optimizationEntrypoint3.js index 5bec906626d5b..613f88bcb5b8a 100644 --- a/tests/baselines/reference/optimizationEntrypoint3.js +++ b/tests/baselines/reference/optimizationEntrypoint3.js @@ -96,6 +96,7 @@ declare class Bar extends Foo> { } export = Bar; + //// [DtsFileErrors] @@ -129,4 +130,5 @@ bundled.d.ts(5,14): error TS4031: Public property 'primary' of exported class ha ~~~ !!! error TS4031: Public property 'primary' of exported class has or is using private name 'Foo'. } - export = Bar; \ No newline at end of file + export = Bar; + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint6.js b/tests/baselines/reference/optimizationEntrypoint6.js new file mode 100644 index 0000000000000..d10c0e8bfd3ad --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint6.js @@ -0,0 +1,179 @@ +//// [tests/cases/compiler/optimizationEntrypoint6.ts] //// + +//// [index.d.ts] + +declare module "foo" { + export class Dependency {} +} + +//// [index.d.ts] +declare module "bar" { + export class Dependency {} +} + +//// [main.ts] +/// +/// +export * from "./interop/index"; +export default 2+2; +export class Baz {} + +//// [index.ts] +export * from "./foodep"; +export * from "./bardep"; + +//// [foodep.ts] +import {Dependency} from "foo"; + +export class FooDependency extends Dependency {} + +//// [bardep.ts] +import {Dependency} from "bar"; + +export class BarDependency extends Dependency {} + + +//// [foodep.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "foo"], function (require, exports, foo_1) { + var FooDependency = (function (_super) { + __extends(FooDependency, _super); + function FooDependency() { + _super.apply(this, arguments); + } + return FooDependency; + })(foo_1.Dependency); + exports.FooDependency = FooDependency; +}); +//// [bardep.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "bar"], function (require, exports, bar_1) { + var BarDependency = (function (_super) { + __extends(BarDependency, _super); + function BarDependency() { + _super.apply(this, arguments); + } + return BarDependency; + })(bar_1.Dependency); + exports.BarDependency = BarDependency; +}); +//// [index.js] +define(["require", "exports", "./foodep", "./bardep"], function (require, exports, foodep_1, bardep_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foodep_1); + __export(bardep_1); +}); +//// [main.js] +define(["require", "exports", "./interop/index"], function (require, exports, index_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + /// + /// + __export(index_1); + exports.__esModule = true; + exports["default"] = 2 + 2; + var Baz = (function () { + function Baz() { + } + return Baz; + })(); + exports.Baz = Baz; +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/interop/foodep", ["require", "exports", "foo"], function (require, exports, foo_1) { + var FooDependency = (function (_super) { + __extends(FooDependency, _super); + function FooDependency() { + _super.apply(this, arguments); + } + return FooDependency; + })(foo_1.Dependency); + exports.FooDependency = FooDependency; +}); +define("tests/cases/compiler/interop/bardep", ["require", "exports", "bar"], function (require, exports, bar_1) { + var BarDependency = (function (_super) { + __extends(BarDependency, _super); + function BarDependency() { + _super.apply(this, arguments); + } + return BarDependency; + })(bar_1.Dependency); + exports.BarDependency = BarDependency; +}); +define("tests/cases/compiler/interop/index", ["require", "exports", "tests/cases/compiler/interop/foodep", "tests/cases/compiler/interop/bardep"], function (require, exports, foodep_1, bardep_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foodep_1); + __export(bardep_1); +}); +define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler/interop/index"], function (require, exports, index_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + /// + /// + __export(index_1); + exports.__esModule = true; + exports["default"] = 2 + 2; + var Baz = (function () { + function Baz() { + } + return Baz; + })(); + exports.Baz = Baz; +}); + + +//// [foodep.d.ts] +import { Dependency } from "foo"; +export declare class FooDependency extends Dependency { +} +//// [bardep.d.ts] +import { Dependency } from "bar"; +export declare class BarDependency extends Dependency { +} +//// [index.d.ts] +export * from "./foodep"; +export * from "./bardep"; +//// [main.d.ts] +/// +/// +export * from "./interop/index"; +declare var _default: number; +export default _default; +export declare class Baz { +} +//// [bundled.d.ts] +/// +/// +import { + Dependency, +} from "foo" +import { + Dependency as Dependency_1, +} from "bar" +export declare class FooDependency extends Dependency { +} +export declare class BarDependency extends Dependency_1 { +} +export declare class Baz { +} +declare var default_1: number; +export default default_1; diff --git a/tests/baselines/reference/optimizationEntrypoint6.symbols b/tests/baselines/reference/optimizationEntrypoint6.symbols new file mode 100644 index 0000000000000..1a6df730912fb --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint6.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/typings/foo/index.d.ts === + +declare module "foo" { + export class Dependency {} +>Dependency : Symbol(Dependency, Decl(index.d.ts, 1, 22)) +} + +=== tests/cases/compiler/typings/bar/index.d.ts === +declare module "bar" { + export class Dependency {} +>Dependency : Symbol(Dependency, Decl(index.d.ts, 0, 22)) +} + +=== tests/cases/compiler/main.ts === +/// +/// +export * from "./interop/index"; +export default 2+2; +export class Baz {} +>Baz : Symbol(Baz, Decl(main.ts, 3, 19)) + +=== tests/cases/compiler/interop/index.ts === +export * from "./foodep"; +No type information for this code.export * from "./bardep"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/interop/foodep.ts === +import {Dependency} from "foo"; +>Dependency : Symbol(Dependency, Decl(foodep.ts, 0, 8)) + +export class FooDependency extends Dependency {} +>FooDependency : Symbol(FooDependency, Decl(foodep.ts, 0, 31)) +>Dependency : Symbol(Dependency, Decl(foodep.ts, 0, 8)) + +=== tests/cases/compiler/interop/bardep.ts === +import {Dependency} from "bar"; +>Dependency : Symbol(Dependency, Decl(bardep.ts, 0, 8)) + +export class BarDependency extends Dependency {} +>BarDependency : Symbol(BarDependency, Decl(bardep.ts, 0, 31)) +>Dependency : Symbol(Dependency, Decl(bardep.ts, 0, 8)) + diff --git a/tests/baselines/reference/optimizationEntrypoint6.types b/tests/baselines/reference/optimizationEntrypoint6.types new file mode 100644 index 0000000000000..00698984f4ab4 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint6.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/typings/foo/index.d.ts === + +declare module "foo" { + export class Dependency {} +>Dependency : Dependency +} + +=== tests/cases/compiler/typings/bar/index.d.ts === +declare module "bar" { + export class Dependency {} +>Dependency : Dependency +} + +=== tests/cases/compiler/main.ts === +/// +/// +export * from "./interop/index"; +export default 2+2; +>2+2 : number +>2 : number +>2 : number + +export class Baz {} +>Baz : Baz + +=== tests/cases/compiler/interop/index.ts === +export * from "./foodep"; +No type information for this code.export * from "./bardep"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/interop/foodep.ts === +import {Dependency} from "foo"; +>Dependency : typeof Dependency + +export class FooDependency extends Dependency {} +>FooDependency : FooDependency +>Dependency : Dependency + +=== tests/cases/compiler/interop/bardep.ts === +import {Dependency} from "bar"; +>Dependency : typeof Dependency + +export class BarDependency extends Dependency {} +>BarDependency : BarDependency +>Dependency : Dependency + diff --git a/tests/baselines/reference/optimizationEntrypoint7.js b/tests/baselines/reference/optimizationEntrypoint7.js new file mode 100644 index 0000000000000..483052afcf67d --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint7.js @@ -0,0 +1,225 @@ +//// [tests/cases/compiler/optimizationEntrypoint7.ts] //// + +//// [index.d.ts] + +export class Dependency {} + +//// [index.d.ts] +export class Dependency {} + +//// [main.ts] +export * from "./interop"; +export class Baz {} + +//// [index.ts] +export * from "./foodep"; +export * from "./bardep"; + +//// [foodep.ts] +import {Dependency} from "foo"; + +export class FooDependency extends Dependency {} + +//// [bardep.ts] +import {Dependency} from "bar"; + +export class BarDependency extends Dependency {} + + +//// [foodep.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "foo"], function (require, exports, foo_1) { + var FooDependency = (function (_super) { + __extends(FooDependency, _super); + function FooDependency() { + _super.apply(this, arguments); + } + return FooDependency; + })(foo_1.Dependency); + exports.FooDependency = FooDependency; +}); +//// [bardep.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "bar"], function (require, exports, bar_1) { + var BarDependency = (function (_super) { + __extends(BarDependency, _super); + function BarDependency() { + _super.apply(this, arguments); + } + return BarDependency; + })(bar_1.Dependency); + exports.BarDependency = BarDependency; +}); +//// [index.js] +define(["require", "exports", "./foodep", "./bardep"], function (require, exports, foodep_1, bardep_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foodep_1); + __export(bardep_1); +}); +//// [main.js] +define(["require", "exports", "./interop"], function (require, exports, interop_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(interop_1); + var Baz = (function () { + function Baz() { + } + return Baz; + })(); + exports.Baz = Baz; +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/node_modules/foo/index", ["require", "exports"], function (require, exports) { + var Dependency = (function () { + function Dependency() { + } + return Dependency; + })(); + exports.Dependency = Dependency; +}); +define("tests/cases/compiler/node_modules/bar/index", ["require", "exports"], function (require, exports) { + var Dependency = (function () { + function Dependency() { + } + return Dependency; + })(); + exports.Dependency = Dependency; +}); +define("tests/cases/compiler/interop/foodep", ["require", "exports", "tests/cases/compiler/node_modules/foo/index"], function (require, exports, foo_1) { + var FooDependency = (function (_super) { + __extends(FooDependency, _super); + function FooDependency() { + _super.apply(this, arguments); + } + return FooDependency; + })(foo_1.Dependency); + exports.FooDependency = FooDependency; +}); +define("tests/cases/compiler/interop/bardep", ["require", "exports", "tests/cases/compiler/node_modules/bar/index"], function (require, exports, bar_1) { + var BarDependency = (function (_super) { + __extends(BarDependency, _super); + function BarDependency() { + _super.apply(this, arguments); + } + return BarDependency; + })(bar_1.Dependency); + exports.BarDependency = BarDependency; +}); +define("tests/cases/compiler/interop/index", ["require", "exports", "tests/cases/compiler/interop/foodep", "tests/cases/compiler/interop/bardep"], function (require, exports, foodep_1, bardep_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(foodep_1); + __export(bardep_1); +}); +define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler/interop/index"], function (require, exports, interop_1) { + function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + __export(interop_1); + var Baz = (function () { + function Baz() { + } + return Baz; + })(); + exports.Baz = Baz; +}); + + +//// [foodep.d.ts] +import { Dependency } from "foo"; +export declare class FooDependency extends Dependency { +} +//// [bardep.d.ts] +import { Dependency } from "bar"; +export declare class BarDependency extends Dependency { +} +//// [index.d.ts] +export * from "./foodep"; +export * from "./bardep"; +//// [main.d.ts] +export * from "./interop"; +export declare class Baz { +} +//// [bundled.d.ts] +import { + Dependency, +} from "foo" +import { + Dependency as Dependency_1, +} from "bar" +export declare class FooDependency extends Dependency { +} +export declare class BarDependency extends Dependency_1 { +} +export declare class Baz { +} + + +//// [DtsFileErrors] + + +bundled.d.ts(3,8): error TS2307: Cannot find module 'foo'. +bundled.d.ts(6,8): error TS2307: Cannot find module 'bar'. + + +==== tests/cases/compiler/node_modules/foo/index.d.ts (0 errors) ==== + + export class Dependency {} + +==== tests/cases/compiler/node_modules/bar/index.d.ts (0 errors) ==== + export class Dependency {} + +==== tests/cases/compiler/main.d.ts (0 errors) ==== + export * from "./interop"; + export declare class Baz { + } + +==== tests/cases/compiler/interop/index.d.ts (0 errors) ==== + export * from "./foodep"; + export * from "./bardep"; + +==== tests/cases/compiler/interop/foodep.d.ts (0 errors) ==== + import { Dependency } from "foo"; + export declare class FooDependency extends Dependency { + } + +==== tests/cases/compiler/interop/bardep.d.ts (0 errors) ==== + import { Dependency } from "bar"; + export declare class BarDependency extends Dependency { + } + +==== bundled.d.ts (2 errors) ==== + import { + Dependency, + } from "foo" + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + import { + Dependency as Dependency_1, + } from "bar" + ~~~~~ +!!! error TS2307: Cannot find module 'bar'. + export declare class FooDependency extends Dependency { + } + export declare class BarDependency extends Dependency_1 { + } + export declare class Baz { + } + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint7.symbols b/tests/baselines/reference/optimizationEntrypoint7.symbols new file mode 100644 index 0000000000000..38ab2d4d44e84 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint7.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +export class Dependency {} +>Dependency : Symbol(Dependency, Decl(index.d.ts, 0, 0)) + +=== tests/cases/compiler/node_modules/bar/index.d.ts === +export class Dependency {} +>Dependency : Symbol(Dependency, Decl(index.d.ts, 0, 0)) + +=== tests/cases/compiler/main.ts === +export * from "./interop"; +export class Baz {} +>Baz : Symbol(Baz, Decl(main.ts, 0, 26)) + +=== tests/cases/compiler/interop/index.ts === +export * from "./foodep"; +No type information for this code.export * from "./bardep"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/interop/foodep.ts === +import {Dependency} from "foo"; +>Dependency : Symbol(Dependency, Decl(foodep.ts, 0, 8)) + +export class FooDependency extends Dependency {} +>FooDependency : Symbol(FooDependency, Decl(foodep.ts, 0, 31)) +>Dependency : Symbol(Dependency, Decl(foodep.ts, 0, 8)) + +=== tests/cases/compiler/interop/bardep.ts === +import {Dependency} from "bar"; +>Dependency : Symbol(Dependency, Decl(bardep.ts, 0, 8)) + +export class BarDependency extends Dependency {} +>BarDependency : Symbol(BarDependency, Decl(bardep.ts, 0, 31)) +>Dependency : Symbol(Dependency, Decl(bardep.ts, 0, 8)) + diff --git a/tests/baselines/reference/optimizationEntrypoint7.types b/tests/baselines/reference/optimizationEntrypoint7.types new file mode 100644 index 0000000000000..363299bc0563e --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint7.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +export class Dependency {} +>Dependency : Dependency + +=== tests/cases/compiler/node_modules/bar/index.d.ts === +export class Dependency {} +>Dependency : Dependency + +=== tests/cases/compiler/main.ts === +export * from "./interop"; +export class Baz {} +>Baz : Baz + +=== tests/cases/compiler/interop/index.ts === +export * from "./foodep"; +No type information for this code.export * from "./bardep"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/interop/foodep.ts === +import {Dependency} from "foo"; +>Dependency : typeof Dependency + +export class FooDependency extends Dependency {} +>FooDependency : FooDependency +>Dependency : Dependency + +=== tests/cases/compiler/interop/bardep.ts === +import {Dependency} from "bar"; +>Dependency : typeof Dependency + +export class BarDependency extends Dependency {} +>BarDependency : BarDependency +>Dependency : Dependency + From a5b9e3a7403db80dbefe6d251047e7285cd65a53 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 14:11:41 -0700 Subject: [PATCH 39/52] handles export assignments in imports --- src/compiler/declarationEmitter.ts | 67 ++++++++++++++----- .../cases/compiler/optimizationEntrypoint8.ts | 22 ++++++ 2 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 tests/cases/compiler/optimizationEntrypoint8.ts diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 8afc189b6a337..bc249d67047ab 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -198,6 +198,7 @@ namespace ts { let aliasEmits: (() => void)[] = []; let symbolNameSet: Map = {}; let imports: Map = {}; + let importEquals: Map = {}; let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); // Handle an export=import as soon as possible @@ -221,20 +222,20 @@ namespace ts { symbolNameSet[name] = 1; symbolGeneratedNameMap[id] = name; }; - let generateName = (symbol: Symbol): string => { - if (symbol.name in symbolNameSet) { - let generatedName = `${symbol.name}_${symbolNameSet[symbol.name]}`; + let generateName = (symbol: Symbol, name: string = symbol.name): string => { + if (name in symbolNameSet) { + let generatedName = `${name}_${symbolNameSet[name]}`; while (!!symbolNameSet[generatedName]) { - generatedName = `${symbol.name}_${++symbolNameSet[symbol.name]}`; + generatedName = `${name}_${++symbolNameSet[name]}`; } - symbolNameSet[symbol.name]++; + symbolNameSet[name]++; createSymbolEntry(generatedName, symbol.id); createSyntheticIdentifiers(symbol, generatedName); return generatedName; } else { - createSymbolEntry(symbol.name, symbol.id); - return symbol.name; + createSymbolEntry(name, symbol.id); + return name; } }; let createDefaultExportAlias = (): string => { @@ -257,13 +258,11 @@ namespace ts { generateName(d.symbol); }); - // TODO: Handle external dts where we use their export= complex type (requiring `import v = require()` or `import * as v from ""`) - // TODO: Map module identifiers back to module names (rather than using absolute paths) - forEachKey(imports, filename => { + forEachKey(imports, fileName => { write("import {"); writeLine(); increaseIndent(); - forEach(imports[filename], declaration => { + forEach(imports[fileName], declaration => { let symbol = declaration.symbol; if (!symbol) { return; @@ -275,7 +274,30 @@ namespace ts { }); decreaseIndent(); // Handle module identifiers - write(filename.match(/^('|")/) ? `} from ${filename}` : `} from "${filename}"`); + write(fileName.match(/^('|")/) ? `} from ${fileName}` : `} from "${fileName}";`); + writeLine(); + }); + forEachKey(importEquals, fileName => { + let declarations = importEquals[fileName]; + let name: string; + forEach(declarations, declaration => { + let symbol = declaration.symbol; + if (name) { + createSymbolEntry(name, symbol.id); + createSyntheticIdentifiers(symbol, name); + } + else { + name = generateName(symbol, "Import"); + } + }); + if (!name) { + Debug.fail("Found dependency on an export= when flattening, but no symbols from it were used"); + } + if (fileName.match(/^('|")/)) { + write(`import * as ${name} from ${fileName};`); + } else { + write(`import * as ${name} from "${fileName}";`); + } writeLine(); }); @@ -318,7 +340,8 @@ namespace ts { writeLine(); }); decreaseIndent(); - write("}"); + write("};"); + writeLine(); } forEach(undoActions, undo => undo()); // So we don't ruin the tree @@ -499,14 +522,24 @@ namespace ts { if (isExternalModule(sourceFile)) { // First, try to reverse lookup a module identifier let fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; - imports[fileName] = imports[fileName] || []; // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) let declarationStack = findDeclarationStack(d); // Get the topmost declaration from that stack of nodes let declaration = declarationStack.pop(); - // Add that outer declaration to the list of things which need to be imported from an external source - if (!contains(imports[fileName], declaration)) { - imports[fileName].push(declaration); + // Check for an export= + if (sourceFile.symbol.exports["export="]) { + importEquals[fileName] = importEquals[fileName] || []; + // Add the declaration to the list of those refed by this file + if (!contains(importEquals[fileName], declaration)) { + importEquals[fileName].push(declaration); + } + } + else { + imports[fileName] = imports[fileName] || []; + // Add that outer declaration to the list of things which need to be imported from an external source + if (!contains(imports[fileName], declaration)) { + imports[fileName].push(declaration); + } } } else { diff --git a/tests/cases/compiler/optimizationEntrypoint8.ts b/tests/cases/compiler/optimizationEntrypoint8.ts new file mode 100644 index 0000000000000..3b51ae6380417 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint8.ts @@ -0,0 +1,22 @@ +// @module: amd +// @moduleResolution: node +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/main.ts +// @declaration: true + +// @Filename: node_modules/foo/index.d.ts +declare class Foo {} +declare namespace Foo { + export interface Bar { + member: number; + } +} +export = Foo; + + +// @Filename: main.ts +import * as Foo from "foo"; +export class Baz extends Foo implements Foo.Bar { + member = 42; +} + From 8088ebe36a428b0c668f2c715c99a0303cb1703a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 14:18:26 -0700 Subject: [PATCH 40/52] accept new baselines --- .../reference/optimizationEntrypoint1.js | 6 +- .../reference/optimizationEntrypoint4.js | 6 +- .../reference/optimizationEntrypoint6.js | 4 +- .../reference/optimizationEntrypoint7.js | 8 +- .../reference/optimizationEntrypoint8.js | 103 ++++++++++++++++++ .../reference/optimizationEntrypoint8.symbols | 35 ++++++ .../reference/optimizationEntrypoint8.types | 36 ++++++ 7 files changed, 188 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/optimizationEntrypoint8.js create mode 100644 tests/baselines/reference/optimizationEntrypoint8.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint8.types diff --git a/tests/baselines/reference/optimizationEntrypoint1.js b/tests/baselines/reference/optimizationEntrypoint1.js index 802fa52ab4092..b43cf593948ac 100644 --- a/tests/baselines/reference/optimizationEntrypoint1.js +++ b/tests/baselines/reference/optimizationEntrypoint1.js @@ -228,7 +228,8 @@ export { Inner_2 as Middle, default_2 as CBaseMain, Inner_1 as Innermost, -} +}; + //// [DtsFileErrors] @@ -324,4 +325,5 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h Inner_2 as Middle, default_2 as CBaseMain, Inner_1 as Innermost, - } \ No newline at end of file + }; + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint4.js b/tests/baselines/reference/optimizationEntrypoint4.js index 29e7b8353583d..624225108c392 100644 --- a/tests/baselines/reference/optimizationEntrypoint4.js +++ b/tests/baselines/reference/optimizationEntrypoint4.js @@ -81,7 +81,8 @@ export declare class Bar { field2: typeof Foo_1.field; } export { -} +}; + //// [DtsFileErrors] @@ -119,4 +120,5 @@ bundled.d.ts(9,20): error TS4031: Public property 'field2' of exported class has !!! error TS4031: Public property 'field2' of exported class has or is using private name 'Foo_1'. } export { - } \ No newline at end of file + }; + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint6.js b/tests/baselines/reference/optimizationEntrypoint6.js index d10c0e8bfd3ad..0a0b4f7bf68d3 100644 --- a/tests/baselines/reference/optimizationEntrypoint6.js +++ b/tests/baselines/reference/optimizationEntrypoint6.js @@ -165,10 +165,10 @@ export declare class Baz { /// import { Dependency, -} from "foo" +} from "foo"; import { Dependency as Dependency_1, -} from "bar" +} from "bar"; export declare class FooDependency extends Dependency { } export declare class BarDependency extends Dependency_1 { diff --git a/tests/baselines/reference/optimizationEntrypoint7.js b/tests/baselines/reference/optimizationEntrypoint7.js index 483052afcf67d..e374a54ac40f8 100644 --- a/tests/baselines/reference/optimizationEntrypoint7.js +++ b/tests/baselines/reference/optimizationEntrypoint7.js @@ -160,10 +160,10 @@ export declare class Baz { //// [bundled.d.ts] import { Dependency, -} from "foo" +} from "foo"; import { Dependency as Dependency_1, -} from "bar" +} from "bar"; export declare class FooDependency extends Dependency { } export declare class BarDependency extends Dependency_1 { @@ -208,12 +208,12 @@ bundled.d.ts(6,8): error TS2307: Cannot find module 'bar'. ==== bundled.d.ts (2 errors) ==== import { Dependency, - } from "foo" + } from "foo"; ~~~~~ !!! error TS2307: Cannot find module 'foo'. import { Dependency as Dependency_1, - } from "bar" + } from "bar"; ~~~~~ !!! error TS2307: Cannot find module 'bar'. export declare class FooDependency extends Dependency { diff --git a/tests/baselines/reference/optimizationEntrypoint8.js b/tests/baselines/reference/optimizationEntrypoint8.js new file mode 100644 index 0000000000000..b1973f686e6a7 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.js @@ -0,0 +1,103 @@ +//// [tests/cases/compiler/optimizationEntrypoint8.ts] //// + +//// [index.d.ts] + +declare class Foo {} +declare namespace Foo { + export interface Bar { + member: number; + } +} +export = Foo; + + +//// [main.ts] +import * as Foo from "foo"; +export class Baz extends Foo implements Foo.Bar { + member = 42; +} + + + +//// [main.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "foo"], function (require, exports, Foo) { + var Baz = (function (_super) { + __extends(Baz, _super); + function Baz() { + _super.apply(this, arguments); + this.member = 42; + } + return Baz; + })(Foo); + exports.Baz = Baz; +}); +//// [bundled.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define("tests/cases/compiler/node_modules/foo/index", ["require", "exports"], function (require, exports) { + return Foo; +}); +define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler/node_modules/foo/index"], function (require, exports, Foo) { + var Baz = (function (_super) { + __extends(Baz, _super); + function Baz() { + _super.apply(this, arguments); + this.member = 42; + } + return Baz; + })(Foo); + exports.Baz = Baz; +}); + + +//// [main.d.ts] +import * as Foo from "foo"; +export declare class Baz extends Foo implements Foo.Bar { + member: number; +} +//// [bundled.d.ts] +import * as Import from "foo"; +export declare class Baz extends Import implements Import.Bar { + member: number; +} + + +//// [DtsFileErrors] + + +bundled.d.ts(1,25): error TS2307: Cannot find module 'foo'. + + +==== tests/cases/compiler/node_modules/foo/index.d.ts (0 errors) ==== + + declare class Foo {} + declare namespace Foo { + export interface Bar { + member: number; + } + } + export = Foo; + + +==== tests/cases/compiler/main.d.ts (0 errors) ==== + import * as Foo from "foo"; + export declare class Baz extends Foo implements Foo.Bar { + member: number; + } + +==== bundled.d.ts (1 errors) ==== + import * as Import from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + export declare class Baz extends Import implements Import.Bar { + member: number; + } + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint8.symbols b/tests/baselines/reference/optimizationEntrypoint8.symbols new file mode 100644 index 0000000000000..b061741f5d615 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +>Import : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) + +declare class Foo {} +>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) + +declare namespace Foo { + export interface Bar { +>Bar : Symbol(Bar, Decl(index.d.ts, 2, 23)) + + member: number; +>member : Symbol(member, Decl(index.d.ts, 3, 23)) + } +} +export = Foo; +>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) + + +=== tests/cases/compiler/main.ts === +import * as Foo from "foo"; +>Foo : Symbol(Foo, Decl(main.ts, 0, 6)) + +export class Baz extends Foo implements Foo.Bar { +>Baz : Symbol(Baz, Decl(main.ts, 0, 27)) +>Foo : Symbol(Foo, Decl(main.ts, 0, 6)) +>Foo.Bar : Symbol(Foo.Bar, Decl(index.d.ts, 2, 23)) +>Foo : Symbol(Foo, Decl(main.ts, 0, 6)) +>Bar : Symbol(Foo.Bar, Decl(index.d.ts, 2, 23)) + + member = 42; +>member : Symbol(member, Decl(main.ts, 1, 49)) +} + + diff --git a/tests/baselines/reference/optimizationEntrypoint8.types b/tests/baselines/reference/optimizationEntrypoint8.types new file mode 100644 index 0000000000000..e87d1863831de --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +>Import : typeof Foo + +declare class Foo {} +>Foo : Foo + +declare namespace Foo { + export interface Bar { +>Bar : Bar + + member: number; +>member : number + } +} +export = Foo; +>Foo : Foo + + +=== tests/cases/compiler/main.ts === +import * as Foo from "foo"; +>Foo : typeof Foo + +export class Baz extends Foo implements Foo.Bar { +>Baz : Baz +>Foo : Foo +>Foo.Bar : any +>Foo : typeof Foo +>Bar : Foo.Bar + + member = 42; +>member : number +>42 : number +} + + From 59b8fa3017f78b9bb6c161d92c226cc3f7cc8920 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 14:18:55 -0700 Subject: [PATCH 41/52] fix lint --- src/compiler/declarationEmitter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index bc249d67047ab..bc26b213b538b 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -295,7 +295,8 @@ namespace ts { } if (fileName.match(/^('|")/)) { write(`import * as ${name} from ${fileName};`); - } else { + } + else { write(`import * as ${name} from "${fileName}";`); } writeLine(); From 1f096fc8a520e1341fa7fea1e8b52d22fd8a5627 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 20 Oct 2015 15:24:54 -0700 Subject: [PATCH 42/52] move return --- src/compiler/checker.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0c2876df122ae..e4b5c0f22efbb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2054,6 +2054,17 @@ namespace ts { function getTypeWalker(accept: (type: Type) => boolean = () => true): TypeWalker { let visited: Type[] = []; let visitedSymbols: Symbol[] = []; + + return { + visitType, + visitTypeFromSymbol, + reset: (newCallback: (type: Type) => boolean = () => true) => { + accept = newCallback; + visited = []; + visitedSymbols = []; + } + }; + function visitType(type: Type): void { if (!type) { return; @@ -2184,16 +2195,6 @@ namespace ts { forEachValue(symbol.exports, visitTypeFromSymbol); } } - - return { - visitType, - visitTypeFromSymbol, - reset: (newCallback: (type: Type) => boolean = () => true) => { - accept = newCallback; - visited = []; - visitedSymbols = []; - } - }; } function isDeclarationVisible(node: Declaration): boolean { From c9e004a17958e9937066e9217beec556dfa30629 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Oct 2015 16:25:27 -0700 Subject: [PATCH 43/52] remove extra member, move diagnostics to program --- src/compiler/checker.ts | 1 - src/compiler/declarationEmitter.ts | 5 ----- src/compiler/program.ts | 9 +++++++++ src/compiler/types.ts | 1 - 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aeb64f109f008..25d0e80164be0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15027,7 +15027,6 @@ namespace ts { return valueType; } }, - getTypeAtLocation: getTypeOfNode, resolveEntityName, getTypeWalker }; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 9c32a012b532b..069601d05a1e2 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -108,11 +108,6 @@ namespace ts { let path = compilerOptions.optimizationEntrypoint; let entrypoint = host.getSourceFile(path); if (!entrypoint) { - diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, path)); - return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; - } - if (!isExternalModule(entrypoint)) { - diagnostics.push(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, path)); return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } noDeclare = false; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7a565bacbcfa1..23799f5295bea 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1083,6 +1083,15 @@ namespace ts { if (options.optimizationEntrypoint && !(outFile && options.module)) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_with_both_options_1_and_2, "optimizationEntrypoint", "module", "outFile")); } + + let path = options.optimizationEntrypoint; + let entrypoint = getSourceFile(path); + if (!entrypoint) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_not_found, path)); + } + if (!isExternalModule(entrypoint)) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, path)); + } } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7a852164ae1a3..f768432d06a47 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1615,7 +1615,6 @@ namespace ts { getSymbolAtLocation(node: Node): Symbol; getExportsOfModule(symbol: Symbol): Symbol[]; getDefiningTypeOfSymbol(symbol: Symbol): Type; - getTypeAtLocation(node: Node): Type; resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; getTypeWalker(accept?: (type: Type) => boolean): TypeWalker; } From ef5075ba43c88ea329201a8909f0223cebb1bf77 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Oct 2015 17:06:50 -0700 Subject: [PATCH 44/52] use side table for identifiers --- src/compiler/declarationEmitter.ts | 125 ++++++++++++++++++----------- src/compiler/program.ts | 24 +++--- src/compiler/utilities.ts | 5 -- 3 files changed, 90 insertions(+), 64 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 069601d05a1e2..354e09bedaebd 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -202,17 +202,6 @@ namespace ts { return emitFlattenedTypeDefinitions(maybeRedirectionType.symbol.valueDeclaration as SourceFile); } - let createSyntheticIdentifiers = (symbol: Symbol, generatedName: string) => { - forEach(symbol.declarations, declaration => { - let synthId = createSynthesizedNode(SyntaxKind.Identifier) as Identifier; - synthId.flags |= NodeFlags.Synthetic; - synthId.text = generatedName; - synthId.parent = declaration; - let oldName = declaration.name; - undoActions.push(() => declaration.name = oldName); - declaration.name = synthId; - }); - }; let createSymbolEntry = (name: string, id: number) => { symbolNameSet[name] = 1; symbolGeneratedNameMap[id] = name; @@ -225,7 +214,6 @@ namespace ts { } symbolNameSet[name]++; createSymbolEntry(generatedName, symbol.id); - createSyntheticIdentifiers(symbol, generatedName); return generatedName; } else { @@ -279,7 +267,6 @@ namespace ts { let symbol = declaration.symbol; if (name) { createSymbolEntry(name, symbol.id); - createSyntheticIdentifiers(symbol, name); } else { name = generateName(symbol, "Import"); @@ -413,7 +400,7 @@ namespace ts { Debug.fail("Encountered export alias of untraversed type when flattening."); } write(" as "); - writeTextOfNode(currentSourceFile, d.name); + emitIdentifier(d.name); currentSourceFile = oldSourceFile; })(d)); } @@ -465,7 +452,6 @@ namespace ts { let symbol = type.symbol; if (symbol) { createSymbolEntry(name, symbol.id); - createSyntheticIdentifiers(symbol, name); } return name; })(exported, type); @@ -481,13 +467,6 @@ namespace ts { if (type.symbol) { let symbol = type.symbol; - if (symbol.name !== exported.name) { - // check if this symbol is defined by another exported symbol - if (!contains(exportedMembers, symbol)) { - // If not, mangle its name to the exported symbol's name - createSyntheticIdentifiers(symbol, exported.name); - } - } createSymbolEntry(symbol.name, symbol.id); } createSymbolEntry(exported.name, exported.id); @@ -840,14 +819,14 @@ namespace ts { return; } if (entityName.kind === SyntaxKind.Identifier) { - writeTextOfNode(currentSourceFile, entityName); + emitIdentifier(entityName as Identifier); } else { let left = entityName.kind === SyntaxKind.QualifiedName ? (entityName).left : (entityName).expression; let right = entityName.kind === SyntaxKind.QualifiedName ? (entityName).right : (entityName).name; writeEntityName(left); write("."); - writeTextOfNode(currentSourceFile, right); + emitIdentifier(right); } } @@ -882,7 +861,7 @@ namespace ts { } function emitTypePredicate(type: TypePredicateNode) { - writeTextOfNode(currentSourceFile, type.parameterName); + emitIdentifier(type.parameterName); write(" is "); emitType(type.type); } @@ -957,7 +936,7 @@ namespace ts { function emitExportAssignment(node: ExportAssignment) { if (node.expression.kind === SyntaxKind.Identifier) { write(node.isExportEquals ? "export = " : "export default "); - writeTextOfNode(currentSourceFile, node.expression); + emitIdentifier(node.expression as Identifier); } else { // Expression @@ -1096,7 +1075,7 @@ namespace ts { write("export "); } write("import "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); write(" = "); if (isInternalModuleImportEqualsDeclaration(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError); @@ -1142,7 +1121,7 @@ namespace ts { if (node.importClause) { let currentWriterPos = writer.getTextPos(); if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) { - writeTextOfNode(currentSourceFile, node.importClause.name); + emitIdentifier(node.importClause.name); } if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) { if (currentWriterPos !== writer.getTextPos()) { @@ -1151,7 +1130,7 @@ namespace ts { } if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { write("* as "); - writeTextOfNode(currentSourceFile, (node.importClause.namedBindings).name); + emitIdentifier((node.importClause.namedBindings as NamespaceImport).name); } else { write("{ "); @@ -1181,15 +1160,20 @@ namespace ts { } } - writeTextOfNode(currentSourceFile, moduleSpecifier); + if (moduleSpecifier.kind === SyntaxKind.Identifier) { + emitIdentifier(moduleSpecifier as Identifier); + } + else { + writeTextOfNode(currentSourceFile, moduleSpecifier); + } } function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) { if (node.propertyName) { - writeTextOfNode(currentSourceFile, node.propertyName); + emitIdentifier(node.propertyName); write(" as "); } - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); } function emitExportSpecifier(node: ExportSpecifier) { @@ -1230,11 +1214,21 @@ namespace ts { else { write("module "); } - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } while (node.body.kind !== SyntaxKind.ModuleBlock) { node = node.body; write("."); - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } } let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; @@ -1254,7 +1248,7 @@ namespace ts { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("type "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); emitTypeParameters(node.typeParameters); write(" = "); emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError); @@ -1278,7 +1272,7 @@ namespace ts { write("const "); } write("enum "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); write(" {"); writeLine(); increaseIndent(); @@ -1290,7 +1284,12 @@ namespace ts { function emitEnumMemberDeclaration(node: EnumMember) { emitJsDocComments(node); - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } let enumMemberValue = resolver.getConstantValue(node); if (enumMemberValue !== undefined) { write(" = "); @@ -1309,7 +1308,7 @@ namespace ts { increaseIndent(); emitJsDocComments(node); decreaseIndent(); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); // If there is constraint present and this is not a type parameter of the private method emit the constraint if (node.constraint && !isPrivateMethodTypeParameter(node)) { write(" extends "); @@ -1440,7 +1439,7 @@ namespace ts { } write("class "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitTypeParameters(node.typeParameters); @@ -1464,7 +1463,7 @@ namespace ts { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("interface "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitTypeParameters(node.typeParameters); @@ -1502,7 +1501,12 @@ namespace ts { // If this node is a computed name, it can only be a symbol, because we've already skipped // it if it's not a well known symbol. In that case, the text of the name will be exactly // what we want, namely the name expression enclosed in brackets. - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + emitBindingPattern(node.name as BindingPattern); + } // If optional property emit ? if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) { write("?"); @@ -1589,7 +1593,7 @@ namespace ts { emitBindingPattern(bindingElement.name); } else { - writeTextOfNode(currentSourceFile, bindingElement.name); + emitIdentifier(bindingElement.name as Identifier); writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError); } } @@ -1639,7 +1643,12 @@ namespace ts { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); emitClassMemberDeclarationFlags(node); - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } if (!(node.flags & NodeFlags.Private)) { accessorWithTypeAnnotation = node; let type = getTypeAnnotationFromAccessor(node); @@ -1729,13 +1738,23 @@ namespace ts { } if (node.kind === SyntaxKind.FunctionDeclaration) { write("function "); - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } } else if (node.kind === SyntaxKind.Constructor) { write("constructor"); } else { - writeTextOfNode(currentSourceFile, node.name); + if (node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } if (hasQuestionToken(node)) { write("?"); } @@ -1875,7 +1894,7 @@ namespace ts { emitBindingPattern(node.name); } else { - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name as Identifier); } if (resolver.isOptionalParameter(node)) { write("?"); @@ -2001,7 +2020,7 @@ namespace ts { // Example: // original: function foo({y: [a,b,c]}) {} // emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void; - writeTextOfNode(currentSourceFile, bindingElement.propertyName); + emitIdentifier(bindingElement.propertyName); write(": "); } if (bindingElement.name) { @@ -2024,13 +2043,23 @@ namespace ts { if (bindingElement.dotDotDotToken) { write("..."); } - writeTextOfNode(currentSourceFile, bindingElement.name); + emitIdentifier(bindingElement.name as Identifier); } } } } } + function emitIdentifier(node: Identifier) { + let symbol = resolver.getSymbolAtLocation(node); + if (symbol && symbol.id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbol.id]); + } + else { + writeTextOfNode(currentSourceFile, node); + } + } + function emitNode(node: Node) { switch (node.kind) { case SyntaxKind.FunctionDeclaration: diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 23799f5295bea..331b6f783787f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1079,18 +1079,20 @@ namespace ts { !options.experimentalDecorators) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators")); } - - if (options.optimizationEntrypoint && !(outFile && options.module)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_with_both_options_1_and_2, "optimizationEntrypoint", "module", "outFile")); - } - let path = options.optimizationEntrypoint; - let entrypoint = getSourceFile(path); - if (!entrypoint) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_not_found, path)); - } - if (!isExternalModule(entrypoint)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, path)); + let entrypointPath = options.optimizationEntrypoint; + if (entrypointPath) { + if (entrypointPath && !(outFile && options.module)) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_with_both_options_1_and_2, "optimizationEntrypoint", "module", "outFile")); + } + + let entrypoint = getSourceFile(entrypointPath); + if (!entrypoint) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_not_found, entrypointPath)); + } + if (!isExternalModule(entrypoint)) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_a_module, entrypointPath)); + } } } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index fd7983b6b8520..24916c2e1060f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -13,7 +13,6 @@ namespace ts { leadingCommentRanges?: CommentRange[]; trailingCommentRanges?: CommentRange[]; startsOnNewLine: boolean; - text?: string; } export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration { @@ -1739,10 +1738,6 @@ namespace ts { } function writeTextOfNode(sourceFile: SourceFile, node: Node) { - if (node && node.flags & NodeFlags.Synthetic) { - write((node as SynthesizedNode).text); - return; - } write(getSourceTextOfNodeFromSourceFile(sourceFile, node)); } From cc7a7345fd5360d04b6321f74bffe7aa6a9cab22 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Oct 2015 17:09:44 -0700 Subject: [PATCH 45/52] derive import equals name from module name --- src/compiler/declarationEmitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 354e09bedaebd..585670bee6e51 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -269,7 +269,7 @@ namespace ts { createSymbolEntry(name, symbol.id); } else { - name = generateName(symbol, "Import"); + name = generateName(symbol, makeIdentifierFromModuleName(fileName)); } }); if (!name) { From e6b1ae814aca52ddc94ba2b879c0186a16d17403 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Oct 2015 18:31:16 -0700 Subject: [PATCH 46/52] fixup the bits, add another test, and accpt the new baselines --- src/compiler/declarationEmitter.ts | 25 ++- src/compiler/program.ts | 2 +- .../reference/optimizationEntrypoint1.symbols | 10 +- .../reference/optimizationEntrypoint1.types | 16 +- .../reference/optimizationEntrypoint4.symbols | 3 +- .../reference/optimizationEntrypoint4.types | 3 +- .../reference/optimizationEntrypoint7.js | 4 +- .../reference/optimizationEntrypoint8.js | 14 +- .../reference/optimizationEntrypoint8.symbols | 4 +- .../reference/optimizationEntrypoint8.types | 4 +- .../reference/optimizationEntrypoint9.js | 166 ++++++++++++++++++ .../reference/optimizationEntrypoint9.symbols | 50 ++++++ .../reference/optimizationEntrypoint9.types | 50 ++++++ .../cases/compiler/optimizationEntrypoint9.ts | 33 ++++ 14 files changed, 342 insertions(+), 42 deletions(-) create mode 100644 tests/baselines/reference/optimizationEntrypoint9.js create mode 100644 tests/baselines/reference/optimizationEntrypoint9.symbols create mode 100644 tests/baselines/reference/optimizationEntrypoint9.types create mode 100644 tests/cases/compiler/optimizationEntrypoint9.ts diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 8a0648cbc5f27..4c648413ac4be 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -179,7 +179,7 @@ namespace ts { let referencedFile = tryResolveScriptReference(host, sourceFile, fileReference); // If the reference file is a declaration file or an external module, emit that reference - if (referencedFile && (isDeclaration(referencedFile) && + if (referencedFile && (isDeclarationFile(referencedFile) && !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted writeReferencePath(referencedFile); @@ -1215,7 +1215,7 @@ namespace ts { else { write("module "); } - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name); } else { @@ -1224,7 +1224,7 @@ namespace ts { while (node.body.kind !== SyntaxKind.ModuleBlock) { node = node.body; write("."); - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name); } else { @@ -1285,7 +1285,7 @@ namespace ts { function emitEnumMemberDeclaration(node: EnumMember) { emitJsDocComments(node); - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name as Identifier); } else { @@ -1502,12 +1502,8 @@ namespace ts { // If this node is a computed name, it can only be a symbol, because we've already skipped // it if it's not a well known symbol. In that case, the text of the name will be exactly // what we want, namely the name expression enclosed in brackets. - if (node.name.kind === SyntaxKind.Identifier) { - emitIdentifier(node.name as Identifier); - } - else { - emitBindingPattern(node.name as BindingPattern); - } + emitIdentifier(node.name as Identifier); + // If optional property emit ? if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) { write("?"); @@ -1644,7 +1640,7 @@ namespace ts { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); emitClassMemberDeclarationFlags(node); - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name as Identifier); } else { @@ -1739,7 +1735,7 @@ namespace ts { } if (node.kind === SyntaxKind.FunctionDeclaration) { write("function "); - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name as Identifier); } else { @@ -1750,7 +1746,7 @@ namespace ts { write("constructor"); } else { - if (node.name.kind === SyntaxKind.Identifier) { + if (node.name && node.name.kind === SyntaxKind.Identifier) { emitIdentifier(node.name as Identifier); } else { @@ -2052,6 +2048,9 @@ namespace ts { } function emitIdentifier(node: Identifier) { + if (!node) { + return; + } let symbol = resolver.getSymbolAtLocation(node); if (symbol && symbol.id in symbolGeneratedNameMap) { write(symbolGeneratedNameMap[symbol.id]); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 331b6f783787f..836d3586c8ae3 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1079,7 +1079,7 @@ namespace ts { !options.experimentalDecorators) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators")); } - + let entrypointPath = options.optimizationEntrypoint; if (entrypointPath) { if (entrypointPath && !(outFile && options.module)) { diff --git a/tests/baselines/reference/optimizationEntrypoint1.symbols b/tests/baselines/reference/optimizationEntrypoint1.symbols index 2573d492487aa..e2b007bb1f6f6 100644 --- a/tests/baselines/reference/optimizationEntrypoint1.symbols +++ b/tests/baselines/reference/optimizationEntrypoint1.symbols @@ -43,9 +43,9 @@ import {default as BaseMain, Inner as Middle} from "./b"; >BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) >Inner : Symbol(Middle, Decl(a.ts, 0, 28)) >Middle : Symbol(Middle, Decl(a.ts, 0, 28)) ->default_1_1 : Symbol((Missing), Decl(a.ts, 0, 57)) export default class Main extends BaseMain { +>Main : Symbol(Main, Decl(a.ts, 0, 57)) >BaseMain : Symbol(BaseMain, Decl(a.ts, 0, 8)) memberc: Middle; @@ -66,7 +66,6 @@ import {default as BaseMain, Inner as Innermost} from "./c"; >BaseMain : Symbol(BaseMain, Decl(b.ts, 0, 8)) >Inner : Symbol(Innermost, Decl(b.ts, 0, 28)) >Innermost : Symbol(Innermost, Decl(b.ts, 0, 28)) ->Inner_2 : Symbol((Missing), Decl(b.ts, 5, 1)) export default class Main extends BaseMain { >Main : Symbol(Main, Decl(b.ts, 0, 60)) @@ -82,6 +81,8 @@ export default class Main extends BaseMain { } export interface Inner { +>Inner : Symbol(Inner, Decl(b.ts, 5, 1)) + item2: number; >item2 : Symbol(item2, Decl(b.ts, 7, 24)) } @@ -95,14 +96,15 @@ export interface Detail { === tests/cases/compiler/c.ts === export default class Main { ->default_2 : Symbol((Missing), Decl(c.ts, 0, 0)) ->Inner_1 : Symbol((Missing), Decl(c.ts, 2, 1)) +>Main : Symbol(Main, Decl(c.ts, 0, 0)) member1: string; >member1 : Symbol(member1, Decl(c.ts, 0, 27)) } export interface Inner { +>Inner : Symbol(Inner, Decl(c.ts, 2, 1)) + item: number; >item : Symbol(item, Decl(c.ts, 4, 24)) } diff --git a/tests/baselines/reference/optimizationEntrypoint1.types b/tests/baselines/reference/optimizationEntrypoint1.types index 87dd10efdcf9c..b804789c5dff4 100644 --- a/tests/baselines/reference/optimizationEntrypoint1.types +++ b/tests/baselines/reference/optimizationEntrypoint1.types @@ -29,13 +29,13 @@ export {default as BBaseMain, Inner as Middle} from "./b"; >Middle : any export {default as CBaseMain, Inner as Innermost} from "./c"; ->default : typeof (Missing) ->CBaseMain : typeof (Missing) +>default : typeof Main +>CBaseMain : typeof Main >Inner : any >Innermost : any export {default} from "./a"; ->default : typeof (Missing) +>default : typeof Main === tests/cases/compiler/a.ts === import {default as BaseMain, Inner as Middle} from "./b"; @@ -43,9 +43,9 @@ import {default as BaseMain, Inner as Middle} from "./b"; >BaseMain : typeof BaseMain >Inner : any >Middle : any ->default_1_1 : (Missing) export default class Main extends BaseMain { +>Main : Main >BaseMain : BaseMain memberc: Middle; @@ -66,7 +66,6 @@ import {default as BaseMain, Inner as Innermost} from "./c"; >BaseMain : typeof BaseMain >Inner : any >Innermost : any ->Inner_2 : (Missing) export default class Main extends BaseMain { >Main : Main @@ -82,6 +81,8 @@ export default class Main extends BaseMain { } export interface Inner { +>Inner : Inner + item2: number; >item2 : number } @@ -95,14 +96,15 @@ export interface Detail { === tests/cases/compiler/c.ts === export default class Main { ->default_2 : (Missing) ->Inner_1 : (Missing) +>Main : Main member1: string; >member1 : string } export interface Inner { +>Inner : Inner + item: number; >item : number } diff --git a/tests/baselines/reference/optimizationEntrypoint4.symbols b/tests/baselines/reference/optimizationEntrypoint4.symbols index 34d503834eec6..4fab89df71d53 100644 --- a/tests/baselines/reference/optimizationEntrypoint4.symbols +++ b/tests/baselines/reference/optimizationEntrypoint4.symbols @@ -15,8 +15,6 @@ export class Bar { === tests/cases/compiler/foo.ts === ->Foo_1 : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) - class Foo { >Foo : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) @@ -26,6 +24,7 @@ class Foo { } namespace Foo {} +>Foo : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) export = Foo; >Foo : Symbol(Foo, Decl(foo.ts, 0, 0), Decl(foo.ts, 3, 1)) diff --git a/tests/baselines/reference/optimizationEntrypoint4.types b/tests/baselines/reference/optimizationEntrypoint4.types index 5dbc10fc5292a..e3a5beed84741 100644 --- a/tests/baselines/reference/optimizationEntrypoint4.types +++ b/tests/baselines/reference/optimizationEntrypoint4.types @@ -15,8 +15,6 @@ export class Bar { === tests/cases/compiler/foo.ts === ->Foo_1 : typeof Foo - class Foo { >Foo : Foo @@ -26,6 +24,7 @@ class Foo { } namespace Foo {} +>Foo : typeof Foo export = Foo; >Foo : Foo diff --git a/tests/baselines/reference/optimizationEntrypoint7.js b/tests/baselines/reference/optimizationEntrypoint7.js index e374a54ac40f8..55ef3b96abc57 100644 --- a/tests/baselines/reference/optimizationEntrypoint7.js +++ b/tests/baselines/reference/optimizationEntrypoint7.js @@ -101,7 +101,7 @@ define("tests/cases/compiler/node_modules/bar/index", ["require", "exports"], fu })(); exports.Dependency = Dependency; }); -define("tests/cases/compiler/interop/foodep", ["require", "exports", "tests/cases/compiler/node_modules/foo/index"], function (require, exports, foo_1) { +define("tests/cases/compiler/interop/foodep", ["require", "exports", "foo"], function (require, exports, foo_1) { var FooDependency = (function (_super) { __extends(FooDependency, _super); function FooDependency() { @@ -111,7 +111,7 @@ define("tests/cases/compiler/interop/foodep", ["require", "exports", "tests/case })(foo_1.Dependency); exports.FooDependency = FooDependency; }); -define("tests/cases/compiler/interop/bardep", ["require", "exports", "tests/cases/compiler/node_modules/bar/index"], function (require, exports, bar_1) { +define("tests/cases/compiler/interop/bardep", ["require", "exports", "bar"], function (require, exports, bar_1) { var BarDependency = (function (_super) { __extends(BarDependency, _super); function BarDependency() { diff --git a/tests/baselines/reference/optimizationEntrypoint8.js b/tests/baselines/reference/optimizationEntrypoint8.js index b1973f686e6a7..dc5e0195b79e6 100644 --- a/tests/baselines/reference/optimizationEntrypoint8.js +++ b/tests/baselines/reference/optimizationEntrypoint8.js @@ -45,7 +45,7 @@ var __extends = (this && this.__extends) || function (d, b) { define("tests/cases/compiler/node_modules/foo/index", ["require", "exports"], function (require, exports) { return Foo; }); -define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler/node_modules/foo/index"], function (require, exports, Foo) { +define("tests/cases/compiler/main", ["require", "exports", "foo"], function (require, exports, Foo) { var Baz = (function (_super) { __extends(Baz, _super); function Baz() { @@ -64,8 +64,8 @@ export declare class Baz extends Foo implements Foo.Bar { member: number; } //// [bundled.d.ts] -import * as Import from "foo"; -export declare class Baz extends Import implements Import.Bar { +import * as foo from "foo"; +export declare class Baz extends foo implements foo.Bar { member: number; } @@ -73,7 +73,7 @@ export declare class Baz extends Import implements Import.Bar { //// [DtsFileErrors] -bundled.d.ts(1,25): error TS2307: Cannot find module 'foo'. +bundled.d.ts(1,22): error TS2307: Cannot find module 'foo'. ==== tests/cases/compiler/node_modules/foo/index.d.ts (0 errors) ==== @@ -94,10 +94,10 @@ bundled.d.ts(1,25): error TS2307: Cannot find module 'foo'. } ==== bundled.d.ts (1 errors) ==== - import * as Import from "foo"; - ~~~~~ + import * as foo from "foo"; + ~~~~~ !!! error TS2307: Cannot find module 'foo'. - export declare class Baz extends Import implements Import.Bar { + export declare class Baz extends foo implements foo.Bar { member: number; } \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint8.symbols b/tests/baselines/reference/optimizationEntrypoint8.symbols index b061741f5d615..a14287ca97d4e 100644 --- a/tests/baselines/reference/optimizationEntrypoint8.symbols +++ b/tests/baselines/reference/optimizationEntrypoint8.symbols @@ -1,11 +1,11 @@ === tests/cases/compiler/node_modules/foo/index.d.ts === ->Import : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) - declare class Foo {} >Foo : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) declare namespace Foo { +>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 1, 20)) + export interface Bar { >Bar : Symbol(Bar, Decl(index.d.ts, 2, 23)) diff --git a/tests/baselines/reference/optimizationEntrypoint8.types b/tests/baselines/reference/optimizationEntrypoint8.types index e87d1863831de..8f62375c9c079 100644 --- a/tests/baselines/reference/optimizationEntrypoint8.types +++ b/tests/baselines/reference/optimizationEntrypoint8.types @@ -1,11 +1,11 @@ === tests/cases/compiler/node_modules/foo/index.d.ts === ->Import : typeof Foo - declare class Foo {} >Foo : Foo declare namespace Foo { +>Foo : typeof Foo + export interface Bar { >Bar : Bar diff --git a/tests/baselines/reference/optimizationEntrypoint9.js b/tests/baselines/reference/optimizationEntrypoint9.js new file mode 100644 index 0000000000000..f443b176899ea --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint9.js @@ -0,0 +1,166 @@ +//// [tests/cases/compiler/optimizationEntrypoint9.ts] //// + +//// [a.ts] + +/// +export class A { + member: typeof GlobalFoo; +} + +//// [b.ts] +/// +class Foo { + member: Bar; +} +declare var GlobalFoo: Foo; + +//// [c.d.ts] +/// +declare class Bar { + member: Baz; +} + +//// [d.d.ts] +declare class Baz { + member: number; +} + +//// [b.ts] +import {A} from "./ref/a"; +export class B extends A { } + + +//// [a.js] +define(["require", "exports"], function (require, exports) { + /// + var A = (function () { + function A() { + } + return A; + })(); + exports.A = A; +}); +//// [b.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +define(["require", "exports", "./ref/a"], function (require, exports, a_1) { + var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; + })(a_1.A); + exports.B = B; +}); +//// [all.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/// +var Foo = (function () { + function Foo() { + } + return Foo; +})(); +define("tests/cases/compiler/ref/a", ["require", "exports"], function (require, exports) { + /// + var A = (function () { + function A() { + } + return A; + })(); + exports.A = A; +}); +define("tests/cases/compiler/b", ["require", "exports", "tests/cases/compiler/ref/a"], function (require, exports, a_1) { + var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; + })(a_1.A); + exports.B = B; +}); + + +//// [a.d.ts] +/// +export declare class A { + member: typeof GlobalFoo; +} +//// [b.d.ts] +import { A } from "./ref/a"; +export declare class B extends A { +} +//// [all.d.ts] +/// +declare class A { + member: typeof GlobalFoo; +} +declare class Foo { + member: Bar; +} +export declare class B extends A { +} +export { +}; + + +//// [DtsFileErrors] + + +all.d.ts(3,20): error TS2304: Cannot find name 'GlobalFoo'. +all.d.ts(8,32): error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. +tests/cases/compiler/ref/a.d.ts(3,20): error TS2304: Cannot find name 'GlobalFoo'. +tests/cases/compiler/ref/a.d.ts(3,20): error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. + + +==== tests/cases/compiler/ref/a.d.ts (2 errors) ==== + /// + export declare class A { + member: typeof GlobalFoo; + ~~~~~~~~~ +!!! error TS2304: Cannot find name 'GlobalFoo'. + ~~~~~~~~~ +!!! error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. + } + +==== all.d.ts (2 errors) ==== + /// + declare class A { + member: typeof GlobalFoo; + ~~~~~~~~~ +!!! error TS2304: Cannot find name 'GlobalFoo'. + } + declare class Foo { + member: Bar; + } + export declare class B extends A { + ~ +!!! error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. + } + export { + }; + +==== tests/cases/compiler/ref/c.d.ts (0 errors) ==== + /// + declare class Bar { + member: Baz; + } + +==== tests/cases/compiler/ref/d.d.ts (0 errors) ==== + declare class Baz { + member: number; + } + +==== tests/cases/compiler/b.d.ts (0 errors) ==== + import { A } from "./ref/a"; + export declare class B extends A { + } + \ No newline at end of file diff --git a/tests/baselines/reference/optimizationEntrypoint9.symbols b/tests/baselines/reference/optimizationEntrypoint9.symbols new file mode 100644 index 0000000000000..f8d550aedb652 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint9.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/ref/a.ts === + +/// +export class A { +>A : Symbol(A, Decl(a.ts, 0, 0)) + + member: typeof GlobalFoo; +>member : Symbol(member, Decl(a.ts, 2, 16)) +>GlobalFoo : Symbol(GlobalFoo, Decl(b.ts, 4, 11)) +} + +=== tests/cases/compiler/ref/b.ts === +/// +class Foo { +>Foo : Symbol(Foo, Decl(b.ts, 0, 0)) + + member: Bar; +>member : Symbol(member, Decl(b.ts, 1, 11)) +>Bar : Symbol(Bar, Decl(c.d.ts, 0, 0)) +} +declare var GlobalFoo: Foo; +>GlobalFoo : Symbol(GlobalFoo, Decl(b.ts, 4, 11)) +>Foo : Symbol(Foo, Decl(b.ts, 0, 0)) + +=== tests/cases/compiler/ref/c.d.ts === +/// +declare class Bar { +>Bar : Symbol(Bar, Decl(c.d.ts, 0, 0)) + + member: Baz; +>member : Symbol(member, Decl(c.d.ts, 1, 19)) +>Baz : Symbol(Baz, Decl(d.d.ts, 0, 0)) +} + +=== tests/cases/compiler/ref/d.d.ts === +declare class Baz { +>Baz : Symbol(Baz, Decl(d.d.ts, 0, 0)) + + member: number; +>member : Symbol(member, Decl(d.d.ts, 0, 19)) +} + +=== tests/cases/compiler/b.ts === +import {A} from "./ref/a"; +>A : Symbol(A, Decl(b.ts, 0, 8)) + +export class B extends A { } +>B : Symbol(B, Decl(b.ts, 0, 26)) +>A : Symbol(A, Decl(b.ts, 0, 8)) + diff --git a/tests/baselines/reference/optimizationEntrypoint9.types b/tests/baselines/reference/optimizationEntrypoint9.types new file mode 100644 index 0000000000000..917704cce5abc --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint9.types @@ -0,0 +1,50 @@ +=== tests/cases/compiler/ref/a.ts === + +/// +export class A { +>A : A + + member: typeof GlobalFoo; +>member : Foo +>GlobalFoo : Foo +} + +=== tests/cases/compiler/ref/b.ts === +/// +class Foo { +>Foo : Foo + + member: Bar; +>member : Bar +>Bar : Bar +} +declare var GlobalFoo: Foo; +>GlobalFoo : Foo +>Foo : Foo + +=== tests/cases/compiler/ref/c.d.ts === +/// +declare class Bar { +>Bar : Bar + + member: Baz; +>member : Baz +>Baz : Baz +} + +=== tests/cases/compiler/ref/d.d.ts === +declare class Baz { +>Baz : Baz + + member: number; +>member : number +} + +=== tests/cases/compiler/b.ts === +import {A} from "./ref/a"; +>A : typeof A + +export class B extends A { } +>B : B +>A : A + diff --git a/tests/cases/compiler/optimizationEntrypoint9.ts b/tests/cases/compiler/optimizationEntrypoint9.ts new file mode 100644 index 0000000000000..845da96150730 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint9.ts @@ -0,0 +1,33 @@ +// @target: ES5 +// @declaration: true +// @module: amd +// @outFile: all.js +// @optimizationEntrypoint: tests/cases/compiler/b.ts + +// @Filename: ref/a.ts +/// +export class A { + member: typeof GlobalFoo; +} + +// @Filename: ref/b.ts +/// +class Foo { + member: Bar; +} +declare var GlobalFoo: Foo; + +// @Filename: ref/c.d.ts +/// +declare class Bar { + member: Baz; +} + +// @Filename: ref/d.d.ts +declare class Baz { + member: number; +} + +// @Filename: b.ts +import {A} from "./ref/a"; +export class B extends A { } From 5d6b1d500102027cdcffcec20bb2db6ae3e9f013 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 22 Oct 2015 18:30:12 -0700 Subject: [PATCH 47/52] typeWalker -> symbolWalker, handle type queries better --- src/compiler/checker.ts | 48 +++++++----- src/compiler/declarationEmitter.ts | 119 +++++++++++++++-------------- src/compiler/types.ts | 8 +- 3 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 25d0e80164be0..4446c86e30ddc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -95,7 +95,7 @@ namespace ts { getJsxElementAttributesType, getJsxIntrinsicTagNames, isOptionalParameter, - getTypeWalker + getSymbolWalker }; let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); @@ -2051,14 +2051,14 @@ namespace ts { }); } - function getTypeWalker(accept: (type: Type) => boolean = () => true): TypeWalker { + function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker { let visited: Type[] = []; let visitedSymbols: Symbol[] = []; return { visitType, visitTypeFromSymbol, - reset: (newCallback: (type: Type) => boolean = () => true) => { + reset: (newCallback: (symbol: Symbol) => boolean = () => true) => { accept = newCallback; visited = []; visitedSymbols = []; @@ -2073,8 +2073,10 @@ namespace ts { return; } visited.push(type); - if (!accept(type)) { - return; + if (type.symbol) { + if (!accept(type.symbol)) { + return; + } } // Visit the type's related types, if any @@ -2177,23 +2179,33 @@ namespace ts { return; } visitedSymbols.push(symbol); + if (!accept(symbol)) { + return; + } let t = getTypeOfSymbol(symbol); visitType(t); // Should handle members on classes and such - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { - let signatures = getSignaturesOfType(t, SignatureKind.Call); - for (let signature of signatures) { - visitSignature(signature); - } - } - if (symbol.flags & SymbolFlags.Class) { - let signatures = getSignaturesOfType(t, SignatureKind.Construct); - for (let signature of signatures) { - visitSignature(signature); - } - } if (symbol.flags & SymbolFlags.HasExports) { forEachValue(symbol.exports, visitTypeFromSymbol); } + forEach(symbol.declarations, d => { + // Type queries are too far resolved when we just visit the symbol's type + // So to get the intervening symbols, we need to check if there's a type + // query node on any of the symbol's declarations and get symbols there + if ((d as any).type && (d as any).type.kind === SyntaxKind.TypeQuery) { + let query = (d as any).type as TypeQueryNode; + let entity = leftmostSymbol(query.exprName); + visitTypeFromSymbol(entity); + } + }); + + function leftmostSymbol(expr: QualifiedName | Identifier): Symbol { + if (expr.kind === SyntaxKind.Identifier) { + return getResolvedSymbol(expr as Identifier); + } + else { + return leftmostSymbol((expr as QualifiedName).left); + } + } } } @@ -15028,7 +15040,7 @@ namespace ts { } }, resolveEntityName, - getTypeWalker + getSymbolWalker }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 4c648413ac4be..218fa3b8266b5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -288,6 +288,9 @@ namespace ts { let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { let realSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); + if (d.kind === SyntaxKind.VariableDeclaration) { + d = d.parent.parent as Declaration; + } let oldFlags = d.flags; if (shouldExport) { d.flags |= NodeFlags.Export; @@ -356,6 +359,7 @@ namespace ts { case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.FunctionDeclaration: case SyntaxKind.VariableStatement: + case SyntaxKind.VariableDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: @@ -477,75 +481,74 @@ namespace ts { function collectDependentDeclarations(exportedMembers: Symbol[]): Map { const dependentDeclarations: Map = {}; - const walker = resolver.getTypeWalker(inspectType); + const walker = resolver.getSymbolWalker(inspectSymbol); forEach(exportedMembers, symbol => walker.visitTypeFromSymbol(symbol)); return dependentDeclarations; - function inspectType(type: Type): boolean { - let symbol = type.symbol; - if (symbol) { - if (symbol.valueDeclaration && symbol.valueDeclaration.flags && symbol.valueDeclaration.flags & NodeFlags.Private) { - return false; - } - else { - // Add containing declarations if we've navigated to a nested type. - forEach(symbol.declarations, d => { - // Collect declarations - let sourceFile = getSourceFileOfNode(d); - if (isDeclarationFile(sourceFile)) { - // If the declaration is from an external module dts, we need to create an import for it - if (isExternalModule(sourceFile)) { - // First, try to reverse lookup a module identifier - let fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; - // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) - let declarationStack = findDeclarationStack(d); - // Get the topmost declaration from that stack of nodes - let declaration = declarationStack.pop(); - // Check for an export= - if (sourceFile.symbol.exports["export="]) { - importEquals[fileName] = importEquals[fileName] || []; - // Add the declaration to the list of those refed by this file - if (!contains(importEquals[fileName], declaration)) { - importEquals[fileName].push(declaration); - } - } - else { - imports[fileName] = imports[fileName] || []; - // Add that outer declaration to the list of things which need to be imported from an external source - if (!contains(imports[fileName], declaration)) { - imports[fileName].push(declaration); - } + function inspectSymbol(symbol: Symbol): boolean { + if (symbol.valueDeclaration && symbol.valueDeclaration.flags && symbol.valueDeclaration.flags & NodeFlags.Private) { + return false; + } + else { + // Add containing declarations if we've navigated to a nested type. + forEach(symbol.declarations, d => { + // Collect declarations + let sourceFile = getSourceFileOfNode(d); + // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) + let declarationStack = findDeclarationStack(d); + if (isDeclarationFile(sourceFile)) { + // If the declaration is from an external module dts, we need to create an import for it + if (isExternalModule(sourceFile)) { + // First, try to reverse lookup a module identifier + let fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; + // Get the topmost declaration from that stack of nodes + let declaration = declarationStack.pop(); + // Check for an export= + if (sourceFile.symbol.exports["export="]) { + importEquals[fileName] = importEquals[fileName] || []; + // Add the declaration to the list of those refed by this file + if (!contains(importEquals[fileName], declaration)) { + importEquals[fileName].push(declaration); } } else { - let declarationStack = findDeclarationStack(d); - // Check if this type comes from an ambient external module declaration - let moduleDeclaration = declarationStack.pop(); - if (moduleDeclaration.kind === SyntaxKind.ModuleDeclaration) { - // If so, add said ambient external module to the imports list, and the next declaration in the stack to the set of imports - let declaration = declarationStack.pop(); - let moduleName = (moduleDeclaration as ModuleDeclaration).name.text; - imports[moduleName] = imports[moduleName] || []; - if (!contains(imports[moduleName], declaration)) { - imports[moduleName].push(declaration); - } + imports[fileName] = imports[fileName] || []; + // Add that outer declaration to the list of things which need to be imported from an external source + if (!contains(imports[fileName], declaration)) { + imports[fileName].push(declaration); } } - // Otherwise we can elide it, as its from the stdlib or a triple-slash reference - return; } - if (!(d.id in dependentDeclarations || d.id in declarations) && isModuleLevelDeclaration(d)) { - // Don't need to collect declarations which are not module-level - dependentDeclarations[d.id] = d; - } - let containingDeclaration: Node = d; - while ((containingDeclaration = containingDeclaration.parent) && (!containingDeclaration.symbol || !(containingDeclaration.symbol.flags & (SymbolFlags.HasMembers | SymbolFlags.HasExports)))); - if (containingDeclaration && containingDeclaration !== d && containingDeclaration.symbol && containingDeclaration.kind !== SyntaxKind.SourceFile && containingDeclaration.kind !== SyntaxKind.ModuleDeclaration) { - walker.visitTypeFromSymbol(containingDeclaration.symbol); + else { + // Check if this type comes from an ambient external module declaration + let moduleDeclaration = declarationStack.pop(); + if (moduleDeclaration.kind === SyntaxKind.ModuleDeclaration) { + // If so, add said ambient external module to the imports list, and the next declaration in the stack to the set of imports + let declaration = declarationStack.pop(); + let moduleName = (moduleDeclaration as ModuleDeclaration).name.text; + imports[moduleName] = imports[moduleName] || []; + if (!contains(imports[moduleName], declaration)) { + imports[moduleName].push(declaration); + } + } } - }); - } + // Otherwise we can elide it, as its from the stdlib or a triple-slash reference + return; + } + if (!(d.id in dependentDeclarations || d.id in declarations) && isModuleLevelDeclaration(d)) { + // Don't need to collect declarations which are not module-level + dependentDeclarations[d.id] = d; + } + let outtermostDeclaration = declarationStack.pop(); + if (outtermostDeclaration && outtermostDeclaration !== d && + outtermostDeclaration.kind !== SyntaxKind.ModuleDeclaration && + isModuleLevelDeclaration(outtermostDeclaration) && + (!(outtermostDeclaration.id in dependentDeclarations || outtermostDeclaration.id in declarations))) { + dependentDeclarations[outtermostDeclaration.id] = outtermostDeclaration; + walker.visitTypeFromSymbol(outtermostDeclaration.symbol) + } + }); } return true; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f768432d06a47..ddf10e4d09e87 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1440,7 +1440,7 @@ namespace ts { getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): ObjectType[]; getReturnTypeOfSignature(signature: Signature): Type; - getTypeWalker(accept?: (type: Type) => boolean): TypeWalker; + getSymbolWalker(accept?: (type: Symbol) => boolean): SymbolWalker; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -1616,13 +1616,13 @@ namespace ts { getExportsOfModule(symbol: Symbol): Symbol[]; getDefiningTypeOfSymbol(symbol: Symbol): Type; resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; - getTypeWalker(accept?: (type: Type) => boolean): TypeWalker; + getSymbolWalker(accept?: (type: Symbol) => boolean): SymbolWalker; } - export interface TypeWalker { + export interface SymbolWalker { visitType(type: Type): void; visitTypeFromSymbol(symbol: Symbol): void; - reset(accept?: (type: Type) => boolean): void; + reset(accept?: (type: Symbol) => boolean): void; } export const enum SymbolFlags { From 439bb9ebf6b84197b8b280aa49a943175436b941 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 22 Oct 2015 18:41:25 -0700 Subject: [PATCH 48/52] Accept new baseline --- tests/baselines/reference/optimizationEntrypoint9.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/optimizationEntrypoint9.js b/tests/baselines/reference/optimizationEntrypoint9.js index f443b176899ea..ce98c4e9d031b 100644 --- a/tests/baselines/reference/optimizationEntrypoint9.js +++ b/tests/baselines/reference/optimizationEntrypoint9.js @@ -103,6 +103,7 @@ export declare class B extends A { declare class A { member: typeof GlobalFoo; } +declare var GlobalFoo: Foo; declare class Foo { member: Bar; } @@ -115,8 +116,7 @@ export { //// [DtsFileErrors] -all.d.ts(3,20): error TS2304: Cannot find name 'GlobalFoo'. -all.d.ts(8,32): error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. +all.d.ts(9,32): error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. tests/cases/compiler/ref/a.d.ts(3,20): error TS2304: Cannot find name 'GlobalFoo'. tests/cases/compiler/ref/a.d.ts(3,20): error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. @@ -131,13 +131,12 @@ tests/cases/compiler/ref/a.d.ts(3,20): error TS4031: Public property 'member' of !!! error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. } -==== all.d.ts (2 errors) ==== +==== all.d.ts (1 errors) ==== /// declare class A { member: typeof GlobalFoo; - ~~~~~~~~~ -!!! error TS2304: Cannot find name 'GlobalFoo'. } + declare var GlobalFoo: Foo; declare class Foo { member: Bar; } From 608955a11d45595cd0ac9d6decbb7563c7b13954 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2015 15:45:00 -0700 Subject: [PATCH 49/52] comma --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 88c07e11333a4..d494be47e1570 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15078,7 +15078,7 @@ namespace ts { } }, resolveEntityName, - getSymbolWalker + getSymbolWalker, isArgumentsLocalBinding, getSymbolAtLocation, }; From dbb913e6c33c12d2842cd0a27c0b02ee31c74103 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2015 16:00:40 -0700 Subject: [PATCH 50/52] semicolong --- src/compiler/declarationEmitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 218fa3b8266b5..561502d22b9c9 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -546,7 +546,7 @@ namespace ts { isModuleLevelDeclaration(outtermostDeclaration) && (!(outtermostDeclaration.id in dependentDeclarations || outtermostDeclaration.id in declarations))) { dependentDeclarations[outtermostDeclaration.id] = outtermostDeclaration; - walker.visitTypeFromSymbol(outtermostDeclaration.symbol) + walker.visitTypeFromSymbol(outtermostDeclaration.symbol); } }); } From f354b9143d8ba18c84784d113461d935de4c835e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 2 Nov 2015 17:21:38 -0800 Subject: [PATCH 51/52] add back in methods --- src/compiler/checker.ts | 3 ++- src/compiler/types.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 93ce69fe3832c..df3a91da161e8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15073,7 +15073,8 @@ namespace ts { resolveEntityName, getSymbolWalker, isArgumentsLocalBinding, - getExternalModuleFileFromDeclaration + getExternalModuleFileFromDeclaration, + getSymbolAtLocation, }; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 542f8908d9836..43ddad0316741 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1628,6 +1628,7 @@ namespace ts { getDefiningTypeOfSymbol(symbol: Symbol): Type; resolveEntityName(entityName: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol; getSymbolWalker(accept?: (type: Symbol) => boolean): SymbolWalker; + getSymbolAtLocation(node: Node): Symbol; } export interface SymbolWalker { From f17efbd192be4cc27443ec4b8d3c102830b3215e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 3 Nov 2015 14:14:06 -0800 Subject: [PATCH 52/52] fix with changes since merge, accept new baselines --- src/compiler/declarationEmitter.ts | 121 +++++++------ .../reference/optimizationEntrypoint1.js | 168 ++---------------- .../reference/optimizationEntrypoint2.js | 53 ------ .../reference/optimizationEntrypoint3.js | 54 ------ .../reference/optimizationEntrypoint4.js | 48 ----- .../reference/optimizationEntrypoint5.js | 140 +-------------- .../reference/optimizationEntrypoint6.js | 76 -------- .../reference/optimizationEntrypoint7.js | 87 --------- .../reference/optimizationEntrypoint8.js | 28 --- .../reference/optimizationEntrypoint9.js | 64 +------ .../reference/thisTypeInClasses.symbols | 140 --------------- .../reference/thisTypeInClasses.types | 150 ---------------- 12 files changed, 90 insertions(+), 1039 deletions(-) delete mode 100644 tests/baselines/reference/thisTypeInClasses.symbols delete mode 100644 tests/baselines/reference/thisTypeInClasses.types diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 21b65410866de..2b34137e55814 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -190,35 +190,35 @@ namespace ts { } function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { - let undoActions: (() => void)[] = []; - let aliasEmits: (() => void)[] = []; - let symbolNameSet: Map = {}; - let imports: Map = {}; - let importEquals: Map = {}; - let exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); + const aliasEmits: (() => void)[] = []; + const symbolNameSet: Map = {}; + const imports: Map = {}; + const importEquals: Map = {}; + const exportedMembers = resolver.getExportsOfModule(entrypoint.symbol); // Handle an export=import as soon as possible - let maybeRedirectionType = exportedMembers.length && resolver.getDefiningTypeOfSymbol(exportedMembers[0]); + const maybeRedirectionType = exportedMembers.length && resolver.getDefiningTypeOfSymbol(exportedMembers[0]); if (maybeRedirectionType && maybeRedirectionType.symbol && exportedMembers[0].name === "export=" && maybeRedirectionType.symbol.valueDeclaration && maybeRedirectionType.symbol.valueDeclaration.kind === SyntaxKind.SourceFile) { return emitFlattenedTypeDefinitions(maybeRedirectionType.symbol.valueDeclaration as SourceFile); } - let createSymbolEntry = (name: string, id: number) => { + const createSymbolEntry = (name: string, id: number) => { symbolNameSet[name] = 1; symbolGeneratedNameMap[id] = name; }; - let generateName = (symbol: Symbol, name: string = symbol.name): string => { + const generateName = (symbol: Symbol, name: string = symbol.name): string => { + const id = getSymbolId(symbol); if (name in symbolNameSet) { let generatedName = `${name}_${symbolNameSet[name]}`; while (!!symbolNameSet[generatedName]) { generatedName = `${name}_${++symbolNameSet[name]}`; } symbolNameSet[name]++; - createSymbolEntry(generatedName, symbol.id); + createSymbolEntry(generatedName, id); return generatedName; } else { - createSymbolEntry(name, symbol.id); + createSymbolEntry(name, id); return name; } }; @@ -233,11 +233,11 @@ namespace ts { let writeExportAssignment = (tempname: string): void => undefined; let exportEquals: Type; - let moduleIdReverseLookup = buildModuleDtsReverseLookupTable(entrypoint); - let declarations = collectExportedDeclarations(exportedMembers); - let dependentDeclarations = collectDependentDeclarations(exportedMembers); + const moduleIdReverseLookup = buildModuleDtsReverseLookupTable(entrypoint); + const declarations = collectExportedDeclarations(exportedMembers); + const dependentDeclarations = collectDependentDeclarations(exportedMembers); - let alias = createDefaultExportAlias(); + const alias = createDefaultExportAlias(); forEachValue(dependentDeclarations, d => { generateName(d.symbol); }); @@ -247,12 +247,12 @@ namespace ts { writeLine(); increaseIndent(); forEach(imports[fileName], declaration => { - let symbol = declaration.symbol; + const symbol = declaration.symbol; if (!symbol) { return; } // Alias the import if need be - let name = generateName(symbol); + const name = generateName(symbol); write(symbol.name !== name ? `${symbol.name} as ${name},` : `${symbol.name},`); writeLine(); }); @@ -262,12 +262,13 @@ namespace ts { writeLine(); }); forEachKey(importEquals, fileName => { - let declarations = importEquals[fileName]; + const declarations = importEquals[fileName]; let name: string; forEach(declarations, declaration => { - let symbol = declaration.symbol; + const symbol = declaration.symbol; + const id = getSymbolId(symbol); if (name) { - createSymbolEntry(name, symbol.id); + createSymbolEntry(name, id); } else { name = generateName(symbol, makeIdentifierFromModuleName(fileName)); @@ -285,13 +286,13 @@ namespace ts { writeLine(); }); - let emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { - let realSourceFile = currentSourceFile; + const emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { + const realSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); if (d.kind === SyntaxKind.VariableDeclaration) { d = d.parent.parent as Declaration; } - let oldFlags = d.flags; + const oldFlags = d.flags; if (shouldExport) { d.flags |= NodeFlags.Export; } @@ -330,7 +331,6 @@ namespace ts { write("};"); writeLine(); } - forEach(undoActions, undo => undo()); // So we don't ruin the tree return; @@ -342,11 +342,10 @@ namespace ts { return; } // Skip relative paths and rooted paths (look at module identifiers only) - let filename = entrypoint.resolvedModules[name].resolvedFileName; - if (!name.match(/(\.|\/)/)) { - table[filename] = name; + const file = host.getSourceFile(entrypoint.resolvedModules[name].resolvedFileName); + if (!name.match(/^(\.|\/)/m)) { + table[file.fileName] = name; } - let file = host.getSourceFile(filename); if (!visited[file.fileName]) { buildModuleDtsReverseLookupTable(file, table, visited); } @@ -376,8 +375,9 @@ namespace ts { for (let exported of exportedMembers) { const type = resolver.getDefiningTypeOfSymbol(exported); for (let declaration of exported.declarations) { + const id = getNodeId(declaration); if (isModuleLevelDeclaration(declaration)) { // skips export specifiers - result[declaration.id] = declaration; + result[id] = declaration; } else { // inline the declaration referred to by an export specifier with the specified name @@ -398,8 +398,9 @@ namespace ts { const oldSourceFile = currentSourceFile; currentSourceFile = getSourceFileOfNode(d); const symbol = resolver.getDefiningTypeOfSymbol(d.symbol).symbol; - if (symbol && symbol.id in symbolGeneratedNameMap) { - write(symbolGeneratedNameMap[symbol.id]); + const symbolid = symbol && getSymbolId(symbol); + if (symbol && symbolid in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbolid]); } else { Debug.fail("Encountered export alias of untraversed type when flattening."); @@ -449,14 +450,16 @@ namespace ts { else if (exported.name === "default") { // delay making the alias until after all exported names are collected createDefaultExportAlias = ((exported: Symbol, type: Type) => () => { + const exportedId = getSymbolId(exported); let name = "default_1"; while (!!symbolNameSet[name]) { name += "_1"; } - createSymbolEntry(name, exported.id); - let symbol = type.symbol; + createSymbolEntry(name, exportedId); + const symbol = type.symbol; if (symbol) { - createSymbolEntry(name, symbol.id); + const symbolId = getSymbolId(symbol); + createSymbolEntry(name, symbolId); } return name; })(exported, type); @@ -471,10 +474,12 @@ namespace ts { } if (type.symbol) { - let symbol = type.symbol; - createSymbolEntry(symbol.name, symbol.id); + const symbol = type.symbol; + const id = getSymbolId(symbol); + createSymbolEntry(symbol.name, id); } - createSymbolEntry(exported.name, exported.id); + const exportedId = getSymbolId(exported); + createSymbolEntry(exported.name, exportedId); } return result; } @@ -493,17 +498,18 @@ namespace ts { else { // Add containing declarations if we've navigated to a nested type. forEach(symbol.declarations, d => { + const id = getNodeId(d); // Collect declarations - let sourceFile = getSourceFileOfNode(d); + const sourceFile = getSourceFileOfNode(d); // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) - let declarationStack = findDeclarationStack(d); + const declarationStack = findDeclarationStack(d); if (isDeclarationFile(sourceFile)) { // If the declaration is from an external module dts, we need to create an import for it if (isExternalModule(sourceFile)) { // First, try to reverse lookup a module identifier - let fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; + const fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; // Get the topmost declaration from that stack of nodes - let declaration = declarationStack.pop(); + const declaration = declarationStack.pop(); // Check for an export= if (sourceFile.symbol.exports["export="]) { importEquals[fileName] = importEquals[fileName] || []; @@ -522,11 +528,11 @@ namespace ts { } else { // Check if this type comes from an ambient external module declaration - let moduleDeclaration = declarationStack.pop(); + const moduleDeclaration = declarationStack.pop(); if (moduleDeclaration.kind === SyntaxKind.ModuleDeclaration) { // If so, add said ambient external module to the imports list, and the next declaration in the stack to the set of imports - let declaration = declarationStack.pop(); - let moduleName = (moduleDeclaration as ModuleDeclaration).name.text; + const declaration = declarationStack.pop(); + const moduleName = (moduleDeclaration as ModuleDeclaration).name.text; imports[moduleName] = imports[moduleName] || []; if (!contains(imports[moduleName], declaration)) { imports[moduleName].push(declaration); @@ -536,16 +542,17 @@ namespace ts { // Otherwise we can elide it, as its from the stdlib or a triple-slash reference return; } - if (!(d.id in dependentDeclarations || d.id in declarations) && isModuleLevelDeclaration(d)) { + if (!(id in dependentDeclarations || id in declarations) && isModuleLevelDeclaration(d)) { // Don't need to collect declarations which are not module-level - dependentDeclarations[d.id] = d; + dependentDeclarations[id] = d; } - let outtermostDeclaration = declarationStack.pop(); + const outtermostDeclaration = declarationStack.pop(); + const outterId = outtermostDeclaration && getNodeId(outtermostDeclaration); if (outtermostDeclaration && outtermostDeclaration !== d && outtermostDeclaration.kind !== SyntaxKind.ModuleDeclaration && isModuleLevelDeclaration(outtermostDeclaration) && - (!(outtermostDeclaration.id in dependentDeclarations || outtermostDeclaration.id in declarations))) { - dependentDeclarations[outtermostDeclaration.id] = outtermostDeclaration; + (!(outterId in dependentDeclarations || outterId in declarations))) { + dependentDeclarations[outterId] = outtermostDeclaration; walker.visitTypeFromSymbol(outtermostDeclaration.symbol); } }); @@ -555,7 +562,7 @@ namespace ts { function findDeclarationStack(d: Declaration): Declaration[] { let outermostNode: Node = d; - let visited: Node[] = [d]; + const visited: Node[] = [d]; // Find all the nodes between this declaration and the top of the file // In most cases, this will _never_ even execute a single iteration as the declaration we have is likely already top-level while (outermostNode.parent && outermostNode.parent.kind !== SyntaxKind.SourceFile) { @@ -768,9 +775,10 @@ namespace ts { } function writeEntityNameIfRenamed(entityName: EntityName | Expression): boolean { - let symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value); - if (symbol && symbol.id in symbolGeneratedNameMap) { - write(symbolGeneratedNameMap[symbol.id]); + const symbol = resolver.resolveEntityName(entityName, SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value); + const id = symbol && getSymbolId(symbol); + if (symbol && id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[id]); return true; } return false; @@ -2051,9 +2059,10 @@ namespace ts { if (!node) { return; } - let symbol = resolver.getSymbolAtLocation(node); - if (symbol && symbol.id in symbolGeneratedNameMap) { - write(symbolGeneratedNameMap[symbol.id]); + const symbol = resolver.getSymbolAtLocation(node); + const id = symbol && getSymbolId(symbol); + if (symbol && id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[id]); } else { writeTextOfNode(currentSourceFile, node); diff --git a/tests/baselines/reference/optimizationEntrypoint1.js b/tests/baselines/reference/optimizationEntrypoint1.js index b43cf593948ac..3a16b827e0ccd 100644 --- a/tests/baselines/reference/optimizationEntrypoint1.js +++ b/tests/baselines/reference/optimizationEntrypoint1.js @@ -53,60 +53,6 @@ export interface Inner { item: number; } -//// [c.js] -define(["require", "exports"], function (require, exports) { - var Main = (function () { - function Main() { - } - return Main; - })(); - exports.__esModule = true; - exports["default"] = Main; -}); -//// [b.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./c"], function (require, exports, c_1) { - var Main = (function (_super) { - __extends(Main, _super); - function Main() { - _super.apply(this, arguments); - } - return Main; - })(c_1["default"]); - exports.__esModule = true; - exports["default"] = Main; -}); -//// [a.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./b"], function (require, exports, b_1) { - var Main = (function (_super) { - __extends(Main, _super); - function Main() { - _super.apply(this, arguments); - } - return Main; - })(b_1["default"]); - exports.__esModule = true; - exports["default"] = Main; -}); -//// [index.js] -define(["require", "exports", "./a", "./b", "./c", "./a"], function (require, exports, a_1, b_1, c_1, a_2) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(a_1); - exports.BBaseMain = b_1.default; - exports.CBaseMain = c_1.default; - exports.default = a_2.default; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -155,62 +101,20 @@ define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compile }); -//// [c.d.ts] -export default class Main { - member1: string; -} -export interface Inner { - item: number; -} -//// [b.d.ts] -import { default as BaseMain, Inner as Innermost } from "./c"; -export default class Main extends BaseMain { - member2: Innermost; - details: Detail; -} -export interface Inner { - item2: number; -} -export interface Detail { - id: string; -} -//// [a.d.ts] -import { default as BaseMain, Inner as Middle } from "./b"; -export default class Main extends BaseMain { - memberc: Middle; -} -export interface Inner { - item3: number; -} -//// [index.d.ts] -export * from "./a"; -export { Detail, Detail as DetailMock, Detail as DetailReal } from "./b"; -export interface Inner { - item4: number; -} -export interface default_1 { - number: number; -} -export { default as BBaseMain, Inner as Middle } from "./b"; -export { default as CBaseMain, Inner as Innermost } from "./c"; -export { default } from "./a"; //// [bundled.d.ts] declare class default_2 { member1: string; } -interface Inner_1 { - item: number; -} declare class default_3 extends default_2 { member2: Inner_1; details: Detail; } +interface Inner_1 { + item: number; +} interface Inner_2 { item2: number; } -export interface Detail { - id: string; -} export declare class default_1_1 extends default_3 { memberc: Inner_2; } @@ -220,6 +124,9 @@ export interface Inner { export interface default_1 { number: number; } +export interface Detail { + id: string; +} export default default_1_1; export { Detail as DetailMock, @@ -234,62 +141,16 @@ export { //// [DtsFileErrors] -bundled.d.ts(7,33): error TS4020: Extends clause of exported class 'default_3' has or is using private name 'default_2'. -bundled.d.ts(8,14): error TS4031: Public property 'member2' of exported class has or is using private name 'Inner_1'. -bundled.d.ts(17,42): error TS4020: Extends clause of exported class 'default_1_1' has or is using private name 'default_3'. -bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. +bundled.d.ts(4,33): error TS4020: Extends clause of exported class 'default_3' has or is using private name 'default_2'. +bundled.d.ts(5,14): error TS4031: Public property 'member2' of exported class has or is using private name 'Inner_1'. +bundled.d.ts(14,42): error TS4020: Extends clause of exported class 'default_1_1' has or is using private name 'default_3'. +bundled.d.ts(15,14): error TS4031: Public property 'memberc' of exported class has or is using private name 'Inner_2'. -==== tests/cases/compiler/index.d.ts (0 errors) ==== - export * from "./a"; - export { Detail, Detail as DetailMock, Detail as DetailReal } from "./b"; - export interface Inner { - item4: number; - } - export interface default_1 { - number: number; - } - export { default as BBaseMain, Inner as Middle } from "./b"; - export { default as CBaseMain, Inner as Innermost } from "./c"; - export { default } from "./a"; - -==== tests/cases/compiler/a.d.ts (0 errors) ==== - import { default as BaseMain, Inner as Middle } from "./b"; - export default class Main extends BaseMain { - memberc: Middle; - } - export interface Inner { - item3: number; - } - -==== tests/cases/compiler/b.d.ts (0 errors) ==== - import { default as BaseMain, Inner as Innermost } from "./c"; - export default class Main extends BaseMain { - member2: Innermost; - details: Detail; - } - export interface Inner { - item2: number; - } - export interface Detail { - id: string; - } - -==== tests/cases/compiler/c.d.ts (0 errors) ==== - export default class Main { - member1: string; - } - export interface Inner { - item: number; - } - ==== bundled.d.ts (4 errors) ==== declare class default_2 { member1: string; } - interface Inner_1 { - item: number; - } declare class default_3 extends default_2 { ~~~~~~~~~ !!! error TS4020: Extends clause of exported class 'default_3' has or is using private name 'default_2'. @@ -298,12 +159,12 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h !!! error TS4031: Public property 'member2' of exported class has or is using private name 'Inner_1'. details: Detail; } + interface Inner_1 { + item: number; + } interface Inner_2 { item2: number; } - export interface Detail { - id: string; - } export declare class default_1_1 extends default_3 { ~~~~~~~~~ !!! error TS4020: Extends clause of exported class 'default_1_1' has or is using private name 'default_3'. @@ -317,6 +178,9 @@ bundled.d.ts(18,14): error TS4031: Public property 'memberc' of exported class h export interface default_1 { number: number; } + export interface Detail { + id: string; + } export default default_1_1; export { Detail as DetailMock, diff --git a/tests/baselines/reference/optimizationEntrypoint2.js b/tests/baselines/reference/optimizationEntrypoint2.js index bf34995dea2b4..8de31ba567f79 100644 --- a/tests/baselines/reference/optimizationEntrypoint2.js +++ b/tests/baselines/reference/optimizationEntrypoint2.js @@ -21,46 +21,6 @@ export class Bar extends Foo> { primary: Foo; } -//// [bar.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./foo"], function (require, exports, foo_1) { - var Bar = (function (_super) { - __extends(Bar, _super); - function Bar() { - _super.apply(this, arguments); - } - return Bar; - })(foo_1.Foo); - exports.Bar = Bar; -}); -//// [foo.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./bar"], function (require, exports, bar_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(bar_1); - var Foo = (function (_super) { - __extends(Foo, _super); - function Foo() { - _super.apply(this, arguments); - } - return Foo; - })(Array); - exports.Foo = Foo; -}); -//// [index.js] -define(["require", "exports", "./foo"], function (require, exports, t) { - return t; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -96,19 +56,6 @@ define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compile }); -//// [bar.d.ts] -import { Foo } from "./foo"; -export declare class Bar extends Foo> { - primary: Foo; -} -//// [foo.d.ts] -export * from "./bar"; -export declare class Foo extends Array { - self: this; -} -//// [index.d.ts] -import * as t from "./foo"; -export = t; //// [bundled.d.ts] export declare class Bar extends Foo> { primary: Foo; diff --git a/tests/baselines/reference/optimizationEntrypoint3.js b/tests/baselines/reference/optimizationEntrypoint3.js index 613f88bcb5b8a..e3f0ea366fe20 100644 --- a/tests/baselines/reference/optimizationEntrypoint3.js +++ b/tests/baselines/reference/optimizationEntrypoint3.js @@ -17,38 +17,6 @@ export class Foo extends Array { } -//// [foo.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports"], function (require, exports) { - var Foo = (function (_super) { - __extends(Foo, _super); - function Foo() { - _super.apply(this, arguments); - } - return Foo; - })(Array); - exports.Foo = Foo; -}); -//// [index.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./foo"], function (require, exports, foo_1) { - var Bar = (function (_super) { - __extends(Bar, _super); - function Bar() { - _super.apply(this, arguments); - } - return Bar; - })(foo_1.Foo); - return Bar; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -77,16 +45,6 @@ define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compile }); -//// [foo.d.ts] -export declare class Foo extends Array { - self: this; -} -//// [index.d.ts] -import { Foo } from "./foo"; -declare class Bar extends Foo> { - primary: Foo; -} -export = Bar; //// [bundled.d.ts] declare class Foo extends Array { self: this; @@ -105,18 +63,6 @@ bundled.d.ts(4,31): error TS4020: Extends clause of exported class 'Bar' has or bundled.d.ts(5,14): error TS4031: Public property 'primary' of exported class has or is using private name 'Foo'. -==== tests/cases/compiler/index.d.ts (0 errors) ==== - import { Foo } from "./foo"; - declare class Bar extends Foo> { - primary: Foo; - } - export = Bar; - -==== tests/cases/compiler/foo.d.ts (0 errors) ==== - export declare class Foo extends Array { - self: this; - } - ==== bundled.d.ts (3 errors) ==== declare class Foo extends Array { self: this; diff --git a/tests/baselines/reference/optimizationEntrypoint4.js b/tests/baselines/reference/optimizationEntrypoint4.js index 624225108c392..a54ee5b0c40b3 100644 --- a/tests/baselines/reference/optimizationEntrypoint4.js +++ b/tests/baselines/reference/optimizationEntrypoint4.js @@ -18,24 +18,6 @@ namespace Foo {} export = Foo; -//// [foo.js] -define(["require", "exports"], function (require, exports) { - var Foo = (function () { - function Foo() { - } - return Foo; - })(); - return Foo; -}); -//// [index.js] -define(["require", "exports"], function (require, exports) { - var Bar = (function () { - function Bar() { - } - return Bar; - })(); - exports.Bar = Bar; -}); //// [bundled.js] define("tests/cases/compiler/foo", ["require", "exports"], function (require, exports) { var Foo = (function () { @@ -55,20 +37,6 @@ define("tests/cases/compiler/index", ["require", "exports"], function (require, }); -//// [foo.d.ts] -declare class Foo { - static field: { - name: string; - }; -} -declare namespace Foo { -} -export = Foo; -//// [index.d.ts] -import Foo = require("./foo"); -export declare class Bar { - field2: typeof Foo.field; -} //// [bundled.d.ts] declare class Foo_1 { static field: { @@ -90,22 +58,6 @@ export { bundled.d.ts(9,20): error TS4031: Public property 'field2' of exported class has or is using private name 'Foo_1'. -==== tests/cases/compiler/index.d.ts (0 errors) ==== - import Foo = require("./foo"); - export declare class Bar { - field2: typeof Foo.field; - } - -==== tests/cases/compiler/foo.d.ts (0 errors) ==== - declare class Foo { - static field: { - name: string; - }; - } - declare namespace Foo { - } - export = Foo; - ==== bundled.d.ts (1 errors) ==== declare class Foo_1 { static field: { diff --git a/tests/baselines/reference/optimizationEntrypoint5.js b/tests/baselines/reference/optimizationEntrypoint5.js index 32240f31c3f04..1e493a213bb98 100644 --- a/tests/baselines/reference/optimizationEntrypoint5.js +++ b/tests/baselines/reference/optimizationEntrypoint5.js @@ -38,94 +38,6 @@ export class J {} export type AnyJ = J; -//// [foo.js] -define(["require", "exports"], function (require, exports) { - var A = (function () { - function A() { - } - return A; - })(); - exports.A = A; - var B = (function () { - function B() { - } - return B; - })(); - exports.B = B; - var C = (function () { - function C() { - } - return C; - })(); - exports.C = C; - var D = (function () { - function D() { - } - return D; - })(); - exports.D = D; - var E = (function () { - function E() { - } - return E; - })(); - exports.E = E; - var F = (function () { - function F() { - } - return F; - })(); - exports.F = F; - var E2 = (function () { - function E2() { - } - return E2; - })(); - exports.E2 = E2; - var F2 = (function () { - function F2() { - } - return F2; - })(); - exports.F2 = F2; - var G = (function () { - function G() { - } - return G; - })(); - exports.G = G; - var H = (function () { - function H() { - } - return H; - })(); - exports.H = H; - var I = (function () { - function I() { - } - return I; - })(); - exports.I = I; - var J = (function () { - function J() { - } - return J; - })(); - exports.J = J; -}); -//// [index.js] -define(["require", "exports", "./foo"], function (require, exports, foo_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(foo_1); - var Main = (function () { - function Main() { - } - return Main; - })(); - exports.Main = Main; -}); //// [bundled.js] define("tests/cases/compiler/foo", ["require", "exports"], function (require, exports) { var A = (function () { @@ -215,52 +127,6 @@ define("tests/cases/compiler/index", ["require", "exports", "tests/cases/compile }); -//// [foo.d.ts] -export declare class A { -} -export declare class B { -} -export declare class C { -} -export declare class D { -} -export declare class E { -} -export declare class F { -} -export declare class E2 { -} -export declare class F2 { -} -export declare class G { -} -export declare type GAlias = G | A; -export declare class H { -} -export declare class I { -} -export declare type IAlias = I; -export declare class J { -} -export declare type AnyJ = J; -//// [index.d.ts] -import * as foo from "./foo"; -export * from "./foo"; -export declare class Main { - a: foo.A; - b: [foo.B]; - c: (foo.C); - d: foo.D[]; - e: foo.E | foo.E2; - f: foo.F & foo.F2; - g: foo.GAlias; - h: { - item: foo.H; - }; - i: foo.IAlias; - j: foo.J; - jj: foo.AnyJ; -} //// [bundled.d.ts] export declare class A { } @@ -286,9 +152,6 @@ export declare class I { } export declare class J { } -export declare type GAlias = G | A; -export declare type IAlias = I; -export declare type AnyJ = J; export declare class Main { a: A; b: [B]; @@ -304,3 +167,6 @@ export declare class Main { j: J; jj: AnyJ; } +export declare type GAlias = G | A; +export declare type IAlias = I; +export declare type AnyJ = J; diff --git a/tests/baselines/reference/optimizationEntrypoint6.js b/tests/baselines/reference/optimizationEntrypoint6.js index 0a0b4f7bf68d3..73fb65929aa13 100644 --- a/tests/baselines/reference/optimizationEntrypoint6.js +++ b/tests/baselines/reference/optimizationEntrypoint6.js @@ -33,63 +33,6 @@ import {Dependency} from "bar"; export class BarDependency extends Dependency {} -//// [foodep.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "foo"], function (require, exports, foo_1) { - var FooDependency = (function (_super) { - __extends(FooDependency, _super); - function FooDependency() { - _super.apply(this, arguments); - } - return FooDependency; - })(foo_1.Dependency); - exports.FooDependency = FooDependency; -}); -//// [bardep.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "bar"], function (require, exports, bar_1) { - var BarDependency = (function (_super) { - __extends(BarDependency, _super); - function BarDependency() { - _super.apply(this, arguments); - } - return BarDependency; - })(bar_1.Dependency); - exports.BarDependency = BarDependency; -}); -//// [index.js] -define(["require", "exports", "./foodep", "./bardep"], function (require, exports, foodep_1, bardep_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(foodep_1); - __export(bardep_1); -}); -//// [main.js] -define(["require", "exports", "./interop/index"], function (require, exports, index_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - /// - /// - __export(index_1); - exports.__esModule = true; - exports["default"] = 2 + 2; - var Baz = (function () { - function Baz() { - } - return Baz; - })(); - exports.Baz = Baz; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -141,25 +84,6 @@ define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler }); -//// [foodep.d.ts] -import { Dependency } from "foo"; -export declare class FooDependency extends Dependency { -} -//// [bardep.d.ts] -import { Dependency } from "bar"; -export declare class BarDependency extends Dependency { -} -//// [index.d.ts] -export * from "./foodep"; -export * from "./bardep"; -//// [main.d.ts] -/// -/// -export * from "./interop/index"; -declare var _default: number; -export default _default; -export declare class Baz { -} //// [bundled.d.ts] /// /// diff --git a/tests/baselines/reference/optimizationEntrypoint7.js b/tests/baselines/reference/optimizationEntrypoint7.js index 55ef3b96abc57..536e51b9071ca 100644 --- a/tests/baselines/reference/optimizationEntrypoint7.js +++ b/tests/baselines/reference/optimizationEntrypoint7.js @@ -26,59 +26,6 @@ import {Dependency} from "bar"; export class BarDependency extends Dependency {} -//// [foodep.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "foo"], function (require, exports, foo_1) { - var FooDependency = (function (_super) { - __extends(FooDependency, _super); - function FooDependency() { - _super.apply(this, arguments); - } - return FooDependency; - })(foo_1.Dependency); - exports.FooDependency = FooDependency; -}); -//// [bardep.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "bar"], function (require, exports, bar_1) { - var BarDependency = (function (_super) { - __extends(BarDependency, _super); - function BarDependency() { - _super.apply(this, arguments); - } - return BarDependency; - })(bar_1.Dependency); - exports.BarDependency = BarDependency; -}); -//// [index.js] -define(["require", "exports", "./foodep", "./bardep"], function (require, exports, foodep_1, bardep_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(foodep_1); - __export(bardep_1); -}); -//// [main.js] -define(["require", "exports", "./interop"], function (require, exports, interop_1) { - function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - } - __export(interop_1); - var Baz = (function () { - function Baz() { - } - return Baz; - })(); - exports.Baz = Baz; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -142,21 +89,6 @@ define("tests/cases/compiler/main", ["require", "exports", "tests/cases/compiler }); -//// [foodep.d.ts] -import { Dependency } from "foo"; -export declare class FooDependency extends Dependency { -} -//// [bardep.d.ts] -import { Dependency } from "bar"; -export declare class BarDependency extends Dependency { -} -//// [index.d.ts] -export * from "./foodep"; -export * from "./bardep"; -//// [main.d.ts] -export * from "./interop"; -export declare class Baz { -} //// [bundled.d.ts] import { Dependency, @@ -186,25 +118,6 @@ bundled.d.ts(6,8): error TS2307: Cannot find module 'bar'. ==== tests/cases/compiler/node_modules/bar/index.d.ts (0 errors) ==== export class Dependency {} -==== tests/cases/compiler/main.d.ts (0 errors) ==== - export * from "./interop"; - export declare class Baz { - } - -==== tests/cases/compiler/interop/index.d.ts (0 errors) ==== - export * from "./foodep"; - export * from "./bardep"; - -==== tests/cases/compiler/interop/foodep.d.ts (0 errors) ==== - import { Dependency } from "foo"; - export declare class FooDependency extends Dependency { - } - -==== tests/cases/compiler/interop/bardep.d.ts (0 errors) ==== - import { Dependency } from "bar"; - export declare class BarDependency extends Dependency { - } - ==== bundled.d.ts (2 errors) ==== import { Dependency, diff --git a/tests/baselines/reference/optimizationEntrypoint8.js b/tests/baselines/reference/optimizationEntrypoint8.js index dc5e0195b79e6..eccedcfabbe00 100644 --- a/tests/baselines/reference/optimizationEntrypoint8.js +++ b/tests/baselines/reference/optimizationEntrypoint8.js @@ -19,23 +19,6 @@ export class Baz extends Foo implements Foo.Bar { -//// [main.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "foo"], function (require, exports, Foo) { - var Baz = (function (_super) { - __extends(Baz, _super); - function Baz() { - _super.apply(this, arguments); - this.member = 42; - } - return Baz; - })(Foo); - exports.Baz = Baz; -}); //// [bundled.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -58,11 +41,6 @@ define("tests/cases/compiler/main", ["require", "exports", "foo"], function (req }); -//// [main.d.ts] -import * as Foo from "foo"; -export declare class Baz extends Foo implements Foo.Bar { - member: number; -} //// [bundled.d.ts] import * as foo from "foo"; export declare class Baz extends foo implements foo.Bar { @@ -87,12 +65,6 @@ bundled.d.ts(1,22): error TS2307: Cannot find module 'foo'. export = Foo; -==== tests/cases/compiler/main.d.ts (0 errors) ==== - import * as Foo from "foo"; - export declare class Baz extends Foo implements Foo.Bar { - member: number; - } - ==== bundled.d.ts (1 errors) ==== import * as foo from "foo"; ~~~~~ diff --git a/tests/baselines/reference/optimizationEntrypoint9.js b/tests/baselines/reference/optimizationEntrypoint9.js index ce98c4e9d031b..550eae31b3d58 100644 --- a/tests/baselines/reference/optimizationEntrypoint9.js +++ b/tests/baselines/reference/optimizationEntrypoint9.js @@ -30,32 +30,6 @@ import {A} from "./ref/a"; export class B extends A { } -//// [a.js] -define(["require", "exports"], function (require, exports) { - /// - var A = (function () { - function A() { - } - return A; - })(); - exports.A = A; -}); -//// [b.js] -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -define(["require", "exports", "./ref/a"], function (require, exports, a_1) { - var B = (function (_super) { - __extends(B, _super); - function B() { - _super.apply(this, arguments); - } - return B; - })(a_1.A); - exports.B = B; -}); //// [all.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; @@ -89,24 +63,15 @@ define("tests/cases/compiler/b", ["require", "exports", "tests/cases/compiler/re }); -//// [a.d.ts] -/// -export declare class A { - member: typeof GlobalFoo; -} -//// [b.d.ts] -import { A } from "./ref/a"; -export declare class B extends A { -} //// [all.d.ts] /// +declare class Foo { + member: Bar; +} declare class A { member: typeof GlobalFoo; } declare var GlobalFoo: Foo; -declare class Foo { - member: Bar; -} export declare class B extends A { } export { @@ -117,29 +82,17 @@ export { all.d.ts(9,32): error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. -tests/cases/compiler/ref/a.d.ts(3,20): error TS2304: Cannot find name 'GlobalFoo'. -tests/cases/compiler/ref/a.d.ts(3,20): error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. -==== tests/cases/compiler/ref/a.d.ts (2 errors) ==== - /// - export declare class A { - member: typeof GlobalFoo; - ~~~~~~~~~ -!!! error TS2304: Cannot find name 'GlobalFoo'. - ~~~~~~~~~ -!!! error TS4031: Public property 'member' of exported class has or is using private name 'GlobalFoo'. - } - ==== all.d.ts (1 errors) ==== /// + declare class Foo { + member: Bar; + } declare class A { member: typeof GlobalFoo; } declare var GlobalFoo: Foo; - declare class Foo { - member: Bar; - } export declare class B extends A { ~ !!! error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. @@ -157,9 +110,4 @@ tests/cases/compiler/ref/a.d.ts(3,20): error TS4031: Public property 'member' of declare class Baz { member: number; } - -==== tests/cases/compiler/b.d.ts (0 errors) ==== - import { A } from "./ref/a"; - export declare class B extends A { - } \ No newline at end of file diff --git a/tests/baselines/reference/thisTypeInClasses.symbols b/tests/baselines/reference/thisTypeInClasses.symbols deleted file mode 100644 index 04ed47b09ffe5..0000000000000 --- a/tests/baselines/reference/thisTypeInClasses.symbols +++ /dev/null @@ -1,140 +0,0 @@ -=== tests/cases/conformance/types/thisType/thisTypeInClasses.ts === -class C1 { ->C1 : Symbol(C1, Decl(thisTypeInClasses.ts, 0, 0)) - - x: this; ->x : Symbol(x, Decl(thisTypeInClasses.ts, 0, 10)) - - f(x: this): this { return undefined; } ->f : Symbol(f, Decl(thisTypeInClasses.ts, 1, 12)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 2, 6)) ->undefined : Symbol(undefined) - - constructor(x: this) { } ->x : Symbol(x, Decl(thisTypeInClasses.ts, 3, 16)) -} - -class C2 { ->C2 : Symbol(C2, Decl(thisTypeInClasses.ts, 4, 1)) - - [x: string]: this; ->x : Symbol(x, Decl(thisTypeInClasses.ts, 7, 5)) -} - -interface Foo { ->Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1)) ->T : Symbol(T, Decl(thisTypeInClasses.ts, 10, 14)) - - x: T; ->x : Symbol(x, Decl(thisTypeInClasses.ts, 10, 18)) ->T : Symbol(T, Decl(thisTypeInClasses.ts, 10, 14)) - - y: this; ->y : Symbol(y, Decl(thisTypeInClasses.ts, 11, 9)) -} - -class C3 { ->C3 : Symbol(C3, Decl(thisTypeInClasses.ts, 13, 1)) - - a: this[]; ->a : Symbol(a, Decl(thisTypeInClasses.ts, 15, 10)) - - b: [this, this]; ->b : Symbol(b, Decl(thisTypeInClasses.ts, 16, 14)) - - c: this | Date; ->c : Symbol(c, Decl(thisTypeInClasses.ts, 17, 20)) ->Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - - d: this & Date; ->d : Symbol(d, Decl(thisTypeInClasses.ts, 18, 19)) ->Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - - e: (((this))); ->e : Symbol(e, Decl(thisTypeInClasses.ts, 19, 19)) - - f: (x: this) => this; ->f : Symbol(f, Decl(thisTypeInClasses.ts, 20, 18)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 21, 8)) - - g: new (x: this) => this; ->g : Symbol(g, Decl(thisTypeInClasses.ts, 21, 25)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 22, 12)) - - h: Foo; ->h : Symbol(h, Decl(thisTypeInClasses.ts, 22, 29)) ->Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1)) - - i: Foo this)>; ->i : Symbol(i, Decl(thisTypeInClasses.ts, 23, 17)) ->Foo : Symbol(Foo, Decl(thisTypeInClasses.ts, 8, 1)) - - j: (x: any) => x is this; ->j : Symbol(j, Decl(thisTypeInClasses.ts, 24, 32)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 25, 8)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 25, 8)) -} - -declare class C4 { ->C4 : Symbol(C4, Decl(thisTypeInClasses.ts, 26, 1)) - - x: this; ->x : Symbol(x, Decl(thisTypeInClasses.ts, 28, 18)) - - f(x: this): this; ->f : Symbol(f, Decl(thisTypeInClasses.ts, 29, 12)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 30, 6)) -} - -class C5 { ->C5 : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - - foo() { ->foo : Symbol(foo, Decl(thisTypeInClasses.ts, 33, 10)) - - let f1 = (x: this): this => this; ->f1 : Symbol(f1, Decl(thisTypeInClasses.ts, 35, 11)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 35, 18)) ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - - let f2 = (x: this) => this; ->f2 : Symbol(f2, Decl(thisTypeInClasses.ts, 36, 11)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 36, 18)) ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - - let f3 = (x: this) => (y: this) => this; ->f3 : Symbol(f3, Decl(thisTypeInClasses.ts, 37, 11)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 37, 18)) ->y : Symbol(y, Decl(thisTypeInClasses.ts, 37, 31)) ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - - let f4 = (x: this) => { ->f4 : Symbol(f4, Decl(thisTypeInClasses.ts, 38, 11)) ->x : Symbol(x, Decl(thisTypeInClasses.ts, 38, 18)) - - let g = (y: this) => { ->g : Symbol(g, Decl(thisTypeInClasses.ts, 39, 15)) ->y : Symbol(y, Decl(thisTypeInClasses.ts, 39, 21)) - - return () => this; ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - } - return g(this); ->g : Symbol(g, Decl(thisTypeInClasses.ts, 39, 15)) ->this : Symbol(C5, Decl(thisTypeInClasses.ts, 31, 1)) - } - } - bar() { ->bar : Symbol(bar, Decl(thisTypeInClasses.ts, 44, 5)) - - let x1 = undefined; ->x1 : Symbol(x1, Decl(thisTypeInClasses.ts, 46, 11)) ->undefined : Symbol(undefined) - - let x2 = undefined as this; ->x2 : Symbol(x2, Decl(thisTypeInClasses.ts, 47, 11)) ->undefined : Symbol(undefined) - } -} - diff --git a/tests/baselines/reference/thisTypeInClasses.types b/tests/baselines/reference/thisTypeInClasses.types deleted file mode 100644 index ddfdfb277a901..0000000000000 --- a/tests/baselines/reference/thisTypeInClasses.types +++ /dev/null @@ -1,150 +0,0 @@ -=== tests/cases/conformance/types/thisType/thisTypeInClasses.ts === -class C1 { ->C1 : C1 - - x: this; ->x : this - - f(x: this): this { return undefined; } ->f : (x: this) => this ->x : this ->undefined : undefined - - constructor(x: this) { } ->x : this -} - -class C2 { ->C2 : C2 - - [x: string]: this; ->x : string -} - -interface Foo { ->Foo : Foo ->T : T - - x: T; ->x : T ->T : T - - y: this; ->y : this -} - -class C3 { ->C3 : C3 - - a: this[]; ->a : this[] - - b: [this, this]; ->b : [this, this] - - c: this | Date; ->c : this | Date ->Date : Date - - d: this & Date; ->d : this & Date ->Date : Date - - e: (((this))); ->e : this - - f: (x: this) => this; ->f : (x: this) => this ->x : this - - g: new (x: this) => this; ->g : new (x: this) => this ->x : this - - h: Foo; ->h : Foo ->Foo : Foo - - i: Foo this)>; ->i : Foo this)> ->Foo : Foo - - j: (x: any) => x is this; ->j : (x: any) => x is this ->x : any ->x : any -} - -declare class C4 { ->C4 : C4 - - x: this; ->x : this - - f(x: this): this; ->f : (x: this) => this ->x : this -} - -class C5 { ->C5 : C5 - - foo() { ->foo : () => void - - let f1 = (x: this): this => this; ->f1 : (x: this) => this ->(x: this): this => this : (x: this) => this ->x : this ->this : this ->this : this - - let f2 = (x: this) => this; ->f2 : (x: this) => this ->(x: this) => this : (x: this) => this ->x : this ->this : this - - let f3 = (x: this) => (y: this) => this; ->f3 : (x: this) => (y: this) => this ->(x: this) => (y: this) => this : (x: this) => (y: this) => this ->x : this ->(y: this) => this : (y: this) => this ->y : this ->this : this - - let f4 = (x: this) => { ->f4 : (x: this) => () => this ->(x: this) => { let g = (y: this) => { return () => this; } return g(this); } : (x: this) => () => this ->x : this - - let g = (y: this) => { ->g : (y: this) => () => this ->(y: this) => { return () => this; } : (y: this) => () => this ->y : this - - return () => this; ->() => this : () => this ->this : this - } - return g(this); ->g(this) : () => this ->g : (y: this) => () => this ->this : this - } - } - bar() { ->bar : () => void - - let x1 = undefined; ->x1 : this ->undefined : this ->undefined : undefined - - let x2 = undefined as this; ->x2 : this ->undefined as this : this ->undefined : undefined - } -} -