Skip to content

Commit c251d60

Browse files
authored
Instead of storing timestamp of when last d.ts file was modified, store its name so buildinfo becomes portable again (#49717)
* Store dts change file path in buildinfo * With composite, do not write d.ts files if they changed * Determine dts change based on outputs * Instead of storing time in buildinfo store filename which was last updated to get modified time stamp from * Get declaration time change lazily * Rename per feedback
1 parent 93f2d2b commit c251d60

File tree

191 files changed

+3632
-4277
lines changed

Some content is hidden

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

191 files changed

+3632
-4277
lines changed

src/compiler/builder.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ namespace ts {
6262
*/
6363
outSignature?: string;
6464
/**
65-
* Time when d.ts was modified
65+
* Name of the file whose dts was the latest to change
6666
*/
67-
dtsChangeTime: number | undefined;
67+
latestChangedDtsFile: string | undefined;
6868
}
6969

7070
export const enum BuilderFileEmit {
@@ -112,7 +112,7 @@ namespace ts {
112112
/**
113113
* Records if change in dts emit was detected
114114
*/
115-
hasChangedEmitSignature?: boolean;
115+
hasChangedEmitSignature?: boolean;
116116
/**
117117
* Files pending to be emitted
118118
*/
@@ -141,7 +141,7 @@ namespace ts {
141141
"programEmitComplete" |
142142
"emitSignatures" |
143143
"outSignature" |
144-
"dtsChangeTime" |
144+
"latestChangedDtsFile" |
145145
"hasChangedEmitSignature"
146146
> & { changedFilesSet: BuilderProgramState["changedFilesSet"] | undefined };
147147

@@ -167,7 +167,7 @@ namespace ts {
167167
state.outSignature = oldState?.outSignature;
168168
}
169169
state.changedFilesSet = new Set();
170-
state.dtsChangeTime = compilerOptions.composite ? oldState?.dtsChangeTime : undefined;
170+
state.latestChangedDtsFile = compilerOptions.composite ? oldState?.latestChangedDtsFile : undefined;
171171

172172
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
173173
const oldCompilerOptions = useOldState ? oldState!.compilerOptions : undefined;
@@ -301,7 +301,7 @@ namespace ts {
301301
programEmitComplete: state.programEmitComplete,
302302
emitSignatures: state.emitSignatures && new Map(state.emitSignatures),
303303
outSignature: state.outSignature,
304-
dtsChangeTime: state.dtsChangeTime,
304+
latestChangedDtsFile: state.latestChangedDtsFile,
305305
hasChangedEmitSignature: state.hasChangedEmitSignature,
306306
changedFilesSet: outFilePath ? new Set(state.changedFilesSet) : undefined,
307307
};
@@ -315,7 +315,7 @@ namespace ts {
315315
state.programEmitComplete = savedEmitState.programEmitComplete;
316316
state.emitSignatures = savedEmitState.emitSignatures;
317317
state.outSignature = savedEmitState.outSignature;
318-
state.dtsChangeTime = savedEmitState.dtsChangeTime;
318+
state.latestChangedDtsFile = savedEmitState.latestChangedDtsFile;
319319
state.hasChangedEmitSignature = savedEmitState.hasChangedEmitSignature;
320320
if (savedEmitState.changedFilesSet) state.changedFilesSet = savedEmitState.changedFilesSet;
321321
}
@@ -795,15 +795,16 @@ namespace ts {
795795
affectedFilesPendingEmit?: ProgramBuilderInfoFilePendingEmit[];
796796
changeFileSet?: readonly ProgramBuildInfoFileId[];
797797
emitSignatures?: readonly ProgramBuildInfoEmitSignature[];
798-
dtsChangeTime?: number;
798+
// Because this is only output file in the program, we dont need fileId to deduplicate name
799+
latestChangedDtsFile?: string;
799800
}
800801

801802
export interface ProgramBundleEmitBuildInfo {
802803
fileNames: readonly string[];
803804
fileInfos: readonly string[];
804805
options: CompilerOptions | undefined;
805806
outSignature?: string;
806-
dtsChangeTime?: number;
807+
latestChangedDtsFile?: string;
807808
}
808809

809810
export type ProgramBuildInfo = ProgramMultiFileEmitBuildInfo | ProgramBundleEmitBuildInfo;
@@ -815,13 +816,13 @@ namespace ts {
815816
/**
816817
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
817818
*/
818-
function getProgramBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName, host: BuilderProgramHost): ProgramBuildInfo | undefined {
819+
function getProgramBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName): ProgramBuildInfo | undefined {
819820
const outFilePath = outFile(state.compilerOptions);
820821
if (outFilePath && !state.compilerOptions.composite) return;
821822
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
822823
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory));
823-
// Update the dtsChange time in buildInfo
824-
state.dtsChangeTime = state.hasChangedEmitSignature ? getCurrentTime(host).getTime() : state.dtsChangeTime;
824+
// Convert the file name to Path here if we set the fileName instead to optimize multiple d.ts file emits and having to compute Canonical path
825+
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
825826
if (outFilePath) {
826827
const fileNames: string[] = [];
827828
const fileInfos: string[] = [];
@@ -836,7 +837,7 @@ namespace ts {
836837
fileInfos,
837838
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions, "affectsBundleEmitBuildInfo"),
838839
outSignature: state.outSignature,
839-
dtsChangeTime: state.dtsChangeTime,
840+
latestChangedDtsFile,
840841
};
841842
return result;
842843
}
@@ -939,7 +940,7 @@ namespace ts {
939940
affectedFilesPendingEmit,
940941
changeFileSet,
941942
emitSignatures,
942-
dtsChangeTime: state.dtsChangeTime,
943+
latestChangedDtsFile,
943944
};
944945
return result;
945946

@@ -1137,7 +1138,7 @@ namespace ts {
11371138
*/
11381139
const computeHash = maybeBind(host, host.createHash);
11391140
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState, host.disableUseFileVersionAsSignature);
1140-
newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName, host);
1141+
newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName);
11411142

