Experiment using caches to answer readFile, fileExists
This commit is contained in:
Родитель
993ffd70e6
Коммит
71a3cfdea2
|
@ -217,6 +217,7 @@ import {
|
|||
maybeBind,
|
||||
memoize,
|
||||
MethodDeclaration,
|
||||
missingFileModifiedTime,
|
||||
ModeAwareCache,
|
||||
ModeAwareCacheKey,
|
||||
ModifierFlags,
|
||||
|
@ -515,6 +516,7 @@ export function changeCompilerHostLikeToUseCache(
|
|||
host: CompilerHostLikeForCache,
|
||||
toPath: (fileName: string) => Path,
|
||||
getSourceFile?: CompilerHost["getSourceFile"],
|
||||
getModifiedTime?: (path: Path) => Date | undefined,
|
||||
) {
|
||||
const originalReadFile = host.readFile;
|
||||
const originalFileExists = host.fileExists;
|
||||
|
@ -533,7 +535,7 @@ export function changeCompilerHostLikeToUseCache(
|
|||
return setReadFileCache(key, fileName);
|
||||
};
|
||||
const setReadFileCache = (key: Path, fileName: string) => {
|
||||
const newValue = originalReadFile.call(host, fileName);
|
||||
const newValue = readFile(key, fileName);
|
||||
readFileCache.set(key, newValue !== undefined ? newValue : false);
|
||||
return newValue;
|
||||
};
|
||||
|
@ -543,7 +545,7 @@ export function changeCompilerHostLikeToUseCache(
|
|||
if (value !== undefined) return value !== false ? value : undefined; // could be .d.ts from output
|
||||
// Cache json or buildInfo
|
||||
if (!fileExtensionIs(fileName, Extension.Json) && !isBuildInfoFile(fileName)) {
|
||||
return originalReadFile.call(host, fileName);
|
||||
return readFile(key, fileName);
|
||||
}
|
||||
|
||||
return setReadFileCache(key, fileName);
|
||||
|
@ -568,7 +570,7 @@ export function changeCompilerHostLikeToUseCache(
|
|||
const key = toPath(fileName);
|
||||
const value = fileExistsCache.get(key);
|
||||
if (value !== undefined) return value;
|
||||
const newValue = originalFileExists.call(host, fileName);
|
||||
const newValue = fileExists(key, fileName);
|
||||
fileExistsCache.set(key, !!newValue);
|
||||
return newValue;
|
||||
};
|
||||
|
@ -623,6 +625,21 @@ export function changeCompilerHostLikeToUseCache(
|
|||
getSourceFileWithCache,
|
||||
readFileWithCache,
|
||||
};
|
||||
|
||||
function readFile(key: Path, fileName: string) {
|
||||
return fileExistsCache.get(key) !== false || getModifiedTime?.(key) !== missingFileModifiedTime ?
|
||||
originalReadFile.call(host, fileName) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function fileExists(key: Path, fileName: string) {
|
||||
const text = readFileCache.get(key);
|
||||
if (text !== undefined) return text !== false;
|
||||
const modifiedTime = getModifiedTime?.(key);
|
||||
return modifiedTime === undefined ?
|
||||
originalFileExists.call(host, fileName) :
|
||||
modifiedTime !== missingFileModifiedTime;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[];
|
||||
|
|
|
@ -759,6 +759,13 @@ function enableCache<T extends BuilderProgram>(state: SolutionBuilderState<T>) {
|
|||
host,
|
||||
fileName => toPath(state, fileName),
|
||||
(...args) => originalGetSourceFile.call(compilerHost, ...args),
|
||||
path => {
|
||||
const existing = state.filesWatched.get(path);
|
||||
if (!!existing) {
|
||||
if (!isFileWatcherWithModifiedTime(existing)) return existing;
|
||||
if (existing.modifiedTime) return existing.modifiedTime;
|
||||
}
|
||||
},
|
||||
);
|
||||
state.readFileWithCache = readFileWithCache;
|
||||
compilerHost.getSourceFile = getSourceFileWithCache!;
|
||||
|
@ -786,6 +793,7 @@ function disableCache<T extends BuilderProgram>(state: SolutionBuilderState<T>)
|
|||
host.writeFile = cache.originalWriteFile;
|
||||
compilerHost.getSourceFile = cache.originalGetSourceFile;
|
||||
state.readFileWithCache = cache.originalReadFileWithCache;
|
||||
if (!state.watch) state.filesWatched.clear();
|
||||
extendedConfigCache.clear();
|
||||
moduleResolutionCache?.clear();
|
||||
typeReferenceDirectiveResolutionCache?.clear();
|
||||
|
@ -1597,7 +1605,7 @@ function isFileWatcherWithModifiedTime(value: FileWatcherWithModifiedTime | Date
|
|||
function getModifiedTime<T extends BuilderProgram>(state: SolutionBuilderState<T>, fileName: string): Date {
|
||||
const path = toPath(state, fileName);
|
||||
const existing = state.filesWatched.get(path);
|
||||
if (state.watch && !!existing) {
|
||||
if (!!existing) {
|
||||
if (!isFileWatcherWithModifiedTime(existing)) return existing;
|
||||
if (existing.modifiedTime) return existing.modifiedTime;
|
||||
}
|
||||
|
@ -1605,10 +1613,8 @@ function getModifiedTime<T extends BuilderProgram>(state: SolutionBuilderState<T
|
|||
// This is either Date | FileWatcherWithModifiedTime because we query modified times first and
|
||||
// then after complete compilation of the project, watch the files so we dont want to loose these modified times.
|
||||
const result = ts_getModifiedTime(state.host, fileName);
|
||||
if (state.watch) {
|
||||
if (existing) (existing as FileWatcherWithModifiedTime).modifiedTime = result;
|
||||
else state.filesWatched.set(path, result);
|
||||
}
|
||||
if (existing) existing.modifiedTime = result;
|
||||
else state.filesWatched.set(path, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче