Add type brands for fileId and fileIdListId (#44280)

This commit is contained in:
Sheetal Nandi
2021-05-27 11:15:13 -07:00
committed by GitHub
parent 6329a0df90
commit 8721dd06f1
2 changed files with 27 additions and 25 deletions

View File

@@ -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<BuilderState.FileInfo, "signature"> & {
/**
* 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<string, number>();
let fileIdsList: (readonly number[])[] | undefined;
let fileNamesToFileIdListId: ESMap<string, number> | undefined;
const fileNameToFileId = new Map<string, ProgramBuildInfoFileId>();
let fileIdsList: (readonly ProgramBuildInfoFileId[])[] | undefined;
let fileNamesToFileIdListId: ESMap<string, ProgramBuildInfoFileIdListId> | 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<Path>): number {
function toFileIdListId(set: ReadonlySet<Path>): 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<Path, BuilderState.FileInfo>();
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];
}

View File

@@ -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<BuilderState.FileInfo>;
options: CompilerOptions | undefined;
referencedMap?: MapLike<string[]>;
exportedModulesMap?: MapLike<string[]>;
semanticDiagnosticsPerFile?: readonly ProgramBuildInfoDiagnostic[];
affectedFilesPendingEmit?: readonly ProgramBuilderInfoFilePendingEmit[];
semanticDiagnosticsPerFile?: readonly ReadableProgramBuildInfoDiagnostic[];
affectedFilesPendingEmit?: readonly ReadableProgramBuilderInfoFilePendingEmit[];
}
type ReadableBuildInfo = Omit<BuildInfo, "program"> & { program: ProgramBuildInfo | undefined; size: number; };
type ReadableBuildInfo = Omit<BuildInfo, "program"> & { 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];
}