Skip to content

Commit e0b782d

Browse files
author
Andy Hanson
committed
Miscellaneous code cleanup relating to module resolution
1 parent eadf44d commit e0b782d

File tree

3 files changed

+30
-52
lines changed

3 files changed

+30
-52
lines changed

src/compiler/resolutionCache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ namespace ts {
8080
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache {
8181
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
8282
let filesWithInvalidatedResolutions: Map<true> | undefined;
83-
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
83+
let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap<ReadonlyArray<string>> | undefined;
8484
let allFilesHaveInvalidatedResolution = false;
8585
const nonRelativeExternalModuleResolutions = createMultiMap<ResolutionWithFailedLookupLocations>();
8686

@@ -242,14 +242,14 @@ namespace ts {
242242
}
243243

244244
function resolveNamesWithLocalCache<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
245-
names: string[],
245+
names: ReadonlyArray<string>,
246246
containingFile: string,
247247
redirectedReference: ResolvedProjectReference | undefined,
248248
cache: Map<Map<T>>,
249249
perDirectoryCacheWithRedirects: CacheWithRedirects<Map<T>>,
250250
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T,
251251
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
252-
reusedNames: string[] | undefined,
252+
reusedNames: ReadonlyArray<string> | undefined,
253253
logChanges: boolean): (R | undefined)[] {
254254

255255
const path = resolutionHost.toPath(containingFile);
@@ -681,7 +681,7 @@ namespace ts {
681681
);
682682
}
683683

684-
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map<ReadonlyArray<string>>) {
684+
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyMap<ReadonlyArray<string>>) {
685685
Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
686686
filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
687687
}

src/harness/virtualFileSystemWithWatch.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ interface Array<T> {}`
128128
return s && isString((<FsSymLink>s).symLink);
129129
}
130130

131-
function invokeWatcherCallbacks<T>(callbacks: T[], invokeCallback: (cb: T) => void): void {
131+
function invokeWatcherCallbacks<T>(callbacks: ReadonlyArray<T> | undefined, invokeCallback: (cb: T) => void): void {
132132
if (callbacks) {
133133
// The array copy is made to ensure that even if one of the callback removes the callbacks,
134134
// we dont miss any callbacks following it
@@ -650,15 +650,15 @@ interface Array<T> {}`
650650

651651
// For overriding the methods
652652
invokeWatchedDirectoriesCallback(folderFullPath: string, relativePath: string) {
653-
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
653+
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
654654
}
655655

656656
invokeWatchedDirectoriesRecursiveCallback(folderFullPath: string, relativePath: string) {
657-
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
657+
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
658658
}
659659

660660
private invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
661-
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath))!, ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
661+
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath)), ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
662662
}
663663

664664
private getRelativePathToDirectory(directoryFullPath: string, fileFullPath: string) {

src/server/project.ts

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -789,41 +789,6 @@ namespace ts.server {
789789
}
790790
}
791791

792-
/* @internal */
793-
private extractUnresolvedImportsFromSourceFile(file: SourceFile, ambientModules: string[]): ReadonlyArray<string> {
794-
const cached = this.cachedUnresolvedImportsPerFile.get(file.path);
795-
if (cached) {
796-
// found cached result, return
797-
return cached;
798-
}
799-
let unresolvedImports: string[] | undefined;
800-
if (file.resolvedModules) {
801-
file.resolvedModules.forEach((resolvedModule, name) => {
802-
// pick unresolved non-relative names
803-
if (!resolvedModule && !isExternalModuleNameRelative(name) && !isAmbientlyDeclaredModule(name)) {
804-
// for non-scoped names extract part up-to the first slash
805-
// for scoped names - extract up to the second slash
806-
let trimmed = name.trim();
807-
let i = trimmed.indexOf("/");
808-
if (i !== -1 && trimmed.charCodeAt(0) === CharacterCodes.at) {
809-
i = trimmed.indexOf("/", i + 1);
810-
}
811-
if (i !== -1) {
812-
trimmed = trimmed.substr(0, i);
813-
}
814-
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
815-
}
816-
});
817-
}
818-
819-
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
820-
return unresolvedImports || emptyArray;
821-
822-
function isAmbientlyDeclaredModule(name: string) {
823-
return ambientModules.some(m => m === name);
824-
}
825-
}
826-
827792
/* @internal */
828793
onFileAddedOrRemoved() {
829794
this.hasAddedorRemovedFiles = true;
@@ -857,15 +822,7 @@ namespace ts.server {
857822
// (can reuse cached imports for files that were not changed)
858823
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
859824
if (hasNewProgram || changedFiles.length) {
860-
let result: string[] | undefined;
861-
const ambientModules = this.program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName()));
862-
for (const sourceFile of this.program.getSourceFiles()) {
863-
const unResolved = this.extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules);
864-
if (unResolved !== emptyArray) {
865-
(result || (result = [])).push(...unResolved);
866-
}
867-
}
868-
this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray;
825+
this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program, this.cachedUnresolvedImportsPerFile);
869826
}
870827

871828
this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
@@ -1194,6 +1151,27 @@ namespace ts.server {
11941151
}
11951152
}
11961153

1154+
function getUnresolvedImports(program: Program, cachedUnresolvedImportsPerFile: Map<ReadonlyArray<string>>): SortedReadonlyArray<string> {
1155+
const ambientModules = program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName()));
1156+
return toDeduplicatedSortedArray(flatMap(program.getSourceFiles(), sourceFile =>
1157+
extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules, cachedUnresolvedImportsPerFile)));
1158+
}
1159+
function extractUnresolvedImportsFromSourceFile(file: SourceFile, ambientModules: ReadonlyArray<string>, cachedUnresolvedImportsPerFile: Map<ReadonlyArray<string>>): ReadonlyArray<string> {
1160+
return getOrUpdate(cachedUnresolvedImportsPerFile, file.path, () => {
1161+
if (!file.resolvedModules) return emptyArray;
1162+
let unresolvedImports: string[] | undefined;
1163+
file.resolvedModules.forEach((resolvedModule, name) => {
1164+
// pick unresolved non-relative names
1165+
if ((!resolvedModule || !resolutionExtensionIsTSOrJson(resolvedModule.extension)) &&
1166+
!isExternalModuleNameRelative(name) &&
1167+
!ambientModules.some(m => m === name)) {
1168+
unresolvedImports = append(unresolvedImports, parsePackageName(name).packageName);
1169+
}
1170+
});
1171+
return unresolvedImports || emptyArray;
1172+
});
1173+
}
1174+
11971175
/**
11981176
* If a file is opened and no tsconfig (or jsconfig) is found,
11991177
* the file and its imports/references are put into an InferredProject.

0 commit comments

Comments
 (0)