Skip to content

Instead of storing timestamp of when last d.ts file was modified, store its name so buildinfo becomes portable again #49717

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 6 commits into from
Jun 30, 2022
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
56 changes: 31 additions & 25 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ namespace ts {
*/
outSignature?: string;
/**
* Time when d.ts was modified
* Name of the file whose dts was the latest to change
*/
dtsChangeTime: number | undefined;
latestChangedDtsFile: string | undefined;
}

export const enum BuilderFileEmit {
Expand Down Expand Up @@ -112,7 +112,7 @@ namespace ts {
/**
* Records if change in dts emit was detected
*/
hasChangedEmitSignature?: boolean;
hasChangedEmitSignature?: boolean;
/**
* Files pending to be emitted
*/
Expand Down Expand Up @@ -141,7 +141,7 @@ namespace ts {
"programEmitComplete" |
"emitSignatures" |
"outSignature" |
"dtsChangeTime" |
"latestChangedDtsFile" |
"hasChangedEmitSignature"
> & { changedFilesSet: BuilderProgramState["changedFilesSet"] | undefined };

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

const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
const oldCompilerOptions = useOldState ? oldState!.compilerOptions : undefined;
Expand Down Expand Up @@ -301,7 +301,7 @@ namespace ts {
programEmitComplete: state.programEmitComplete,
emitSignatures: state.emitSignatures && new Map(state.emitSignatures),
outSignature: state.outSignature,
dtsChangeTime: state.dtsChangeTime,
latestChangedDtsFile: state.latestChangedDtsFile,
hasChangedEmitSignature: state.hasChangedEmitSignature,
changedFilesSet: outFilePath ? new Set(state.changedFilesSet) : undefined,
};
Expand All @@ -315,7 +315,7 @@ namespace ts {
state.programEmitComplete = savedEmitState.programEmitComplete;
state.emitSignatures = savedEmitState.emitSignatures;
state.outSignature = savedEmitState.outSignature;
state.dtsChangeTime = savedEmitState.dtsChangeTime;
state.latestChangedDtsFile = savedEmitState.latestChangedDtsFile;
state.hasChangedEmitSignature = savedEmitState.hasChangedEmitSignature;
if (savedEmitState.changedFilesSet) state.changedFilesSet = savedEmitState.changedFilesSet;
}
Expand Down Expand Up @@ -795,15 +795,16 @@ namespace ts {
affectedFilesPendingEmit?: ProgramBuilderInfoFilePendingEmit[];
changeFileSet?: readonly ProgramBuildInfoFileId[];
emitSignatures?: readonly ProgramBuildInfoEmitSignature[];
dtsChangeTime?: number;
// Because this is only output file in the program, we dont need fileId to deduplicate name
latestChangedDtsFile?: string;
}

export interface ProgramBundleEmitBuildInfo {
fileNames: readonly string[];
fileInfos: readonly string[];
options: CompilerOptions | undefined;
outSignature?: string;
dtsChangeTime?: number;
latestChangedDtsFile?: string;
}

export type ProgramBuildInfo = ProgramMultiFileEmitBuildInfo | ProgramBundleEmitBuildInfo;
Expand All @@ -815,13 +816,13 @@ namespace ts {
/**
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
*/
function getProgramBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName, host: BuilderProgramHost): ProgramBuildInfo | undefined {
function getProgramBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName): ProgramBuildInfo | undefined {
const outFilePath = outFile(state.compilerOptions);
if (outFilePath && !state.compilerOptions.composite) return;
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory));
// Update the dtsChange time in buildInfo
state.dtsChangeTime = state.hasChangedEmitSignature ? getCurrentTime(host).getTime() : state.dtsChangeTime;
// 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
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
if (outFilePath) {
const fileNames: string[] = [];
const fileInfos: string[] = [];
Expand All @@ -836,7 +837,7 @@ namespace ts {
fileInfos,
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions, "affectsBundleEmitBuildInfo"),
outSignature: state.outSignature,
dtsChangeTime: state.dtsChangeTime,
latestChangedDtsFile,
};
return result;
}
Expand Down Expand Up @@ -939,7 +940,7 @@ namespace ts {
affectedFilesPendingEmit,
changeFileSet,
emitSignatures,
dtsChangeTime: state.dtsChangeTime,
latestChangedDtsFile,
};
return result;

Expand Down Expand Up @@ -1137,7 +1138,7 @@ namespace ts {
*/
const computeHash = maybeBind(host, host.createHash);
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState, host.disableUseFileVersionAsSignature);
newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName, host);
newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName);

