Skip to content

Commit a9b6369

Browse files
committed
Move symlinks cache to host
1 parent 5ddd273 commit a9b6369

File tree

16 files changed

+57
-47
lines changed

16 files changed

+57
-47
lines changed

src/compiler/moduleSpecifiers.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ namespace ts.moduleSpecifiers {
1111
readonly ending: Ending;
1212
}
1313

14-
let discoverProbableSymlinksCached: (() => ReadonlyMap<string>) | undefined;
15-
1614
function getPreferences({ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences {
1715
return {
1816
relativePreference: importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : importModuleSpecifierPreference === "non-relative" ? RelativePreference.NonRelative : RelativePreference.Auto,
@@ -190,7 +188,7 @@ namespace ts.moduleSpecifiers {
190188
return [getPathFromPathComponents(aParts), getPathFromPathComponents(bParts)];
191189
}
192190

193-
function discoverProbableSymlinks(files: readonly SourceFile[], getCanonicalFileName: GetCanonicalFileName, cwd: string): ReadonlyMap<string> {
191+
export function discoverProbableSymlinks(files: readonly SourceFile[], getCanonicalFileName: GetCanonicalFileName, cwd: string): ReadonlyMap<string> {
194192
const result = createMap<string>();
195193
const symlinks = flatten<readonly [string, string]>(mapDefined(files, sf =>
196194
sf.resolvedModules && compact(arrayFrom(mapIterator(sf.resolvedModules.values(), res =>
@@ -202,15 +200,6 @@ namespace ts.moduleSpecifiers {
202200
return result;
203201
}
204202

205-
export function withCachedSymlinks(files: readonly SourceFile[], getCanonicalFileName: GetCanonicalFileName, cwd: string, cb: () => void) {
206-
discoverProbableSymlinksCached = memoize(() => discoverProbableSymlinks(files, getCanonicalFileName, cwd));
207-
try {
208-
cb();
209-
} finally {
210-
discoverProbableSymlinksCached = undefined;
211-
}
212-
}
213-
214203
/**
215204
* Looks for existing imports that use symlinks to this module.
216205
* Symlinks will be returned first so they are preferred over the real path.
@@ -220,8 +209,8 @@ namespace ts.moduleSpecifiers {
220209
const importedFileNames = redirects ? [...redirects, importedFileName] : [importedFileName];
221210
const cwd = host.getCurrentDirectory ? host.getCurrentDirectory() : "";
222211
const targets = importedFileNames.map(f => getNormalizedAbsolutePath(f, cwd));
223-
const links = discoverProbableSymlinksCached
224-
? discoverProbableSymlinksCached()
212+
const links = host.getProbableSymlinks
213+
? host.getProbableSymlinks(files)
225214
: discoverProbableSymlinks(files, getCanonicalFileName, cwd);
226215

227216
const result: string[] = [];

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5922,11 +5922,13 @@ namespace ts {
59225922
directoryExists?(directoryName: string): boolean;
59235923
getCurrentDirectory?(): string;
59245924
}
5925-
/** @internal */
5925+
59265926
export interface ModuleSpecifierResolutionHost extends GetEffectiveTypeRootsHost {
59275927
useCaseSensitiveFileNames?(): boolean;
59285928
fileExists?(path: string): boolean;
59295929
readFile?(path: string): string | undefined;
5930+
/* @internal */
5931+
getProbableSymlinks?(files: readonly SourceFile[]): ReadonlyMap<string>;
59305932
}
59315933

59325934
// Note: this used to be deprecated in our public API, but is still used internally

src/server/project.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ namespace ts.server {
235235

236236
private importSuggestionsCache = Completions.createImportSuggestionsCache();
237237
private dirtyFilesForSuggestions: Map<true> | undefined;
238+
private symlinks: ReadonlyMap<string> | undefined;
238239

239240
/*@internal*/
240241
constructor(
@@ -300,6 +301,13 @@ namespace ts.server {
300301
return this.projectService.typingsCache;
301302
}
302303

304+
getProbableSymlinks(files: readonly SourceFile[]): ReadonlyMap<string> {
305+
return this.symlinks || (this.symlinks = moduleSpecifiers.discoverProbableSymlinks(
306+
files,
307+
this.getCanonicalFileName,
308+
this.getCurrentDirectory()));
309+
}
310+
303311
// Method of LanguageServiceHost
304312
getCompilationSettings() {
305313
return this.compilerOptions;
@@ -1034,6 +1042,10 @@ namespace ts.server {
10341042
this.dirtyFilesForSuggestions.clear();
10351043
}
10361044

1045+
if (this.hasAddedorRemovedFiles) {
1046+
this.symlinks = undefined;
1047+
}
1048+
10371049
const oldExternalFiles = this.externalFiles || emptyArray as SortedReadonlyArray<string>;
10381050
this.externalFiles = this.getExternalFiles();
10391051
enumerateInsertsAndDeletes<string, string>(this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()),

src/services/codefixes/importFixes.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -632,25 +632,23 @@ namespace ts.codefix {
632632
) {
633633
let filteredCount = 0;
634634
const packageJson = filterByPackageJson && createAutoImportFilter(from, host, redirectTargetsMap);
635-
moduleSpecifiers.withCachedSymlinks(allSourceFiles, hostGetCanonicalFileName(host), host.getCurrentDirectory(), () => {
636-
forEachExternalModule(checker, allSourceFiles, (module, sourceFile) => {
637-
if (sourceFile === undefined) {
638-
if (!packageJson || packageJson.allowsImportingAmbientModule(module, allSourceFiles)) {
639-
cb(module);
640-
}
641-
else if (packageJson) {
642-
filteredCount++;
643-
}
635+
forEachExternalModule(checker, allSourceFiles, (module, sourceFile) => {
636+
if (sourceFile === undefined) {
637+
if (!packageJson || packageJson.allowsImportingAmbientModule(module, allSourceFiles)) {
638+
cb(module);
644639
}
645-
else if (sourceFile && sourceFile !== from && isImportablePath(from.fileName, sourceFile.fileName)) {
646-
if (!packageJson || packageJson.allowsImportingSourceFile(sourceFile, allSourceFiles)) {
647-
cb(module);
648-
}
649-
else if (packageJson) {
650-
filteredCount++;
651-
}
640+
else if (packageJson) {
641+
filteredCount++;
652642
}
653-
});
643+
}
644+
else if (sourceFile && sourceFile !== from && isImportablePath(from.fileName, sourceFile.fileName)) {
645+
if (!packageJson || packageJson.allowsImportingSourceFile(sourceFile, allSourceFiles)) {
646+
cb(module);
647+
}
648+
else if (packageJson) {
649+
filteredCount++;
650+
}
651+
}
654652
});
655653
if (host.log) {
656654
host.log(`forEachExternalModuleToImportFrom: filtered out ${filteredCount} modules by package.json contents`);

src/services/types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ namespace ts {
190190
//
191191
// Public interface of the host of a language service instance.
192192
//
193-
export interface LanguageServiceHost extends GetEffectiveTypeRootsHost {
193+
export interface LanguageServiceHost extends ModuleSpecifierResolutionHost {
194194
getCompilationSettings(): CompilerOptions;
195195
getNewLine?(): string;
196196
getProjectVersion?(): string;
@@ -206,7 +206,6 @@ namespace ts {
206206
log?(s: string): void;
207207
trace?(s: string): void;
208208
error?(s: string): void;
209-
useCaseSensitiveFileNames?(): boolean;
210209

211210
/*
212211
* LS host can optionally implement these methods to support completions for module specifiers.

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,6 +3030,11 @@ declare namespace ts {
30303030
directoryExists?(directoryName: string): boolean;
30313031
getCurrentDirectory?(): string;
30323032
}
3033+
export interface ModuleSpecifierResolutionHost extends GetEffectiveTypeRootsHost {
3034+
useCaseSensitiveFileNames?(): boolean;
3035+
fileExists?(path: string): boolean;
3036+
readFile?(path: string): string | undefined;
3037+
}
30333038
export interface TextSpan {
30343039
start: number;
30353040
length: number;
@@ -4889,7 +4894,7 @@ declare namespace ts {
48894894
fileName: Path;
48904895
packageName: string;
48914896
}
4892-
interface LanguageServiceHost extends GetEffectiveTypeRootsHost {
4897+
interface LanguageServiceHost extends ModuleSpecifierResolutionHost {
48934898
getCompilationSettings(): CompilerOptions;
48944899
getNewLine?(): string;
48954900
getProjectVersion?(): string;
@@ -4905,7 +4910,6 @@ declare namespace ts {
49054910
log?(s: string): void;
49064911
trace?(s: string): void;
49074912
error?(s: string): void;
4908-
useCaseSensitiveFileNames?(): boolean;
49094913
readDirectory?(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[];
49104914
readFile?(path: string, encoding?: string): string | undefined;
49114915
realpath?(path: string): string;
@@ -8469,9 +8473,11 @@ declare namespace ts.server {
84698473
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void, logErrors?: (message: string) => void): {} | undefined;
84708474
private importSuggestionsCache;
84718475
private dirtyFilesForSuggestions;
8476+
private symlinks;
84728477
isKnownTypesPackageName(name: string): boolean;
84738478
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
84748479
private readonly typingsCache;
8480+
getProbableSymlinks(files: readonly SourceFile[]): ReadonlyMap<string>;
84758481
getCompilationSettings(): CompilerOptions;
84768482
getCompilerOptions(): CompilerOptions;
84778483
getNewLine(): string;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,6 +3030,11 @@ declare namespace ts {
30303030
directoryExists?(directoryName: string): boolean;
30313031
getCurrentDirectory?(): string;
30323032
}
3033+
export interface ModuleSpecifierResolutionHost extends GetEffectiveTypeRootsHost {
3034+
useCaseSensitiveFileNames?(): boolean;
3035+
fileExists?(path: string): boolean;
3036+
readFile?(path: string): string | undefined;
3037+
}
30333038
export interface TextSpan {
30343039
start: number;
30353040
length: number;
@@ -4889,7 +4894,7 @@ declare namespace ts {
48894894
fileName: Path;
48904895
packageName: string;
48914896
}
4892-
interface LanguageServiceHost extends GetEffectiveTypeRootsHost {
4897+
interface LanguageServiceHost extends ModuleSpecifierResolutionHost {
48934898
getCompilationSettings(): CompilerOptions;
48944899
getNewLine?(): string;
48954900
getProjectVersion?(): string;
@@ -4905,7 +4910,6 @@ declare namespace ts {
49054910
log?(s: string): void;
49064911
trace?(s: string): void;
49074912
error?(s: string): void;
4908-
useCaseSensitiveFileNames?(): boolean;
49094913
readDirectory?(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[];
49104914
readFile?(path: string, encoding?: string): string | undefined;
49114915
realpath?(path: string): string;

0 commit comments

Comments
 (0)