TypeReference directive reuse (#49750)

This commit is contained in:
Sheetal Nandi
2022-11-07 15:15:11 -08:00
committed by GitHub
parent 1d96eb489e
commit 48aebcdcdb
13 changed files with 627 additions and 72 deletions
+3 -3
View File
@@ -15,7 +15,7 @@ import {
patternText, perfLogger, Push, readJson, removeExtension, removeFileExtension, removePrefix,
ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective,
ResolvedTypeReferenceDirectiveWithFailedLookupLocations, some, sort, SourceFile, startsWith, stringContains,
StringLiteralLike, supportedTSExtensionsFlat, toPath, tryExtractTSExtension, tryGetExtensionFromPath,
StringLiteralLike, supportedTSExtensionsFlat, toFileNameLowerCase, toPath, tryExtractTSExtension, tryGetExtensionFromPath,
tryParsePatterns, tryRemoveExtension, version, Version, versionMajorMinor, VersionRange,
} from "./_namespaces/ts";
@@ -795,9 +795,9 @@ export function createModeAwareCache<T>(): ModeAwareCache<T> {
}
/** @internal */
export function getResolutionName(entry: FileReference | StringLiteralLike) {
export function getResolutionName(entry: string | FileReference | StringLiteralLike) {
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
return isStringLiteralLike(entry) ? entry.text : entry.fileName.toLowerCase();
return !isString(entry) ? isStringLiteralLike(entry) ? entry.text : toFileNameLowerCase(entry.fileName) : entry;
}
/** @internal */
+107 -11
View File
@@ -58,7 +58,7 @@ import {
targetOptionDeclaration, toFileNameLowerCase, tokenToString, trace, tracing, trimStringEnd, TsConfigSourceFile,
TypeChecker, typeDirectiveIsEqualTo, TypeReferenceDirectiveResolutionCache, UnparsedSource, VariableDeclaration,
VariableStatement, walkUpParenthesizedExpressions, WriteFileCallback, WriteFileCallbackData,
writeFileEnsuringDirectories, zipToModeAwareCache,
writeFileEnsuringDirectories, zipToModeAwareCache, TypeReferenceDirectiveResolutionInfo, getResolvedTypeReferenceDirective,
} from "./_namespaces/ts";
import * as performance from "./_namespaces/ts.performance";
@@ -564,8 +564,7 @@ export function loadWithTypeDirectiveCache<T>(names: string[] | readonly FileRef
for (const name of names) {
let result: T;
const mode = getModeForFileReference(name, containingFileMode);
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
const strName = isString(name) ? name : name.fileName.toLowerCase();
const strName = getResolutionName(name);
const cacheKey = mode !== undefined ? `${mode}|${strName}` : strName;
if (cache.has(cacheKey)) {
result = cache.get(cacheKey)!;
@@ -1202,9 +1201,16 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
loadWithModeAwareCache(moduleNames, containingFile, containingFileName, redirectedReference, resolutionInfo, loader);
}
let actualResolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined) => (ResolvedTypeReferenceDirective | undefined)[];
let actualResolveTypeReferenceDirectiveNamesWorker: (
typeDirectiveNames: string[] | readonly FileReference[],
containingFile: string,
redirectedReference: ResolvedProjectReference | undefined,
containingFileMode: SourceFile["impliedNodeFormat"] | undefined,
resolutionInfo: TypeReferenceDirectiveResolutionInfo | undefined,
) => (ResolvedTypeReferenceDirective | undefined)[];
if (host.resolveTypeReferenceDirectives) {
actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, containingFileMode) => host.resolveTypeReferenceDirectives!(Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options, containingFileMode);
actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, containingFileMode, resolutionInfo) =>
host.resolveTypeReferenceDirectives!(Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options, containingFileMode, resolutionInfo);
}
else {
typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache());
@@ -1318,7 +1324,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
// This containingFilename needs to match with the one used in managed-side
const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
const resolutions = resolveTypeReferenceDirectiveNamesReusingOldState(typeReferences, containingFilename);
for (let i = 0; i < typeReferences.length; i++) {
// under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode
processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId });
@@ -1516,14 +1522,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return result;
}
function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string | SourceFile): readonly (ResolvedTypeReferenceDirective | undefined)[] {
function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string | SourceFile, resolutionInfo: TypeReferenceDirectiveResolutionInfo | undefined): readonly (ResolvedTypeReferenceDirective | undefined)[] {
if (!typeDirectiveNames.length) return [];
const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile;
const redirectedReference = !isString(containingFile) ? getRedirectReferenceForResolution(containingFile) : undefined;
const containingFileMode = !isString(containingFile) ? containingFile.impliedNodeFormat : undefined;
tracing?.push(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName });
performance.mark("beforeResolveTypeReference");
const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference, containingFileMode);
const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference, containingFileMode, resolutionInfo);
performance.mark("afterResolveTypeReference");
performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference");
tracing?.pop();
@@ -1759,6 +1765,96 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
}
}
function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: readonly FileReference[], containingFile: SourceFile): readonly (ResolvedTypeReferenceDirective | undefined)[];
function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: string[], containingFile: string): readonly (ResolvedTypeReferenceDirective | undefined)[];
function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string | SourceFile): readonly (ResolvedTypeReferenceDirective | undefined)[] {
if (structureIsReused === StructureIsReused.Not) {
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
// the best we can do is fallback to the default logic.
return resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, /*resolutionInfo*/ undefined);
}
const oldSourceFile = !isString(containingFile) ? oldProgram && oldProgram.getSourceFile(containingFile.fileName) : undefined;
if (!isString(containingFile)) {
if (oldSourceFile !== containingFile && containingFile.resolvedTypeReferenceDirectiveNames) {
// `file` was created for the new program.
//
// We only set `file.resolvedTypeReferenceDirectiveNames` via work from the current function,
// so it is defined iff we already called the current function on `file`.
// That call happened no later than the creation of the `file` object,
// which per above occurred during the current program creation.
// Since we assume the filesystem does not change during program creation,
// it is safe to reuse resolutions from the earlier call.
const result: (ResolvedTypeReferenceDirective | undefined)[] = [];
for (const typeDirectiveName of typeDirectiveNames as readonly FileReference[]) {
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
const resolvedTypeReferenceDirective = containingFile.resolvedTypeReferenceDirectiveNames.get(getResolutionName(typeDirectiveName), typeDirectiveName.resolutionMode || containingFile.impliedNodeFormat);
result.push(resolvedTypeReferenceDirective);
}
return result;
}
}
/** An ordered list of module names for which we cannot recover the resolution. */
let unknownTypeReferenceDirectiveNames: string[] | FileReference[] | undefined;
let result: (ResolvedTypeReferenceDirective | undefined)[] | undefined;
let reusedNames: (string | FileReference)[] | undefined;
const containingSourceFile = !isString(containingFile) ? containingFile : undefined;
const canReuseResolutions = !isString(containingFile) ?
containingFile === oldSourceFile && !hasInvalidatedResolutions(oldSourceFile.path) :
!hasInvalidatedResolutions(toPath(containingFile));
for (let i = 0; i < typeDirectiveNames.length; i++) {
const entry = typeDirectiveNames[i];
if (canReuseResolutions) {
const typeDirectiveName = getResolutionName(entry);
const mode = getModeForFileReference(entry, containingSourceFile?.impliedNodeFormat);
const oldResolvedTypeReferenceDirective = getResolvedTypeReferenceDirective(oldSourceFile, typeDirectiveName, mode);
if (oldResolvedTypeReferenceDirective) {
if (isTraceEnabled(options, host)) {
trace(host,
oldResolvedTypeReferenceDirective.packageId ?
Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 :
Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2,
typeDirectiveName,
!isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile,
oldResolvedTypeReferenceDirective.resolvedFileName,
oldResolvedTypeReferenceDirective.packageId && packageIdToString(oldResolvedTypeReferenceDirective.packageId)
);
}
(result ??= new Array(typeDirectiveNames.length))[i] = oldResolvedTypeReferenceDirective;
(reusedNames ??= []).push(entry);
continue;
}
}
// Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
(unknownTypeReferenceDirectiveNames ??= []).push(entry as FileReference & string);
}
if (!unknownTypeReferenceDirectiveNames) return result || emptyArray;
const resolutions = resolveTypeReferenceDirectiveNamesWorker(
unknownTypeReferenceDirectiveNames,
containingFile,
{ names: unknownTypeReferenceDirectiveNames, reusedNames }
);
// Combine results of resolutions
if (!result) {
// There were no unresolved resolutions.
Debug.assert(resolutions.length === typeDirectiveNames.length);
return resolutions;
}
let j = 0;
for (let i = 0; i < result.length; i++) {
if (!result[i]) {
result[i] = resolutions[j];
j++;
}
}
Debug.assert(j === resolutions.length);
return result;
}
function canReuseProjectReferences(): boolean {
return !forEachProjectReference(
oldProgram!.getProjectReferences(),
@@ -1962,7 +2058,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
}
const typesReferenceDirectives = newSourceFile.typeReferenceDirectives;
const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile);
const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesReusingOldState(typesReferenceDirectives, newSourceFile);
// ensure that types resolutions are still correct
const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, newSourceFile, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
if (typeReferenceResolutionsChanged) {
@@ -3229,13 +3325,13 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return;
}
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file);
const resolutions = resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectives, file);
for (let index = 0; index < typeDirectives.length; index++) {
const ref = file.typeReferenceDirectives[index];
const resolvedTypeReferenceDirective = resolutions[index];
// store resolved type directive on the file
const fileName = toFileNameLowerCase(ref.fileName);
setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective, getModeForFileReference(ref, file.impliedNodeFormat));
const mode = ref.resolutionMode || file.impliedNodeFormat;
if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) {
programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.resolution_mode_assertions_are_only_supported_when_moduleResolution_is_node16_or_nodenext));
+26 -7
View File
@@ -15,7 +15,7 @@ import {
ReadonlyESMap, removeSuffix, removeTrailingDirectorySeparator, resolutionExtensionIsTSOrJson, ResolvedModuleFull,
ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective,
ResolvedTypeReferenceDirectiveWithFailedLookupLocations, returnTrue, Set, some, SourceFile, startsWith,
stringContains, trace, unorderedRemoveItem, WatchDirectoryFlags,
stringContains, trace, TypeReferenceDirectiveResolutionInfo, unorderedRemoveItem, WatchDirectoryFlags,
} from "./_namespaces/ts";
/**
@@ -36,7 +36,13 @@ export interface ResolutionCache {
resolutionInfo: ModuleResolutionInfo | undefined
): (ResolvedModuleFull | undefined)[];
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined;
resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[];
resolveTypeReferenceDirectives(
typeDirectiveNames: string[] | readonly FileReference[],
containingFile: string,
redirectedReference: ResolvedProjectReference | undefined,
containingFileMode: SourceFile["impliedNodeFormat"] | undefined,
resolutionInfo: TypeReferenceDirectiveResolutionInfo | undefined,
): (ResolvedTypeReferenceDirective | undefined)[];
invalidateResolutionsOfFailedLookupLocations(): boolean;
invalidateResolutionOfFile(filePath: Path): void;
@@ -445,7 +451,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>;
shouldRetryResolution: (t: T) => boolean;
reusedNames?: readonly string[];
resolutionInfo?: ModuleResolutionInfo;
resolutionInfo?: ModuleResolutionInfo | TypeReferenceDirectiveResolutionInfo;
logChanges?: boolean;
containingSourceFile?: SourceFile;
containingSourceFileMode?: SourceFile["impliedNodeFormat"];
@@ -479,7 +485,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
const seenNamesInFile = createModeAwareCache<true>();
let i = 0;
for (const entry of containingSourceFile && resolutionInfo ? resolutionInfo.names : names) {
const name = !isString(entry) ? getResolutionName(entry) : entry;
const name = getResolutionName(entry);
// Imports supply a `containingSourceFile` but no `containingSourceFileMode` - it would be redundant
// they require calculating the mode for a given import from it's position in the resolution table, since a given
// import's syntax may override the file's default mode.
@@ -576,7 +582,13 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
if (containingSourceFile && resolutionInfo) {
resolutionInfo.reusedNames?.forEach(literal => seenNamesInFile.set(literal.text, getModeForUsageLocation(containingSourceFile, literal), true));
resolutionInfo.reusedNames?.forEach(entry => seenNamesInFile.set(
getResolutionName(entry),
!isString(entry) && isStringLiteralLike(entry) ?
getModeForUsageLocation(containingSourceFile, entry) :
getModeForFileReference(entry, containingSourceFile.impliedNodeFormat),
true,
));
reusedNames = undefined;
}
if (resolutionsInFile.size() !== seenNamesInFile.size()) {
@@ -610,7 +622,13 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
}
function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[] {
function resolveTypeReferenceDirectives(
typeDirectiveNames: string[] | readonly FileReference[],
containingFile: string,
redirectedReference?: ResolvedProjectReference,
containingFileMode?: SourceFile["impliedNodeFormat"],
resolutionInfo?: TypeReferenceDirectiveResolutionInfo,
): (ResolvedTypeReferenceDirective | undefined)[] {
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>({
names: typeDirectiveNames,
containingFile,
@@ -620,7 +638,8 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
loader: resolveTypeReferenceDirective,
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
shouldRetryResolution: resolution => resolution.resolvedTypeReferenceDirective === undefined,
containingSourceFileMode: containingFileMode
containingSourceFileMode: containingFileMode,
resolutionInfo,
});
}
+6 -4
View File
@@ -7291,10 +7291,12 @@ export type HasInvalidatedResolutions = (sourceFile: Path) => boolean;
/** @internal */
export type HasChangedAutomaticTypeDirectiveNames = () => boolean;
export interface ModuleResolutionInfo {
names: readonly StringLiteralLike[];
reusedNames: readonly StringLiteralLike[] | undefined;
export interface ResolutionInfo<T> {
names: readonly T[];
reusedNames: readonly T[] | undefined;
}
export type ModuleResolutionInfo = ResolutionInfo<StringLiteralLike>;
export type TypeReferenceDirectiveResolutionInfo = ResolutionInfo<string | FileReference>;
export interface CompilerHost extends ModuleResolutionHost {
getSourceFile(fileName: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
@@ -7324,7 +7326,7 @@ export interface CompilerHost extends ModuleResolutionHost {
/**
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
*/
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined): (ResolvedTypeReferenceDirective | undefined)[];
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined, resolutionInfo?: TypeReferenceDirectiveResolutionInfo): (ResolvedTypeReferenceDirective | undefined)[];
getEnvironmentVariable?(name: string): string | undefined;
/** @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions, hasSourceFileByPath: boolean): void;
/** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void;
+7 -2
View File
@@ -291,12 +291,17 @@ export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string
}
/** @internal */
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective): void {
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): void {
if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
sourceFile.resolvedTypeReferenceDirectiveNames = createModeAwareCache();
}
sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, /*mode*/ undefined, resolvedTypeReferenceDirective);
sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, mode, resolvedTypeReferenceDirective);
}
/** @internal */
export function getResolvedTypeReferenceDirective(sourceFile: SourceFile | undefined, typeReferenceDirectiveName: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): ResolvedTypeReferenceDirective | undefined {
return sourceFile?.resolvedTypeReferenceDirectiveNames?.get(typeReferenceDirectiveName, mode);
}
/** @internal */
+3 -2
View File
@@ -17,6 +17,7 @@ import {
ParsedCommandLine, Path, perfLogger, PollingInterval, ProjectReference, ResolutionCacheHost, ResolvedModule,
ResolvedProjectReference, ResolvedTypeReferenceDirective, returnFalse, returnTrue, ScriptTarget,
setGetSourceFileAsHashVersioned, SharedExtendedConfigFileWatcher, SourceFile, sys, System, toPath,
TypeReferenceDirectiveResolutionInfo,
updateErrorForNoInputFiles, updateMissingFilePathsWatch, updateSharedExtendedConfigFileWatcher,
updateWatchingWildcardDirectories, version, WatchDirectoryFlags, WatchOptions, WatchType, WatchTypeRegistry,
WildcardDirectoryWatcher,
@@ -134,7 +135,7 @@ export interface ProgramHost<T extends BuilderProgram> {
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile, resolutionInfo?: ModuleResolutionInfo): (ResolvedModule | undefined)[];
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined): (ResolvedTypeReferenceDirective | undefined)[];
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined, resolutionInfo?: TypeReferenceDirectiveResolutionInfo): (ResolvedTypeReferenceDirective | undefined)[];
/** If provided along with custom resolveModuleNames or resolveTypeReferenceDirectives, used to determine if unchanged file path needs to re-resolve modules/type reference directives */
hasInvalidatedResolutions?(filePath: Path): boolean;
/**
@@ -397,7 +398,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
((moduleNames, containingFile, reusedNames, redirectedReference, _options, sourceFile, resolutionInfo) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, sourceFile, resolutionInfo));
compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
((...args) => host.resolveTypeReferenceDirectives!(...args)) :
((typeDirectiveNames, containingFile, redirectedReference, _options, containingFileMode) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference, containingFileMode));
((typeDirectiveNames, containingFile, redirectedReference, _options, containingFileMode, resolutionInfo) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference, containingFileMode, resolutionInfo));
compilerHost.getModuleResolutionCache = host.resolveModuleNames ?
maybeBind(host, host.getModuleResolutionCache) :
(() => resolutionCache.getModuleResolutionCache());