Skip to content

Reducing tsbuildinfo size further #43695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 47 additions & 17 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,23 @@ namespace ts {
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 ProgramBuildInfoBuilderStateFileInfo = Omit<BuilderState.FileInfo, "signature"> & {
/**
* Signature is
* - undefined if FileInfo.version === FileInfo.signature
* - false if FileInfo has signature as undefined (not calculated)
* - string actual signature
*/
signature: string | false | undefined;
};
/**
* ProgramBuildInfoFileInfo is string if FileInfo.version === FileInfo.signature && !FileInfo.affectsGlobalScope otherwise encoded FileInfo
*/
export type ProgramBuildInfoFileInfo = string | ProgramBuildInfoBuilderStateFileInfo;
export interface ProgramBuildInfo {
fileNames: readonly string[];
fileInfos: readonly BuilderState.FileInfo[];
options: CompilerOptions;
fileInfos: readonly ProgramBuildInfoFileInfo[];
options: CompilerOptions | undefined;
fileIdsList?: readonly (readonly number[])[];
referencedMap?: ProgramBuildInfoReferencedMap;
exportedModulesMap?: ProgramBuildInfoReferencedMap;
Expand All @@ -730,12 +743,21 @@ namespace ts {
const fileNameToFileId = new Map<string, number>();
let fileIdsList: (readonly number[])[] | undefined;
let fileNamesToFileIdListId: ESMap<string, number> | undefined;
const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]) => {
const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramBuildInfoFileInfo => {
// Ensure fileId
const fileId = toFileId(key);
Debug.assert(fileNames[fileId - 1] === relativeToBuildInfo(key));
const signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key);
return signature === undefined ? value : { version: value.version, signature, affectsGlobalScope: value.affectsGlobalScope };
const actualSignature = signature ?? value.signature;
return value.version === actualSignature ?
value.affectsGlobalScope ?
{ version: value.version, signature: undefined, affectsGlobalScope: true } :
value.version :
actualSignature !== undefined ?
signature === undefined ?
value :
{ version: value.version, signature, affectsGlobalScope: value.affectsGlobalScope } :
{ version: value.version, signature: false, affectsGlobalScope: value.affectsGlobalScope };
});

let referencedMap: ProgramBuildInfoReferencedMap | undefined;
Expand Down Expand Up @@ -787,7 +809,7 @@ namespace ts {
return {
fileNames,
fileInfos,
options: convertToReusableCompilerOptions(state.compilerOptions, relativeToBuildInfoEnsuringAbsolutePath),
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions, relativeToBuildInfoEnsuringAbsolutePath),
fileIdsList,
referencedMap,
exportedModulesMap,
Expand Down Expand Up @@ -824,19 +846,19 @@ namespace ts {
}
}

function convertToReusableCompilerOptions(options: CompilerOptions, relativeToBuildInfo: (path: string) => string) {
const result: CompilerOptions = {};
function convertToProgramBuildInfoCompilerOptions(options: CompilerOptions, relativeToBuildInfo: (path: string) => string) {
let result: CompilerOptions | undefined;
const { optionsNameMap } = getOptionsNameMap();

for (const name of getOwnKeys(options).sort(compareStringsCaseSensitive)) {
result[name] = convertToReusableCompilerOptionValue(
optionsNameMap.get(name.toLowerCase()),
options[name] as CompilerOptionsValue,
relativeToBuildInfo
);
}
if (result.configFilePath) {
result.configFilePath = relativeToBuildInfo(result.configFilePath);
const optionInfo = optionsNameMap.get(name.toLowerCase());
if (optionInfo?.affectsEmit || optionInfo?.affectsSemanticDiagnostics || name === "skipLibCheck" || name === "skipDefaultLibCheck") {
(result ||= {})[name] = convertToReusableCompilerOptionValue(
optionInfo,
options[name] as CompilerOptionsValue,
relativeToBuildInfo
);
}
}
return result;
}
Expand Down Expand Up @@ -1211,17 +1233,25 @@ namespace ts {
}
}

