Skip to content

Commit 22637a2

Browse files
authored
avoid computing a full shape for indirectly invalidated files (#44090)
* add shape updates to baselines * avoid computing a full shape for indirectly invalidated files using file version as shape is enough to keep build info valid and it's much cheaper
1 parent e9a51b4 commit 22637a2

File tree

313 files changed

+5074
-380
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

313 files changed

+5074
-380
lines changed

src/compiler/builder.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,14 +478,16 @@ namespace ts {
478478
// we need to update the signature to reflect correctness of the signature(which is output d.ts emit) of this file
479479
// This ensures that we dont later during incremental builds considering wrong signature.
480480
// Eg where this also is needed to ensure that .tsbuildinfo generated by incremental build should be same as if it was first fresh build
481+
// But we avoid expensive full shape computation, as using file version as shape is enough for correctness.
481482
BuilderState.updateShapeSignature(
482483
state,
483484
program,
484485
sourceFile,
485486
Debug.checkDefined(state.currentAffectedFilesSignatures),
486487
cancellationToken,
487488
computeHash,
488-
state.currentAffectedFilesExportedModulesMap
489+
state.currentAffectedFilesExportedModulesMap,
490+
/* useFileVersionAsSignature */ true
489491
);
490492
// If not dts emit, nothing more to do
491493
if (getEmitDeclarations(state.compilerOptions)) {

src/compiler/builderState.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ namespace ts {
398398
/**
399399
* Returns if the shape of the signature has changed since last emit
400400
*/
401-
export function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap<Path, string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap) {
401+
export function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap<Path, string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap, useFileVersionAsSignature: boolean = state.useFileVersionAsSignature) {
402402
Debug.assert(!!sourceFile);
403403
Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
404404

@@ -412,7 +412,7 @@ namespace ts {
412412

413413
const prevSignature = info.signature;
414414
let latestSignature: string | undefined;
415-
if (!sourceFile.isDeclarationFile && !state.useFileVersionAsSignature) {
415+
if (!sourceFile.isDeclarationFile && !useFileVersionAsSignature) {
416416
const emitOutput = getFileEmitOutput(
417417
programOfThisState,
418418
sourceFile,

src/testRunner/unittests/tscWatch/helpers.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ namespace ts.tscWatch {
468468
if (!builderProgram) return;
469469
if (builderProgram !== oldProgram?.[1]) {
470470
const state = builderProgram.getState();
471+
const internalState = state as unknown as BuilderState;
471472
if (state.semanticDiagnosticsPerFile?.size) {
472473
baseline.push("Semantic diagnostics in builder refreshed for::");
473474
for (const file of program.getSourceFiles()) {
@@ -479,6 +480,24 @@ namespace ts.tscWatch {
479480
else {
480481
baseline.push("No cached semantic diagnostics in the builder::");
481482
}
483+
if (internalState) {
484+
baseline.push("");
485+
if (internalState.hasCalledUpdateShapeSignature?.size) {
486+
baseline.push("Shape signatures in builder refreshed for::");
487+
internalState.hasCalledUpdateShapeSignature.forEach((path: Path) => {
488+
const info = state.fileInfos.get(path);
489+
if(info?.version === info?.signature || !info?.signature) {
490+
baseline.push(path + " (used version)");
491+
}
492+
else {
493+
baseline.push(path + " (computed .d.ts)");
494+
}
495+
});
496+
}
497+
else {
498+
baseline.push("No shapes updated in the builder::");
499+
}
500+
}
482501
baseline.push("");
483502
if (!baselineDependencies) return;
484503
baseline.push("Dependencies for::");

tests/baselines/reference/tsbuild/$publicAPI/initial-build/build-with-custom-transformers.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Semantic diagnostics in builder refreshed for::
6666
/lib/lib.d.ts
6767
/src/shared/index.ts
6868

69+
Shape signatures in builder refreshed for::
70+
/lib/lib.d.ts (used version)
71+
/src/shared/index.ts (used version)
72+
6973
Program root files: ["/src/webpack/index.ts"]
7074
Program options: {"composite":true,"configFilePath":"/src/webpack/tsconfig.json"}
7175
Program structureReused: Not
@@ -77,6 +81,10 @@ Semantic diagnostics in builder refreshed for::
7781
/lib/lib.d.ts
7882
/src/webpack/index.ts
7983

84+
Shape signatures in builder refreshed for::
85+
/lib/lib.d.ts (used version)
86+
/src/webpack/index.ts (used version)
87+
8088

8189
//// [/src/shared/index.d.ts]
8290
export declare function f1(): void;

tests/baselines/reference/tsbuild/emitDeclarationOnly/initial-build/only-dts-output-in-non-circular-imports-project-with-emitDeclarationOnly.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ export interface A {
344344
//// [/src/lib/c.d.ts] file written with same contents
345345
//// [/src/lib/c.d.ts.map] file written with same contents
346346
//// [/src/tsconfig.tsbuildinfo]
347-
{"program":{"fileNames":["../lib/lib.d.ts","./src/a.ts","./src/c.ts","./src/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},{"version":"5380514971-export class B { prop = \"hello\"; }\n\nclass C { }\nexport interface A {\n b: B; foo: any;\n}\n","signature":"-6995298949-export declare class B {\r\n prop: string;\r\n}\r\nexport interface A {\r\n b: B;\r\n foo: any;\r\n}\r\n"},{"version":"429593025-import { A } from \"./a\";\n\nexport interface C {\n a: A;\n}\n","signature":"-2697851509-import { A } from \"./a\";\r\nexport interface C {\r\n a: A;\r\n}\r\n"},{"version":"-2273488249-import { C } from \"./c\";\n\nexport interface B {\n b: C;\n}\n","signature":"20298635505-import { C } from \"./c\";\r\nexport interface B {\r\n b: C;\r\n}\r\n"}],"options":{"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":true,"esModuleInterop":true,"module":1,"outDir":"./lib","rootDir":"./src","sourceMap":true,"strict":true,"target":1},"fileIdsList":[[3],[2]],"referencedMap":[[4,1],[3,2]],"exportedModulesMap":[[4,1],[3,2]],"semanticDiagnosticsPerFile":[1,2,4,3]},"version":"FakeTSVersion"}
347+
{"program":{"fileNames":["../lib/lib.d.ts","./src/a.ts","./src/c.ts","./src/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},{"version":"5380514971-export class B { prop = \"hello\"; }\n\nclass C { }\nexport interface A {\n b: B; foo: any;\n}\n","signature":"-6995298949-export declare class B {\r\n prop: string;\r\n}\r\nexport interface A {\r\n b: B;\r\n foo: any;\r\n}\r\n"},{"version":"429593025-import { A } from \"./a\";\n\nexport interface C {\n a: A;\n}\n","signature":"-2697851509-import { A } from \"./a\";\r\nexport interface C {\r\n a: A;\r\n}\r\n"},"-2273488249-import { C } from \"./c\";\n\nexport interface B {\n b: C;\n}\n"],"options":{"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":true,"esModuleInterop":true,"module":1,"outDir":"./lib","rootDir":"./src","sourceMap":true,"strict":true,"target":1},"fileIdsList":[[3],[2]],"referencedMap":[[4,1],[3,2]],"exportedModulesMap":[[4,1],[3,2]],"semanticDiagnosticsPerFile":[1,2,4,3]},"version":"FakeTSVersion"}
348348

349349
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
350350
{
@@ -379,7 +379,7 @@ export interface A {
379379
},
380380
"./src/b.ts": {
381381
"version": "-2273488249-import { C } from \"./c\";\n\nexport interface B {\n b: C;\n}\n",
382-
"signature": "20298635505-import { C } from \"./c\";\r\nexport interface B {\r\n b: C;\r\n}\r\n"
382+
"signature": "-2273488249-import { C } from \"./c\";\n\nexport interface B {\n b: C;\n}\n"
383383
}
384384
},
385385
"options": {
@@ -419,6 +419,6 @@ export interface A {
419419
]
420420
},
421421
"version": "FakeTSVersion",
422-
"size": 1580
422+
"size": 1469
423423
}
424424

0 commit comments

Comments
 (0)