mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Read reusable module cache information from the buildinfo
This commit is contained in:
+60
-25
@@ -170,6 +170,11 @@ export interface ReusableBuilderProgramState extends BuilderState {
|
||||
modules: Map<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>> | undefined;
|
||||
typeRefs: Map<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>> | undefined;
|
||||
};
|
||||
resuableCacheResolutions?: {
|
||||
resolutions: ProgramBuildInfoCacheResolutions;
|
||||
fileNames: readonly string[];
|
||||
buildInfoPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -496,6 +501,8 @@ function convertToDiagnosticRelatedInformation(diagnostic: ReusableDiagnosticRel
|
||||
*/
|
||||
function releaseCache(state: BuilderProgramState) {
|
||||
BuilderState.releaseCache(state);
|
||||
// Store the resolutions if possible
|
||||
if (!state.resuableCacheResolutions) getCacheResolutions(state);
|
||||
state.program = undefined;
|
||||
}
|
||||
|
||||
@@ -1013,9 +1020,10 @@ export function isProgramBundleEmitBuildInfo(info: ProgramBuildInfo): info is Pr
|
||||
/**
|
||||
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
|
||||
*/
|
||||
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined): BuildInfo {
|
||||
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined, buildInfoPath: string,): BuildInfo {
|
||||
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
|
||||
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory));
|
||||
buildInfoPath = getNormalizedAbsolutePath(buildInfoPath, currentDirectory);
|
||||
const buildInfoDirectory = getDirectoryPath(buildInfoPath);
|
||||
// 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;
|
||||
const fileNames: string[] = [];
|
||||
@@ -1271,13 +1279,18 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
if (!resolutions) return;
|
||||
Debug.assertIsDefined(names);
|
||||
Debug.assertIsDefined(resolutionEntries);
|
||||
return {
|
||||
resolutions,
|
||||
names,
|
||||
resolutionEntries,
|
||||
modules,
|
||||
typeRefs,
|
||||
state.resuableCacheResolutions = {
|
||||
resolutions: {
|
||||
resolutions,
|
||||
names,
|
||||
resolutionEntries,
|
||||
modules,
|
||||
typeRefs,
|
||||
},
|
||||
fileNames,
|
||||
buildInfoPath,
|
||||
};
|
||||
return state.resuableCacheResolutions.resolutions;
|
||||
}
|
||||
|
||||
function toProgramBuildInfoResolutionCache<T extends ResolvedModuleWithFailedLookupLocations | ResolvedTypeReferenceDirectiveWithFailedLookupLocations>(
|
||||
@@ -1495,7 +1508,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
|
||||
}
|
||||
|
||||
const state = createBuilderProgramState(newProgram, oldState);
|
||||
newProgram.getBuildInfo = bundle => getBuildInfo(state, bundle);
|
||||
newProgram.getBuildInfo = (bundle, buildInfoPath) => getBuildInfo(state, bundle, buildInfoPath);
|
||||
|
||||
// To ensure that we arent storing any references to old program or new program without state
|
||||
newProgram = undefined!; // TODO: GH#18217
|
||||
@@ -1839,14 +1852,38 @@ export function toProgramEmitPending(value: ProgramBuildInfoBundlePendingEmit, o
|
||||
return !value ? getBuilderFileEmit(options || {}) : value;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo, buildInfoPath: string, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram {
|
||||
const program = buildInfo.program!;
|
||||
function getProgramBuildInfoFilePathDecoder(fileNames: readonly string[], buildInfoPath: string, host: ReadBuildProgramHost) {
|
||||
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
|
||||
let filePaths: Path[] | undefined;
|
||||
let fileAbsolutePaths: string[] | undefined;
|
||||
return { toAbsolutePath, toFilePath, toFileAbsolutePath };
|
||||
|
||||
function toPath(path: string) {
|
||||
return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function toAbsolutePath(path: string) {
|
||||
return getNormalizedAbsolutePath(path, buildInfoDirectory);
|
||||
}
|
||||
|
||||
function toFilePath(fileId: ProgramBuildInfoFileId): Path {
|
||||
return filePaths?.[fileId - 1] ??
|
||||
((filePaths ??= new Array(fileNames.length))[fileId - 1] = toPath(fileNames[fileId - 1]));
|
||||
}
|
||||
|
||||
function toFileAbsolutePath(fileId: ProgramBuildInfoAbsoluteFileId): string {
|
||||
return fileAbsolutePaths?.[fileId - 1] ??
|
||||
((fileAbsolutePaths ??= new Array(fileNames.length))[fileId - 1] = toAbsolutePath(fileNames[fileId - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo, buildInfoPath: string, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram {
|
||||
const program = buildInfo.program!;
|
||||
const { toFilePath, toAbsolutePath } = getProgramBuildInfoFilePathDecoder(program.fileNames, buildInfoPath, host);
|
||||
let state: ReusableBuilderProgramState;
|
||||
const filePaths = program.fileNames?.map(toPath);
|
||||
let filePathsSetList: Set<Path>[] | undefined;
|
||||
const latestChangedDtsFile = program.latestChangedDtsFile ? toAbsolutePath(program.latestChangedDtsFile) : undefined;
|
||||
if (isProgramBundleEmitBuildInfo(program)) {
|
||||
@@ -1862,6 +1899,7 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
|
||||
outSignature: program.outSignature,
|
||||
programEmitPending: program.pendingEmit === undefined ? undefined : toProgramEmitPending(program.pendingEmit, program.options),
|
||||
bundle: buildInfo.bundle,
|
||||
resuableCacheResolutions: toResuableCacheResolutions(),
|
||||
};
|
||||
}
|
||||
else {
|
||||
@@ -1897,6 +1935,7 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
|
||||
changedFilesSet: new Set(map(program.changeFileSet, toFilePath)),
|
||||
latestChangedDtsFile,
|
||||
emitSignatures: emitSignatures?.size ? emitSignatures : undefined,
|
||||
resuableCacheResolutions: toResuableCacheResolutions(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1926,18 +1965,6 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
|
||||
hasChangedEmitSignature: returnFalse,
|
||||
};
|
||||
|
||||
function toPath(path: string) {
|
||||
return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function toAbsolutePath(path: string) {
|
||||
return getNormalizedAbsolutePath(path, buildInfoDirectory);
|
||||
}
|
||||
|
||||
function toFilePath(fileId: ProgramBuildInfoFileId) {
|
||||
return filePaths[fileId - 1];
|
||||
}
|
||||
|
||||
function toFilePathsSet(fileIdsListId: ProgramBuildInfoFileIdListId) {
|
||||
return filePathsSetList![fileIdsListId - 1];
|
||||
}
|
||||
@@ -1953,6 +1980,14 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
|
||||
);
|
||||
return map;
|
||||
}
|
||||
|
||||
function toResuableCacheResolutions(): BuilderProgramState["resuableCacheResolutions"] {
|
||||
return program.cacheResolutions && {
|
||||
resolutions: program.cacheResolutions,
|
||||
fileNames: program.fileNames,
|
||||
buildInfoPath,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -811,7 +811,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
|
||||
emitSkipped = true;
|
||||
return;
|
||||
}
|
||||
const buildInfo = host.getBuildInfo(bundle) || createBuildInfo(/*program*/ undefined, bundle);
|
||||
const buildInfo = host.getBuildInfo(bundle, buildInfoPath) || createBuildInfo(/*program*/ undefined, bundle);
|
||||
// Pass buildinfo as additional data to avoid having to reparse
|
||||
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
|
||||
}
|
||||
|
||||
@@ -2491,7 +2491,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
return host.fileExists(f);
|
||||
},
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getBuildInfo: bundle => program.getBuildInfo?.(bundle),
|
||||
getBuildInfo: (bundle, buildInfoPath) => program.getBuildInfo?.(bundle, buildInfoPath),
|
||||
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
|
||||
redirectTargetsMap,
|
||||
getFileIncludeReasons: program.getFileIncludeReasons,
|
||||
|
||||
@@ -4539,7 +4539,7 @@ export interface Program extends ScriptReferenceHost {
|
||||
/** @internal */ forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined;
|
||||
/** @internal */ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined;
|
||||
/** @internal */ isSourceOfProjectReferenceRedirect(fileName: string): boolean;
|
||||
/** @internal */ getBuildInfo?(bundle: BundleBuildInfo | undefined): BuildInfo;
|
||||
/** @internal */ getBuildInfo?(bundle: BundleBuildInfo | undefined, buildInfoPath: string): BuildInfo;
|
||||
/** @internal */ emitBuildInfo(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult;
|
||||
/**
|
||||
* This implementation handles file exists to be true if file is source of project reference redirect when program is created using useSourceOfProjectReferenceRedirect
|
||||
@@ -7687,7 +7687,7 @@ export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolution
|
||||
getPrependNodes(): readonly (InputFiles | UnparsedSource)[];
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
getBuildInfo(bundle: BundleBuildInfo | undefined): BuildInfo | undefined;
|
||||
getBuildInfo(bundle: BundleBuildInfo | undefined, buildInfoPath: string): BuildInfo | undefined;
|
||||
getSourceFileFromReference: Program["getSourceFileFromReference"];
|
||||
readonly redirectTargetsMap: RedirectTargetsMap;
|
||||
createHash?(data: string): string;
|
||||
|
||||
Reference in New Issue
Block a user