From a99c04e8f9893f9f193fad81df6a7f4430a5a077 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 14 Aug 2017 15:52:20 -0700 Subject: [PATCH] Make the failedLookuplocations to be readonly array --- src/compiler/resolutionCache.ts | 36 ++++++++++++++++++--------------- src/compiler/types.ts | 4 ++-- src/compiler/watchedProgram.ts | 5 +++-- src/server/project.ts | 2 +- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index e50e32dfce..4fefd87a83 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -13,7 +13,7 @@ namespace ts { resolveModuleNames(moduleNames: string[], containingFile: string, logChanges: boolean): ResolvedModuleFull[]; resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; - invalidateResolutionOfDeletedFile(filePath: Path): void; + invalidateResolutionOfFile(filePath: Path): void; invalidateResolutionOfChangedFailedLookupLocation(failedLookupLocation: string): void; createHasInvalidatedResolution(): HasInvalidatedResolution; @@ -22,7 +22,7 @@ namespace ts { } interface NameResolutionWithFailedLookupLocations { - readonly failedLookupLocations: string[]; + readonly failedLookupLocations: ReadonlyArray; isInvalidated?: boolean; } @@ -40,9 +40,12 @@ namespace ts { getGlobalCache?: () => string | undefined): ResolutionCache { let host: ModuleResolutionHost; - let filesWithChangedSetOfUnresolvedImports: Path[]; - let filesWithInvalidatedResolutions: Map; + let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; + let filesWithInvalidatedResolutions: Map | undefined; + // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file. + // The key in the map is source file's path. + // The values are Map of resolutions with key being name lookedup. const resolvedModuleNames = createMap>(); const resolvedTypeReferenceDirectives = createMap>(); @@ -54,7 +57,7 @@ namespace ts { finishRecordingFilesWithChangedResolutions, resolveModuleNames, resolveTypeReferenceDirectives, - invalidateResolutionOfDeletedFile, + invalidateResolutionOfFile, invalidateResolutionOfChangedFailedLookupLocation, createHasInvalidatedResolution, clear @@ -65,6 +68,7 @@ namespace ts { } function clear() { + // Close all the watches for failed lookup locations, irrespective of refcounts for them since this is to clear the cache clearMap(failedLookupLocationsWatches, (failedLookupLocationPath, failedLookupLocationWatcher) => { log(`Watcher: FailedLookupLocations: Status: ForceClose: LocationPath: ${failedLookupLocationPath}, refCount: ${failedLookupLocationWatcher.refCount}`); failedLookupLocationWatcher.fileWatcher.close(); @@ -103,7 +107,7 @@ namespace ts { // if it will fail and we've already found something during the first pass - we don't want to pollute its results const { resolvedModule, failedLookupLocations } = loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache); if (resolvedModule) { - return { resolvedModule, failedLookupLocations: primaryResult.failedLookupLocations.concat(failedLookupLocations) }; + return { resolvedModule, failedLookupLocations: addRange(primaryResult.failedLookupLocations as Array, failedLookupLocations) }; } } @@ -229,20 +233,20 @@ namespace ts { } type FailedLookupLocationAction = (failedLookupLocation: string, failedLookupLocationPath: Path, containingFile: string, name: string) => void; - function withFailedLookupLocations(failedLookupLocations: string[], containingFile: string, name: string, fn: FailedLookupLocationAction) { + function withFailedLookupLocations(failedLookupLocations: ReadonlyArray, containingFile: string, name: string, fn: FailedLookupLocationAction) { forEach(failedLookupLocations, failedLookupLocation => { fn(failedLookupLocation, toPath(failedLookupLocation), containingFile, name); }); } - function updateFailedLookupLocationWatches(containingFile: string, name: string, existingFailedLookupLocations: string[], failedLookupLocations: string[]) { + function updateFailedLookupLocationWatches(containingFile: string, name: string, existingFailedLookupLocations: ReadonlyArray | undefined, failedLookupLocations: ReadonlyArray) { if (failedLookupLocations) { if (existingFailedLookupLocations) { - const existingWatches = arrayToMap(existingFailedLookupLocations, failedLookupLocation => toPath(failedLookupLocation)); + const existingWatches = arrayToMap(existingFailedLookupLocations, toPath); for (const failedLookupLocation of failedLookupLocations) { const failedLookupLocationPath = toPath(failedLookupLocation); if (existingWatches && existingWatches.has(failedLookupLocationPath)) { - // still has same failed lookup location, keep the was + // still has same failed lookup location, keep the watch existingWatches.delete(failedLookupLocationPath); } else { @@ -272,7 +276,7 @@ namespace ts { cache: Map>, getResult: (s: T) => R, getResultFileName: (result: R) => string | undefined) { - cache.forEach((value, path: Path) => { + cache.forEach((value, path) => { if (path === deletedFilePath) { cache.delete(path); value.forEach((resolution, name) => { @@ -280,7 +284,7 @@ namespace ts { }); } else if (value) { - value.forEach((resolution, __name) => { + value.forEach(resolution => { if (resolution && !resolution.isInvalidated) { const result = getResult(resolution); if (result) { @@ -298,10 +302,10 @@ namespace ts { function invalidateResolutionCacheOfChangedFailedLookupLocation( failedLookupLocation: string, cache: Map>) { - cache.forEach((value, containingFile: Path) => { + cache.forEach((value, containingFile) => { if (value) { - value.forEach((resolution, __name) => { - if (resolution && !resolution.isInvalidated && contains(resolution.failedLookupLocations, failedLookupLocation)) { + value.forEach(resolution => { + if (resolution && !resolution.isInvalidated && some(resolution.failedLookupLocations, location => toPath(location) === failedLookupLocation)) { // Mark the file as needing re-evaluation of module resolution instead of using it blindly. resolution.isInvalidated = true; (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = createMap())).set(containingFile, true); @@ -311,7 +315,7 @@ namespace ts { }); } - function invalidateResolutionOfDeletedFile(filePath: Path) { + function invalidateResolutionOfFile(filePath: Path) { invalidateResolutionCacheOfDeletedFile(filePath, resolvedModuleNames, m => m.resolvedModule, r => r.resolvedFileName); invalidateResolutionCacheOfDeletedFile(filePath, resolvedTypeReferenceDirectives, m => m.resolvedTypeReferenceDirective, r => r.resolvedFileName); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9fe93f55cb..87d0ad153c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4011,7 +4011,7 @@ namespace ts { export interface ResolvedModuleWithFailedLookupLocations { readonly resolvedModule: ResolvedModuleFull | undefined; /* @internal */ - readonly failedLookupLocations: string[]; + readonly failedLookupLocations: ReadonlyArray; /*@internal*/ isInvalidated?: boolean; } @@ -4025,7 +4025,7 @@ namespace ts { export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { readonly resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective; - readonly failedLookupLocations: string[]; + readonly failedLookupLocations: ReadonlyArray; /*@internal*/ isInvalidated?: boolean; } diff --git a/src/compiler/watchedProgram.ts b/src/compiler/watchedProgram.ts index 6423b98189..bd2473a699 100644 --- a/src/compiler/watchedProgram.ts +++ b/src/compiler/watchedProgram.ts @@ -437,7 +437,7 @@ namespace ts { if (hostSourceFile !== undefined) { if (!isString(hostSourceFile)) { hostSourceFile.fileWatcher.close(); - resolutionCache.invalidateResolutionOfDeletedFile(path); + resolutionCache.invalidateResolutionOfFile(path); } sourceFilesCache.delete(path); } @@ -461,6 +461,7 @@ namespace ts { } else if (hostSourceFileInfo.sourceFile === oldSourceFile) { sourceFilesCache.delete(oldSourceFile.path); + resolutionCache.invalidateResolutionOfFile(oldSourceFile.path); } } } @@ -528,7 +529,7 @@ namespace ts { if (hostSourceFile) { // Update the cache if (eventKind === FileWatcherEventKind.Deleted) { - resolutionCache.invalidateResolutionOfDeletedFile(path); + resolutionCache.invalidateResolutionOfFile(path); if (!isString(hostSourceFile)) { hostSourceFile.fileWatcher.close(); sourceFilesCache.set(path, (hostSourceFile.version++).toString()); diff --git a/src/server/project.ts b/src/server/project.ts index fc6dca31ec..c5ee3aa42b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -547,7 +547,7 @@ namespace ts.server { if (this.isRoot(info)) { this.removeRoot(info); } - this.resolutionCache.invalidateResolutionOfDeletedFile(info.path); + this.resolutionCache.invalidateResolutionOfFile(info.path); this.cachedUnresolvedImportsPerFile.remove(info.path); if (detachFromProject) {