diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8da1edaeed40..df3a91da161e8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -94,7 +94,8 @@ namespace ts { getJsxElementAttributesType, getJsxIntrinsicTagNames, - isOptionalParameter + isOptionalParameter, + getSymbolWalker }; let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); @@ -2052,6 +2053,164 @@ namespace ts { }); } + function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker { + let visited: Type[] = []; + let visitedSymbols: Symbol[] = []; + + return { + visitType, + visitTypeFromSymbol, + reset: (newCallback: (symbol: Symbol) => boolean = () => true) => { + accept = newCallback; + visited = []; + visitedSymbols = []; + } + }; + + function visitType(type: Type): void { + if (!type) { + return; + } + if (contains(visited, type)) { + return; + } + visited.push(type); + if (type.symbol) { + if (!accept(type.symbol)) { + return; + } + } + + // Visit the type's related types, if any + if (type.flags & TypeFlags.Reference) { + visitTypeReference(type as TypeReference); + } + if (type.flags & TypeFlags.TypeParameter) { + visitTypeParameter(type as TypeParameter); + } + if (type.flags & TypeFlags.Tuple) { + visitTupleType(type as TupleType); + } + if (type.flags & TypeFlags.UnionOrIntersection) { + visitUnionOrIntersectionType(type as UnionOrIntersectionType); + } + if (type.flags & (TypeFlags.Class | TypeFlags.Interface)) { + visitInterfaceType(type as InterfaceType); + } + if (type.flags & TypeFlags.Anonymous) { + visitObjectType(type as ObjectType); + } + } + + function visitTypeList(types: Type[]): void { + if (!types) { + return; + } + 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 { + if (signature.typePredicate) { + visitType(signature.typePredicate.type); + } + visitTypeList(signature.typeParameters); + + for (let parameter of signature.parameters){ + visitTypeFromSymbol(parameter); + } + visitType(getRestTypeOfSignature(signature)); + visitType(getReturnTypeOfSignature(signature)); + } + + function visitInterfaceType(interfaceT: InterfaceType): void { + visitObjectType(interfaceT); + if (interfaceT.typeParameters) { + visitTypeList(interfaceT.typeParameters); + } + visitTypeList(getBaseTypes(interfaceT)); + visitType(interfaceT.thisType); + } + + 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); + if (!accept(symbol)) { + return; + } + let t = getTypeOfSymbol(symbol); + visitType(t); // Should handle members on classes and such + 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); + } + } + } + } + function isDeclarationVisible(node: Declaration): boolean { function getContainingExternalModule(node: Node) { for (; node; node = node.parent) { @@ -14900,8 +15059,22 @@ namespace ts { getReferencedValueDeclaration, getTypeReferenceSerializationKind, isOptionalParameter, + getExportsOfModule: getExportsOfModuleAsArray, + getDefiningTypeOfSymbol: (symbol: Symbol) => { + let declaredType = getDeclaredTypeOfSymbol(symbol); + if (declaredType !== unknownType) { + return declaredType; + } + let valueType = getTypeOfSymbol(symbol); + if (valueType !== unknownType) { + return valueType; + } + }, + resolveEntityName, + getSymbolWalker, isArgumentsLocalBinding, - getExternalModuleFileFromDeclaration + getExternalModuleFileFromDeclaration, + getSymbolAtLocation, }; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f4de5c430acd9..44afaf5fa023c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -255,6 +255,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 + }, { name: "allowUnusedLabels", type: "boolean", diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 8ecf818a613a9..2b34137e55814 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[]; @@ -103,70 +104,475 @@ namespace ts { } } else { - // Emit references corresponding to this file - let emittedReferencedFiles: SourceFile[] = []; - let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; - forEach(host.getSourceFiles(), sourceFile => { - if (!isDeclarationFile(sourceFile)) { - // 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, emit that reference - if (referencedFile && (isDeclarationFile(referencedFile) && - !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted - - writeReferencePath(referencedFile); - emittedReferencedFiles.push(referencedFile); - } - }); - } + if (compilerOptions.optimizationEntrypoint) { + let path = compilerOptions.optimizationEntrypoint; + let entrypoint = host.getSourceFile(path); + if (!entrypoint) { + return {reportedDeclarationError: true, synchronousDeclarationOutput: "", referencePathsOutput: "", moduleElementDeclarationEmitInfo: []}; } + noDeclare = false; + let emittedReferencedFiles: SourceFile[] = []; + forEach(host.getSourceFiles(), sourceFile => { + if (!isDeclarationFile(sourceFile)) { + emitReferences(sourceFile, emittedReferencedFiles); + } + }); + emitFlattenedTypeDefinitions(entrypoint); + } + else { + // Emit references corresponding to this file + let emittedReferencedFiles: SourceFile[] = []; + let prevModuleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = []; + forEach(host.getSourceFiles(), sourceFile => { + if (!isDeclarationFile(sourceFile)) { + emitReferences(sourceFile, emittedReferencedFiles); + } + if (!isExternalModuleOrDeclarationFile(sourceFile)) { + noDeclare = false; + emitSourceFile(sourceFile); + } + else if (isExternalModule(sourceFile)) { + noDeclare = true; + write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`); + 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 { + reportedDeclarationError, + moduleElementDeclarationEmitInfo, + synchronousDeclarationOutput: writer.getText(), + referencePathsOutput, + }; - if (!isExternalModuleOrDeclarationFile(sourceFile)) { - noDeclare = false; - emitSourceFile(sourceFile); + 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 && (isDeclarationFile(referencedFile) && + !contains(emittedReferencedFiles, referencedFile))) { // If the file reference was not already emitted + + writeReferencePath(referencedFile); + emittedReferencedFiles.push(referencedFile); + } + }); + } + } + + function emitFlattenedTypeDefinitions(entrypoint: SourceFile): void { + 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 + 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); + } + + const createSymbolEntry = (name: string, id: number) => { + symbolNameSet[name] = 1; + symbolGeneratedNameMap[id] = name; + }; + 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, id); + return generatedName; } - else if (isExternalModule(sourceFile)) { - noDeclare = true; - write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`); + else { + createSymbolEntry(name, id); + return 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; + const moduleIdReverseLookup = buildModuleDtsReverseLookupTable(entrypoint); + const declarations = collectExportedDeclarations(exportedMembers); + const dependentDeclarations = collectDependentDeclarations(exportedMembers); + + const alias = createDefaultExportAlias(); + forEachValue(dependentDeclarations, d => { + generateName(d.symbol); + }); + + forEachKey(imports, fileName => { + write("import {"); + writeLine(); + increaseIndent(); + forEach(imports[fileName], declaration => { + const symbol = declaration.symbol; + if (!symbol) { + return; + } + // Alias the import if need be + const name = generateName(symbol); + write(symbol.name !== name ? `${symbol.name} as ${name},` : `${symbol.name},`); writeLine(); - increaseIndent(); - emitSourceFile(sourceFile); - decreaseIndent(); - write("}"); + }); + decreaseIndent(); + // Handle module identifiers + write(fileName.match(/^('|")/) ? `} from ${fileName}` : `} from "${fileName}";`); + writeLine(); + }); + forEachKey(importEquals, fileName => { + const declarations = importEquals[fileName]; + let name: string; + forEach(declarations, declaration => { + const symbol = declaration.symbol; + const id = getSymbolId(symbol); + if (name) { + createSymbolEntry(name, id); + } + else { + name = generateName(symbol, makeIdentifierFromModuleName(fileName)); + } + }); + 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(); + }); + + const emitModuleLevelDeclaration = (d: Declaration, shouldExport: boolean) => { + const realSourceFile = currentSourceFile; + currentSourceFile = getSourceFileOfNode(d); + if (d.kind === SyntaxKind.VariableDeclaration) { + d = d.parent.parent as Declaration; + } + const 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; + } + writeModuleElement(d); + d.flags = oldFlags; + currentSourceFile = realSourceFile; + }; + let privateDeclarations = 0; + forEachValue(dependentDeclarations, d => { + privateDeclarations++; + emitModuleLevelDeclaration(d, /*shouldExport*/false); + }); + if (!exportEquals) { + forEachValue(declarations, d => emitModuleLevelDeclaration(d, /*shouldExport*/true)); + } + writeExportAssignment(alias); + if ((privateDeclarations && !exportEquals) || aliasEmits.length) { + writeLine(); + write("export {"); + writeLine(); + increaseIndent(); + forEach(aliasEmits, alias => { + alias(); + write(","); writeLine(); + }); + decreaseIndent(); + write("};"); + writeLine(); + } + + return; + + 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) + const file = host.getSourceFile(entrypoint.resolvedModules[name].resolvedFileName); + if (!name.match(/^(\.|\/)/m)) { + table[file.fileName] = name; + } + if (!visited[file.fileName]) { + buildModuleDtsReverseLookupTable(file, table, visited); + } + }); + return table; + } + + function isModuleLevelDeclaration(node: Node) { + switch (node.kind) { + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.VariableStatement: + case SyntaxKind.VariableDeclaration: + 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 = {}; + const originalExportAssignment = writeExportAssignment; + 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[id] = declaration; + } + else { + // inline the declaration referred to by an export specifier with the specified name + if (declaration.kind === SyntaxKind.ExportSpecifier) { + 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 + const innertype = resolver.getDefiningTypeOfSymbol(symbol); + if (innertype && innertype.symbol) { + exportedMembers.push(innertype.symbol); + } + } + else { + aliasEmits.push(((d: ExportSpecifier) => () => { + const oldSourceFile = currentSourceFile; + currentSourceFile = getSourceFileOfNode(d); + const symbol = resolver.getDefiningTypeOfSymbol(d.symbol).symbol; + const symbolid = symbol && getSymbolId(symbol); + if (symbol && symbolid in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[symbolid]); + } + else { + Debug.fail("Encountered export alias of untraversed type when flattening."); + } + write(" as "); + emitIdentifier(d.name); + currentSourceFile = oldSourceFile; + })(d)); + } + } + } + // Handle export assignments + else if (declaration.kind === SyntaxKind.ExportAssignment) { + const 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); + } + } + } + } + + // Special case all the things + if (exported.name === "export=") { + exportEquals = type; + createDefaultExportAlias = ((value: string) => () => value)(type.symbol.name); + continue; + } + 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, exportedId); + const symbol = type.symbol; + if (symbol) { + const symbolId = getSymbolId(symbol); + createSymbolEntry(name, symbolId); + } + 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; + } + + if (type.symbol) { + const symbol = type.symbol; + const id = getSymbolId(symbol); + createSymbolEntry(symbol.name, id); + } + const exportedId = getSymbolId(exported); + createSymbolEntry(exported.name, exportedId); + } + return result; + } + + function collectDependentDeclarations(exportedMembers: Symbol[]): Map { + const dependentDeclarations: Map = {}; + const walker = resolver.getSymbolWalker(inspectSymbol); + forEach(exportedMembers, symbol => walker.visitTypeFromSymbol(symbol)); - // 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(); + return dependentDeclarations; + + 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 => { + const id = getNodeId(d); + // Collect declarations + const sourceFile = getSourceFileOfNode(d); + // Look for the outtermost declaration (ie, the outtermost namespace this declaration is nested within) + 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 + const fileName = moduleIdReverseLookup[sourceFile.fileName] || sourceFile.fileName; + // Get the topmost declaration from that stack of nodes + const 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); + } + } + } + else { + // Check if this type comes from an ambient external module declaration + 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 + const declaration = declarationStack.pop(); + const 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 (!(id in dependentDeclarations || id in declarations) && isModuleLevelDeclaration(d)) { + // Don't need to collect declarations which are not module-level + dependentDeclarations[id] = d; + } + const outtermostDeclaration = declarationStack.pop(); + const outterId = outtermostDeclaration && getNodeId(outtermostDeclaration); + if (outtermostDeclaration && outtermostDeclaration !== d && + outtermostDeclaration.kind !== SyntaxKind.ModuleDeclaration && + isModuleLevelDeclaration(outtermostDeclaration) && + (!(outterId in dependentDeclarations || outterId in declarations))) { + dependentDeclarations[outterId] = outtermostDeclaration; + walker.visitTypeFromSymbol(outtermostDeclaration.symbol); } }); - setWriter(oldWriter); } - prevModuleElementDeclarationEmitInfo = prevModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo); - moduleElementDeclarationEmitInfo = []; + return true; } - }); - moduleElementDeclarationEmitInfo = moduleElementDeclarationEmitInfo.concat(prevModuleElementDeclarationEmitInfo); - } - return { - reportedDeclarationError, - moduleElementDeclarationEmitInfo, - synchronousDeclarationOutput: writer.getText(), - referencePathsOutput, - }; + function findDeclarationStack(d: Declaration): Declaration[] { + let outermostNode: 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) { + outermostNode = outermostNode.parent; + visited.push(outermostNode); + } + return filter(visited, node => isDeclaration(node)) as Declaration[]; + } + } + } function hasInternalAnnotation(range: CommentRange) { let text = currentSourceFile.text; @@ -368,6 +774,16 @@ namespace ts { emitType(type); } + function writeEntityNameIfRenamed(entityName: EntityName | Expression): boolean { + 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; + } + function emitType(type: TypeNode | Identifier | QualifiedName) { switch (type.kind) { case SyntaxKind.AnyKeyword: @@ -409,15 +825,20 @@ namespace ts { } function writeEntityName(entityName: EntityName | Expression) { + // Lookup for renames + let written = writeEntityNameIfRenamed(entityName); + if (written) { + 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); } } @@ -452,7 +873,7 @@ namespace ts { } function emitTypePredicate(type: TypePredicateNode) { - writeTextOfNode(currentSourceFile, type.parameterName); + emitIdentifier(type.parameterName); write(" is "); emitType(type.type); } @@ -528,7 +949,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 @@ -667,7 +1088,7 @@ namespace ts { write("export "); } write("import "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); write(" = "); if (isInternalModuleImportEqualsDeclaration(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError); @@ -713,7 +1134,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()) { @@ -722,7 +1143,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("{ "); @@ -748,15 +1169,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) { @@ -797,11 +1223,21 @@ namespace ts { else { write("module "); } - writeTextOfNode(currentSourceFile, node.name); + if (node.name && 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 && node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } } let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; @@ -821,7 +1257,7 @@ namespace ts { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("type "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); emitTypeParameters(node.typeParameters); write(" = "); emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError); @@ -845,7 +1281,7 @@ namespace ts { write("const "); } write("enum "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); write(" {"); writeLine(); increaseIndent(); @@ -857,7 +1293,12 @@ namespace ts { function emitEnumMemberDeclaration(node: EnumMember) { emitJsDocComments(node); - writeTextOfNode(currentSourceFile, node.name); + if (node.name && node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } let enumMemberValue = resolver.getConstantValue(node); if (enumMemberValue !== undefined) { write(" = "); @@ -876,7 +1317,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 "); @@ -1007,7 +1448,7 @@ namespace ts { } write("class "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitTypeParameters(node.typeParameters); @@ -1031,7 +1472,7 @@ namespace ts { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("interface "); - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name); let prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitTypeParameters(node.typeParameters); @@ -1069,7 +1510,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. - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name as Identifier); + // If optional property emit ? if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) { write("?"); @@ -1156,7 +1598,7 @@ namespace ts { emitBindingPattern(bindingElement.name); } else { - writeTextOfNode(currentSourceFile, bindingElement.name); + emitIdentifier(bindingElement.name as Identifier); writeTypeOfDeclaration(bindingElement, /*type*/ undefined, getBindingElementTypeVisibilityError); } } @@ -1206,7 +1648,12 @@ namespace ts { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); emitClassMemberDeclarationFlags(node); - writeTextOfNode(currentSourceFile, node.name); + if (node.name && 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); @@ -1296,13 +1743,23 @@ namespace ts { } if (node.kind === SyntaxKind.FunctionDeclaration) { write("function "); - writeTextOfNode(currentSourceFile, node.name); + if (node.name && 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 && node.name.kind === SyntaxKind.Identifier) { + emitIdentifier(node.name as Identifier); + } + else { + writeTextOfNode(currentSourceFile, node.name); + } if (hasQuestionToken(node)) { write("?"); } @@ -1442,7 +1899,7 @@ namespace ts { emitBindingPattern(node.name); } else { - writeTextOfNode(currentSourceFile, node.name); + emitIdentifier(node.name as Identifier); } if (resolver.isOptionalParameter(node)) { write("?"); @@ -1568,7 +2025,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) { @@ -1591,13 +2048,27 @@ namespace ts { if (bindingElement.dotDotDotToken) { write("..."); } - writeTextOfNode(currentSourceFile, bindingElement.name); + emitIdentifier(bindingElement.name as Identifier); } } } } } + function emitIdentifier(node: Identifier) { + if (!node) { + return; + } + const symbol = resolver.getSymbolAtLocation(node); + const id = symbol && getSymbolId(symbol); + if (symbol && id in symbolGeneratedNameMap) { + write(symbolGeneratedNameMap[id]); + } + else { + writeTextOfNode(currentSourceFile, node); + } + } + function emitNode(node: Node) { switch (node.kind) { case SyntaxKind.FunctionDeclaration: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ad71d646b7b6a..b73782039e07c 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 e34e95e5f37e5..44c43b75100ad 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1080,6 +1080,21 @@ 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)) { + 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/types.ts b/src/compiler/types.ts index 19e4211533d98..43ddad0316741 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1450,6 +1450,7 @@ namespace ts { getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): ObjectType[]; getReturnTypeOfSignature(signature: Signature): Type; + getSymbolWalker(accept?: (type: Symbol) => boolean): SymbolWalker; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -1623,6 +1624,17 @@ namespace ts { isOptionalParameter(node: ParameterDeclaration): boolean; isArgumentsLocalBinding(node: Identifier): boolean; getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): SourceFile; + getExportsOfModule(symbol: Symbol): Symbol[]; + 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 { + visitType(type: Type): void; + visitTypeFromSymbol(symbol: Symbol): void; + reset(accept?: (type: Symbol) => boolean): void; } export const enum SymbolFlags { @@ -2103,6 +2115,7 @@ namespace ts { experimentalDecorators?: boolean; emitDecoratorMetadata?: boolean; moduleResolution?: ModuleResolutionKind; + optimizationEntrypoint?: string; allowUnusedLabels?: boolean; allowUnreachableCode?: boolean; noImplicitReturns?: boolean; diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 108c6f4518ae6..8a3da33ff6314 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -183,8 +183,9 @@ class CompilerBaselineRunner extends RunnerBase { jsCode += result.declFilesCode[i].code; } } - + options.optimizationEntrypoint = undefined; let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { + delete tcSettings["optimizationEntrypoint"]; harnessCompiler.setCompilerSettings(tcSettings); }, options); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 91f7e46f845d3..ce7ee2995ac78 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1157,6 +1157,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); @@ -1191,7 +1201,6 @@ namespace Harness { } } else { - // Goes to single --out file sourceFileName = outFile; } @@ -1199,10 +1208,10 @@ namespace Harness { 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/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, diff --git a/tests/baselines/reference/optimizationEntrypoint1.js b/tests/baselines/reference/optimizationEntrypoint1.js new file mode 100644 index 0000000000000..3a16b827e0ccd --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint1.js @@ -0,0 +1,193 @@ +//// [tests/cases/compiler/optimizationEntrypoint1.ts] //// + +//// [index.ts] + +export * from "./a"; +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 {default as BaseMain, Inner as Middle} from "./b"; + +export default class Main extends BaseMain { + memberc: Middle; +} + +export interface Inner { + item3: number; +} + +//// [b.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; +} + +//// [c.ts] +export default class Main { + member1: string; +} + +export interface Inner { + item: number; +} + +//// [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.__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) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return 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) { + __extends(Main, _super); + function Main() { + _super.apply(this, arguments); + } + return Main; + })(b_1["default"]); + exports.__esModule = true; + exports["default"] = Main; +}); +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; +}); + + +//// [bundled.d.ts] +declare class default_2 { + member1: string; +} +declare class default_3 extends default_2 { + member2: Inner_1; + details: Detail; +} +interface Inner_1 { + item: number; +} +interface Inner_2 { + item2: number; +} +export declare class default_1_1 extends default_3 { + memberc: Inner_2; +} +export interface Inner { + item4: number; +} +export interface default_1 { + number: number; +} +export interface Detail { + id: string; +} +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(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'. + + +==== bundled.d.ts (4 errors) ==== + declare class default_2 { + member1: string; + } + 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_1 { + item: number; + } + interface Inner_2 { + item2: number; + } + 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'. + } + export interface Inner { + item4: number; + } + export interface default_1 { + number: number; + } + export interface Detail { + id: string; + } + 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..e2b007bb1f6f6 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint1.symbols @@ -0,0 +1,110 @@ +=== 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)) + +export default class Main extends BaseMain { +>Main : Symbol(Main, Decl(a.ts, 0, 57)) +>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)) + +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 { +>Inner : Symbol(Inner, Decl(b.ts, 5, 1)) + + 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 { +>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 new file mode 100644 index 0000000000000..b804789c5dff4 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint1.types @@ -0,0 +1,110 @@ +=== 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 Main +>CBaseMain : typeof Main +>Inner : any +>Innermost : any + +export {default} from "./a"; +>default : typeof Main + +=== tests/cases/compiler/a.ts === +import {default as BaseMain, Inner as Middle} from "./b"; +>default : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Middle : any + +export default 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 {default as BaseMain, Inner as Innermost} from "./c"; +>default : typeof BaseMain +>BaseMain : typeof BaseMain +>Inner : any +>Innermost : any + +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 { +>Inner : Inner + + item2: number; +>item2 : number +} + +export interface Detail { +>Detail : Detail + + id: string; +>id : string +} + +=== tests/cases/compiler/c.ts === +export default class Main { +>Main : Main + + member1: string; +>member1 : string +} + +export interface Inner { +>Inner : 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..8de31ba567f79 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint2.js @@ -0,0 +1,65 @@ +//// [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; +} + +//// [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; +}); + + +//// [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..e3f0ea366fe20 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint3.js @@ -0,0 +1,80 @@ +//// [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; +} + + +//// [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; +}); + + +//// [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'. + + +==== 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..a54ee5b0c40b3 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.js @@ -0,0 +1,76 @@ +//// [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; + +//// [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; +}); + + +//// [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'. + + +==== 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..4fab89df71d53 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.symbols @@ -0,0 +1,31 @@ +=== 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 === + +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 {} +>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 new file mode 100644 index 0000000000000..e3a5beed84741 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint4.types @@ -0,0 +1,31 @@ +=== 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 === + +class Foo { +>Foo : Foo + + static field: {name: string} +>field : { name: string; } +>name : string +} + +namespace Foo {} +>Foo : typeof 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..1e493a213bb98 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint5.js @@ -0,0 +1,172 @@ +//// [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; + + +//// [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; +}); + + +//// [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 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; +} +export declare type GAlias = G | A; +export declare type IAlias = I; +export declare type AnyJ = J; 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 + diff --git a/tests/baselines/reference/optimizationEntrypoint6.js b/tests/baselines/reference/optimizationEntrypoint6.js new file mode 100644 index 0000000000000..73fb65929aa13 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint6.js @@ -0,0 +1,103 @@ +//// [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 {} + + +//// [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; +}); + + +//// [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..536e51b9071ca --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint7.js @@ -0,0 +1,138 @@ +//// [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 {} + + +//// [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", "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, 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.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 {} + +==== 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 + diff --git a/tests/baselines/reference/optimizationEntrypoint8.js b/tests/baselines/reference/optimizationEntrypoint8.js new file mode 100644 index 0000000000000..eccedcfabbe00 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.js @@ -0,0 +1,75 @@ +//// [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; +} + + + +//// [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", "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.d.ts] +import * as foo from "foo"; +export declare class Baz extends foo implements foo.Bar { + member: number; +} + + +//// [DtsFileErrors] + + +bundled.d.ts(1,22): 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; + + +==== bundled.d.ts (1 errors) ==== + import * as foo from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + 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 new file mode 100644 index 0000000000000..a14287ca97d4e --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +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)) + + 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..8f62375c9c079 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint8.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/node_modules/foo/index.d.ts === + +declare class Foo {} +>Foo : Foo + +declare namespace Foo { +>Foo : typeof 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 +} + + diff --git a/tests/baselines/reference/optimizationEntrypoint9.js b/tests/baselines/reference/optimizationEntrypoint9.js new file mode 100644 index 0000000000000..550eae31b3d58 --- /dev/null +++ b/tests/baselines/reference/optimizationEntrypoint9.js @@ -0,0 +1,113 @@ +//// [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 { } + + +//// [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; +}); + + +//// [all.d.ts] +/// +declare class Foo { + member: Bar; +} +declare class A { + member: typeof GlobalFoo; +} +declare var GlobalFoo: Foo; +export declare class B extends A { +} +export { +}; + + +//// [DtsFileErrors] + + +all.d.ts(9,32): error TS4020: Extends clause of exported class 'B' has or is using private name 'A'. + + +==== all.d.ts (1 errors) ==== + /// + declare class Foo { + member: Bar; + } + declare class A { + member: typeof GlobalFoo; + } + declare var GlobalFoo: Foo; + 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; + } + \ 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/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 - } -} - diff --git a/tests/cases/compiler/optimizationEntrypoint1.ts b/tests/cases/compiler/optimizationEntrypoint1.ts new file mode 100644 index 0000000000000..ce62160620a08 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint1.ts @@ -0,0 +1,56 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/index.ts +// @declaration: true + +// @Filename: index.ts +export * from "./a"; +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"; + +// @Filename: a.ts +import {default as BaseMain, Inner as Middle} from "./b"; + +export default class Main extends BaseMain { + memberc: Middle; +} + +export interface Inner { + item3: number; +} + +// @Filename: b.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; +} + +// @Filename: c.ts +export default class Main { + member1: string; +} + +export interface Inner { + item: number; +} \ No newline at end of file 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 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; +} diff --git a/tests/cases/compiler/optimizationEntrypoint4.ts b/tests/cases/compiler/optimizationEntrypoint4.ts new file mode 100644 index 0000000000000..436bb73b10ef5 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint4.ts @@ -0,0 +1,21 @@ +// @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} +} + +namespace Foo {} + +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..27dc3777dcc45 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint5.ts @@ -0,0 +1,40 @@ +// @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}; + i: foo.IAlias; + j: foo.J; + jj: foo.AnyJ; +} + +// @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 | A; +export class H {} +export class I {} +export type IAlias = I; +export class J {} +export type AnyJ = J; diff --git a/tests/cases/compiler/optimizationEntrypoint6.ts b/tests/cases/compiler/optimizationEntrypoint6.ts new file mode 100644 index 0000000000000..c9300a4f4ef67 --- /dev/null +++ b/tests/cases/compiler/optimizationEntrypoint6.ts @@ -0,0 +1,35 @@ +// @module: amd +// @outFile: bundled.js +// @optimizationEntrypoint: tests/cases/compiler/main.ts +// @declaration: true + +// @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 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 {} 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 {} 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; +} + 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 { }