// To ensure that we arent storing any references to old program or new program without state
newProgram = undefined!; // TODO: GH#18217
Expand All @@ -1149,6 +1150,7 @@ namespace ts {
builderProgram.getState = getState;
builderProgram.saveEmitState = () => backupBuilderProgramEmitState(state);
builderProgram.restoreEmitState = (saved) => restoreBuilderProgramEmitState(state, saved);
builderProgram.hasChangedEmitSignature = () => !!state.hasChangedEmitSignature;
builderProgram.getAllDependencies = sourceFile => BuilderState.getAllDependencies(state, Debug.checkDefined(state.program), sourceFile);
builderProgram.getSemanticDiagnostics = getSemanticDiagnostics;
builderProgram.emit = emit;
Expand Down Expand Up @@ -1279,18 +1281,20 @@ namespace ts {
const filePath = sourceFiles[0].resolvedPath;
const oldSignature = state.emitSignatures?.get(filePath);
emitSignature ??= computeSignature(text, computeHash, data);
if (emitSignature !== oldSignature) {
(state.emitSignatures ??= new Map()).set(filePath, emitSignature);
state.hasChangedEmitSignature = true;
}
// Dont write dts files if they didn't change
if (emitSignature === oldSignature) return;
(state.emitSignatures ??= new Map()).set(filePath, emitSignature);
state.hasChangedEmitSignature = true;
state.latestChangedDtsFile = fileName;
}
}
else if (state.compilerOptions.composite) {
const newSignature = computeSignature(text, computeHash, data);
if (newSignature !== state.outSignature) {
state.outSignature = newSignature;
state.hasChangedEmitSignature = true;
}
// Dont write dts files if they didn't change
if (newSignature === state.outSignature) return;
state.outSignature = newSignature;
state.hasChangedEmitSignature = true;
state.latestChangedDtsFile = fileName;
}
}
if (writeFile) writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
Expand Down Expand Up @@ -1472,11 +1476,12 @@ namespace ts {
let state: ReusableBuilderProgramState;
let filePaths: Path[] | undefined;
let filePathsSetList: Set<Path>[] | undefined;
const latestChangedDtsFile = program.latestChangedDtsFile ? toAbsolutePath(program.latestChangedDtsFile) : undefined;
if (isProgramBundleEmitBuildInfo(program)) {
state = {
fileInfos: new Map(),
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
dtsChangeTime: program.dtsChangeTime,
latestChangedDtsFile,
outSignature: program.outSignature,
};
}
Expand Down Expand Up @@ -1506,7 +1511,7 @@ namespace ts {
affectedFilesPendingEmitKind: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(value[0]), value => value[1]),
affectedFilesPendingEmitIndex: program.affectedFilesPendingEmit && 0,
changedFilesSet: new Set(map(program.changeFileSet, toFilePath)),
dtsChangeTime: program.dtsChangeTime,
latestChangedDtsFile,
emitSignatures: emitSignatures?.size ? emitSignatures : undefined,
};
}
Expand Down Expand Up @@ -1534,6 +1539,7 @@ namespace ts {
getSemanticDiagnosticsOfNextAffectedFile: notImplemented,
emitBuildInfo: notImplemented,
close: noop,
hasChangedEmitSignature: returnFalse,
};

function toPath(path: string) {
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/builderPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace ts {
saveEmitState(): SavedBuildProgramEmitState;
/*@internal*/
restoreEmitState(saved: SavedBuildProgramEmitState): void;
/*@internal*/
hasChangedEmitSignature?(): boolean;
/**
* Returns current program
*/
Expand Down
2 changes: 0 additions & 2 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ namespace ts {
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
createHash?(data: string): string;
now?(): Date;
getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined;
}

Expand Down Expand Up @@ -832,7 +831,6 @@ namespace ts {
if (newBuildInfo.program && changedDtsText !== undefined && config.options.composite) {
// Update the output signature
(newBuildInfo.program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, createHash, changedDtsData);
newBuildInfo.program.dtsChangeTime = getCurrentTime(host).getTime();
}
// Update sourceFileInfo
const { js, dts, sourceFiles } = buildInfo.bundle!;
Expand Down
1 change: 0 additions & 1 deletion src/compiler/tsbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ namespace ts {
type: UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes | UpToDateStatusType.UpToDateWithInputFileText;
newestInputFileTime?: Date;
newestInputFileName?: string;
newestDeclarationFileContentChangedTime: Date | undefined;
oldestOutputFileName: string;
}

Expand Down
Loading