export function toBuilderStateFileInfo(fileInfo: ProgramBuildInfoFileInfo): BuilderState.FileInfo {
return isString(fileInfo) ?
{ version: fileInfo, signature: fileInfo, affectsGlobalScope: undefined } :
isString(fileInfo.signature) ?
fileInfo as BuilderState.FileInfo :
{ version: fileInfo.version, signature: fileInfo.signature === false ? undefined : fileInfo.version, affectsGlobalScope: fileInfo.affectsGlobalScope };
}

export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo, buildInfoPath: string, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram {
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());

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), fileInfo));
program.fileInfos.forEach((fileInfo, index) => fileInfos.set(toFilePath(index + 1), toBuilderStateFileInfo(fileInfo)));
const state: ReusableBuilderProgramState = {
fileInfos,
compilerOptions: convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath),
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
referencedMap: toMapOfReferencedSet(program.referencedMap),
exportedModulesMap: toMapOfReferencedSet(program.exportedModulesMap),
semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && arrayToMap(program.semanticDiagnosticsPerFile, value => toFilePath(isNumber(value) ? value : value[0]), value => isNumber(value) ? emptyArray : value[1]),
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/builderState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace ts {
export interface FileInfo {
readonly version: string;
signature: string | undefined;
affectsGlobalScope: boolean;
affectsGlobalScope: boolean | undefined;
}
/**
* Referenced files with values for the keys as referenced file's path to be true
Expand Down Expand Up @@ -235,7 +235,7 @@ namespace ts {
}
}
}
fileInfos.set(sourceFile.resolvedPath, { version, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) });
fileInfos.set(sourceFile.resolvedPath, { version, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) || undefined });
}

return {
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/unittests/tsbuild/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ interface Symbol {
fileNames: readonly string[];
fileNamesList: readonly (readonly string[])[] | undefined;
fileInfos: MapLike<BuilderState.FileInfo>;
options: CompilerOptions;
options: CompilerOptions | undefined;
referencedMap?: MapLike<string[]>;
exportedModulesMap?: MapLike<string[]>;
semanticDiagnosticsPerFile?: readonly ProgramBuildInfoDiagnostic[];
Expand All @@ -251,7 +251,7 @@ interface Symbol {
type ReadableBuildInfo = Omit<BuildInfo, "program"> & { program: ProgramBuildInfo | 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)] = fileInfo);
buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1)] = toBuilderStateFileInfo(fileInfo));
const fileNamesList = buildInfo.program?.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName));
const program: ProgramBuildInfo | undefined = buildInfo.program && {
fileNames: buildInfo.program.fileNames,
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/unittests/tscWatch/incremental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,12 @@ namespace ts.tscWatch {
assert.deepEqual(state.fileInfos.get(file1.path as Path), {
version: system.createHash(file1.content),
signature: system.createHash(file1.content),
affectsGlobalScope: false,
affectsGlobalScope: undefined,
});
assert.deepEqual(state.fileInfos.get(file2.path as Path), {
version: system.createHash(fileModified.content),
signature: system.createHash(fileModified.content),
affectsGlobalScope: false,
affectsGlobalScope: undefined,
});

assert.deepEqual(state.compilerOptions, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ exports.bar = bar;


//// [/src/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../lib/lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","signature":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"4646078106-export function foo() { }","signature":"4646078106-export function foo() { }","affectsGlobalScope":false},{"version":"1045484683-export function bar() { }","signature":"1045484683-export function bar() { }","affectsGlobalScope":false}],"options":{"composite":true,"configFilePath":"./tsconfig.json","declaration":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../lib/lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},"4646078106-export function foo() { }","1045484683-export function bar() { }"],"options":{"composite":true,"declaration":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3]},"version":"FakeTSVersion"}

//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
{
Expand All @@ -52,18 +52,15 @@ exports.bar = bar;
},
"./a.ts": {
"version": "4646078106-export function foo() { }",
"signature": "4646078106-export function foo() { }",
"affectsGlobalScope": false
"signature": "4646078106-export function foo() { }"
},
"./b.ts": {
"version": "1045484683-export function bar() { }",
"signature": "1045484683-export function bar() { }",
"affectsGlobalScope": false
"signature": "1045484683-export function bar() { }"
}
},
"options": {
"composite": true,
"configFilePath": "./tsconfig.json",
"declaration": true
},
"referencedMap": {},
Expand All @@ -75,6 +72,6 @@ exports.bar = bar;
]
},
"version": "FakeTSVersion",
"size": 1456
"size": 788
}

Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ exports.a = 1;


//// [/src/target-tsc-build/shared/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../lib/lib.d.ts","../../shared/index.ts","../../shared/typings-base/globals.d.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","signature":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-22125360210-export const a: Unrestricted = 1;","signature":"-22125360210-export const a: Unrestricted = 1;","affectsGlobalScope":false},{"version":"4725476611-type Unrestricted = any;","signature":"4725476611-type Unrestricted = any;","affectsGlobalScope":true}],"options":{"composite":true,"configFilePath":"../../shared/tsconfig.json","listFiles":true,"outDir":"..","rootDir":"../.."},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../../../lib/lib.d.ts","../../shared/index.ts","../../shared/typings-base/globals.d.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},"-22125360210-export const a: Unrestricted = 1;",{"version":"4725476611-type Unrestricted = any;","affectsGlobalScope":true}],"options":{"composite":true,"outDir":"..","rootDir":"../.."},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3]},"version":"FakeTSVersion"}

//// [/src/target-tsc-build/shared/tsconfig.tsbuildinfo.readable.baseline.txt]
{
Expand All @@ -90,8 +90,7 @@ exports.a = 1;
},
"../../shared/index.ts": {
"version": "-22125360210-export const a: Unrestricted = 1;",
"signature": "-22125360210-export const a: Unrestricted = 1;",
"affectsGlobalScope": false
"signature": "-22125360210-export const a: Unrestricted = 1;"
},
"../../shared/typings-base/globals.d.ts": {
"version": "4725476611-type Unrestricted = any;",
Expand All @@ -101,8 +100,6 @@ exports.a = 1;
},
"options": {
"composite": true,
"configFilePath": "../../shared/tsconfig.json",
"listFiles": true,
"outDir": "..",
"rootDir": "../.."
},
Expand All @@ -115,7 +112,7 @@ exports.a = 1;
]
},
"version": "FakeTSVersion",
"size": 1567
"size": 901
}

//// [/src/target-tsc-build/webpack/index.d.ts]
Expand All @@ -130,7 +127,7 @@ exports.b = 1;


//// [/src/target-tsc-build/webpack/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../lib/lib.d.ts","../../webpack/index.ts","../../shared/typings-base/globals.d.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","signature":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-14405273073-export const b: Unrestricted = 1;","signature":"-14405273073-export const b: Unrestricted = 1;","affectsGlobalScope":false},{"version":"4725476611-type Unrestricted = any;","signature":"4725476611-type Unrestricted = any;","affectsGlobalScope":true}],"options":{"composite":true,"configFilePath":"../../webpack/tsconfig.json","listFiles":true,"outDir":"..","rootDir":"../.."},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,3,2]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../../../lib/lib.d.ts","../../webpack/index.ts","../../shared/typings-base/globals.d.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},"-14405273073-export const b: Unrestricted = 1;",{"version":"4725476611-type Unrestricted = any;","affectsGlobalScope":true}],"options":{"composite":true,"outDir":"..","rootDir":"../.."},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,3,2]},"version":"FakeTSVersion"}

//// [/src/target-tsc-build/webpack/tsconfig.tsbuildinfo.readable.baseline.txt]
{
Expand All @@ -148,8 +145,7 @@ exports.b = 1;
},
"../../webpack/index.ts": {
"version": "-14405273073-export const b: Unrestricted = 1;",
"signature": "-14405273073-export const b: Unrestricted = 1;",
"affectsGlobalScope": false
"signature": "-14405273073-export const b: Unrestricted = 1;"
},
"../../shared/typings-base/globals.d.ts": {
"version": "4725476611-type Unrestricted = any;",
Expand All @@ -159,8 +155,6 @@ exports.b = 1;
},
"options": {
"composite": true,
"configFilePath": "../../webpack/tsconfig.json",
"listFiles": true,
"outDir": "..",
"rootDir": "../.."
},
Expand All @@ -173,6 +167,6 @@ exports.b = 1;
]
},
"version": "FakeTSVersion",
"size": 1569
"size": 902
}

Loading