11421143
// To ensure that we arent storing any references to old program or new program without state
11431144
newProgram = undefined!; // TODO: GH#18217
@@ -1149,6 +1150,7 @@ namespace ts {
11491150
builderProgram.getState = getState;
11501151
builderProgram.saveEmitState = () => backupBuilderProgramEmitState(state);
11511152
builderProgram.restoreEmitState = (saved) => restoreBuilderProgramEmitState(state, saved);
1153+
builderProgram.hasChangedEmitSignature = () => !!state.hasChangedEmitSignature;
11521154
builderProgram.getAllDependencies = sourceFile => BuilderState.getAllDependencies(state, Debug.checkDefined(state.program), sourceFile);
11531155
builderProgram.getSemanticDiagnostics = getSemanticDiagnostics;
11541156
builderProgram.emit = emit;
@@ -1279,18 +1281,20 @@ namespace ts {
12791281
const filePath = sourceFiles[0].resolvedPath;
12801282
const oldSignature = state.emitSignatures?.get(filePath);
12811283
emitSignature ??= computeSignature(text, computeHash, data);
1282-
if (emitSignature !== oldSignature) {
1283-
(state.emitSignatures ??= new Map()).set(filePath, emitSignature);
1284-
state.hasChangedEmitSignature = true;
1285-
}
1284+
// Dont write dts files if they didn't change
1285+
if (emitSignature === oldSignature) return;
1286+
(state.emitSignatures ??= new Map()).set(filePath, emitSignature);
1287+
state.hasChangedEmitSignature = true;
1288+
state.latestChangedDtsFile = fileName;
12861289
}
12871290
}
12881291
else if (state.compilerOptions.composite) {
12891292
const newSignature = computeSignature(text, computeHash, data);
1290-
if (newSignature !== state.outSignature) {
1291-
state.outSignature = newSignature;
1292-
state.hasChangedEmitSignature = true;
1293-
}
1293+
// Dont write dts files if they didn't change
1294+
if (newSignature === state.outSignature) return;
1295+
state.outSignature = newSignature;
1296+
state.hasChangedEmitSignature = true;
1297+
state.latestChangedDtsFile = fileName;
12941298
}
12951299
}
12961300
if (writeFile) writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
@@ -1472,11 +1476,12 @@ namespace ts {
14721476
let state: ReusableBuilderProgramState;
14731477
let filePaths: Path[] | undefined;
14741478
let filePathsSetList: Set<Path>[] | undefined;
1479+
const latestChangedDtsFile = program.latestChangedDtsFile ? toAbsolutePath(program.latestChangedDtsFile) : undefined;
14751480
if (isProgramBundleEmitBuildInfo(program)) {
14761481
state = {
14771482
fileInfos: new Map(),
14781483
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
1479-
dtsChangeTime: program.dtsChangeTime,
1484+
latestChangedDtsFile,
14801485
outSignature: program.outSignature,
14811486
};
14821487
}
@@ -1506,7 +1511,7 @@ namespace ts {
15061511
affectedFilesPendingEmitKind: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(value[0]), value => value[1]),
15071512
affectedFilesPendingEmitIndex: program.affectedFilesPendingEmit && 0,
15081513
changedFilesSet: new Set(map(program.changeFileSet, toFilePath)),
1509-
dtsChangeTime: program.dtsChangeTime,
1514+
latestChangedDtsFile,
15101515
emitSignatures: emitSignatures?.size ? emitSignatures : undefined,
15111516
};
15121517
}
@@ -1534,6 +1539,7 @@ namespace ts {
15341539
getSemanticDiagnosticsOfNextAffectedFile: notImplemented,
15351540
emitBuildInfo: notImplemented,
15361541
close: noop,
1542+
hasChangedEmitSignature: returnFalse,
15371543
};
15381544

15391545
function toPath(path: string) {

src/compiler/builderPublic.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace ts {
4242
saveEmitState(): SavedBuildProgramEmitState;
4343
/*@internal*/
4444
restoreEmitState(saved: SavedBuildProgramEmitState): void;
45+
/*@internal*/
46+
hasChangedEmitSignature?(): boolean;
4547
/**
4648
* Returns current program
4749
*/

src/compiler/emitter.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,6 @@ namespace ts {
712712
useCaseSensitiveFileNames(): boolean;
713713
getNewLine(): string;
714714
createHash?(data: string): string;
715-
now?(): Date;
716715
getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined;
717716
}
718717

@@ -832,7 +831,6 @@ namespace ts {
832831
if (newBuildInfo.program && changedDtsText !== undefined && config.options.composite) {
833832
// Update the output signature
834833
(newBuildInfo.program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, createHash, changedDtsData);
835-
newBuildInfo.program.dtsChangeTime = getCurrentTime(host).getTime();
836834
}
837835
// Update sourceFileInfo
838836
const { js, dts, sourceFiles } = buildInfo.bundle!;

src/compiler/tsbuild.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ namespace ts {
7272
type: UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes | UpToDateStatusType.UpToDateWithInputFileText;
7373
newestInputFileTime?: Date;
7474
newestInputFileName?: string;
75-
newestDeclarationFileContentChangedTime: Date | undefined;
7675
oldestOutputFileName: string;
7776
}
7877

0 commit comments

Comments
 (0)