diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 68d3796fa345d..c63627df3e60b 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -705,9 +705,11 @@ namespace ts { return filterSemanticDiagnotics(diagnostics, state.compilerOptions); } - export type ProgramBuildInfoDiagnostic = number | [fileId: number, diagnostics: readonly ReusableDiagnostic[]]; - export type ProgramBuilderInfoFilePendingEmit = [fileId: number, emitKind: BuilderFileEmit]; - export type ProgramBuildInfoReferencedMap = [fileId: number, fileIdListId: number][]; + export type ProgramBuildInfoFileId = number & { __programBuildInfoFileIdBrand: any }; + export type ProgramBuildInfoFileIdListId = number & { __programBuildInfoFileIdListIdBrand: any }; + export type ProgramBuildInfoDiagnostic = ProgramBuildInfoFileId | [fileId: ProgramBuildInfoFileId, diagnostics: readonly ReusableDiagnostic[]]; + export type ProgramBuilderInfoFilePendingEmit = [fileId: ProgramBuildInfoFileId, emitKind: BuilderFileEmit]; + export type ProgramBuildInfoReferencedMap = [fileId: ProgramBuildInfoFileId, fileIdListId: ProgramBuildInfoFileIdListId][]; export type ProgramBuildInfoBuilderStateFileInfo = Omit & { /** * Signature is @@ -725,7 +727,7 @@ namespace ts { fileNames: readonly string[]; fileInfos: readonly ProgramBuildInfoFileInfo[]; options: CompilerOptions | undefined; - fileIdsList?: readonly (readonly number[])[]; + fileIdsList?: readonly (readonly ProgramBuildInfoFileId[])[]; referencedMap?: ProgramBuildInfoReferencedMap; exportedModulesMap?: ProgramBuildInfoReferencedMap; semanticDiagnosticsPerFile?: ProgramBuildInfoDiagnostic[]; @@ -740,9 +742,9 @@ namespace ts { const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory(); const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory)); const fileNames: string[] = []; - const fileNameToFileId = new Map(); - let fileIdsList: (readonly number[])[] | undefined; - let fileNamesToFileIdListId: ESMap | undefined; + const fileNameToFileId = new Map(); + let fileIdsList: (readonly ProgramBuildInfoFileId[])[] | undefined; + let fileNamesToFileIdListId: ESMap | undefined; const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramBuildInfoFileInfo => { // Ensure fileId const fileId = toFileId(key); @@ -825,22 +827,22 @@ namespace ts { return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName)); } - function toFileId(path: Path): number { + function toFileId(path: Path): ProgramBuildInfoFileId { let fileId = fileNameToFileId.get(path); if (fileId === undefined) { fileNames.push(relativeToBuildInfo(path)); - fileNameToFileId.set(path, fileId = fileNames.length); + fileNameToFileId.set(path, fileId = fileNames.length as ProgramBuildInfoFileId); } return fileId; } - function toFileIdListId(set: ReadonlySet): number { + function toFileIdListId(set: ReadonlySet): ProgramBuildInfoFileIdListId { const fileIds = arrayFrom(set.keys(), toFileId).sort(compareValues); const key = fileIds.join(); let fileIdListId = fileNamesToFileIdListId?.get(key); if (fileIdListId === undefined) { (fileIdsList ||= []).push(fileIds); - (fileNamesToFileIdListId ||= new Map()).set(key, fileIdListId = fileIdsList.length); + (fileNamesToFileIdListId ||= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId); } return fileIdListId; } @@ -1249,7 +1251,7 @@ namespace ts { const filePaths = program.fileNames.map(toPath); const filePathsSetList = program.fileIdsList?.map(fileIds => new Set(fileIds.map(toFilePath))); const fileInfos = new Map(); - program.fileInfos.forEach((fileInfo, index) => fileInfos.set(toFilePath(index + 1), toBuilderStateFileInfo(fileInfo))); + program.fileInfos.forEach((fileInfo, index) => fileInfos.set(toFilePath(index + 1 as ProgramBuildInfoFileId), toBuilderStateFileInfo(fileInfo))); const state: ReusableBuilderProgramState = { fileInfos, compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {}, @@ -1294,11 +1296,11 @@ namespace ts { return getNormalizedAbsolutePath(path, buildInfoDirectory); } - function toFilePath(fileId: number) { + function toFilePath(fileId: ProgramBuildInfoFileId) { return filePaths[fileId - 1]; } - function toFilePathsSet(fileIdsListId: number) { + function toFilePathsSet(fileIdsListId: ProgramBuildInfoFileIdListId) { return filePathsSetList![fileIdsListId - 1]; } diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 776ef9fcb062e..05800deaaac4f 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -236,24 +236,24 @@ interface Symbol { } } - type ProgramBuildInfoDiagnostic = string | [string, readonly ReusableDiagnostic[]]; - type ProgramBuilderInfoFilePendingEmit = [string, "DtsOnly" | "Full"]; - interface ProgramBuildInfo { + type ReadableProgramBuildInfoDiagnostic = string | [string, readonly ReusableDiagnostic[]]; + type ReadableProgramBuilderInfoFilePendingEmit = [string, "DtsOnly" | "Full"]; + interface ReadableProgramBuildInfo { fileNames: readonly string[]; fileNamesList: readonly (readonly string[])[] | undefined; fileInfos: MapLike; options: CompilerOptions | undefined; referencedMap?: MapLike; exportedModulesMap?: MapLike; - semanticDiagnosticsPerFile?: readonly ProgramBuildInfoDiagnostic[]; - affectedFilesPendingEmit?: readonly ProgramBuilderInfoFilePendingEmit[]; + semanticDiagnosticsPerFile?: readonly ReadableProgramBuildInfoDiagnostic[]; + affectedFilesPendingEmit?: readonly ReadableProgramBuilderInfoFilePendingEmit[]; } - type ReadableBuildInfo = Omit & { program: ProgramBuildInfo | undefined; size: number; }; + type ReadableBuildInfo = Omit & { program: ReadableProgramBuildInfo | undefined; size: number; }; function generateBuildInfoProgramBaseline(sys: System, originalWriteFile: System["writeFile"], buildInfoPath: string, buildInfo: BuildInfo) { - const fileInfos: ProgramBuildInfo["fileInfos"] = {}; - buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1)] = toBuilderStateFileInfo(fileInfo)); + const fileInfos: ReadableProgramBuildInfo["fileInfos"] = {}; + buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ProgramBuildInfoFileId)] = toBuilderStateFileInfo(fileInfo)); const fileNamesList = buildInfo.program?.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName)); - const program: ProgramBuildInfo | undefined = buildInfo.program && { + const program: ReadableProgramBuildInfo | undefined = buildInfo.program && { fileNames: buildInfo.program.fileNames, fileNamesList, fileInfos, @@ -282,11 +282,11 @@ interface Symbol { // For now its just JSON.stringify originalWriteFile.call(sys, `${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2)); - function toFileName(fileId: number) { + function toFileName(fileId: ProgramBuildInfoFileId) { return buildInfo.program!.fileNames[fileId - 1]; } - function toFileNames(fileIdsListId: number) { + function toFileNames(fileIdsListId: ProgramBuildInfoFileIdListId) { return fileNamesList![fileIdsListId - 1]; }