Skip to content

Commit fdb5e95

Browse files
committed
Use the module cache to resolve non relative module name as well
1 parent 403b7d8 commit fdb5e95

17 files changed

+77
-37
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3296,7 +3296,7 @@
32963296
"category": "Message",
32973297
"code": 6146
32983298
},
3299-
"Resolution for module '{0}' was found in cache.": {
3299+
"Resolution for module '{0}' was found in cache from location '{1}'.": {
33003300
"category": "Message",
33013301
"code": 6147
33023302
},

src/compiler/moduleNameResolver.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,20 @@ namespace ts {
335335
}
336336

337337
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
338-
const directoryToModuleNameMap = createMap<Map<ResolvedModuleWithFailedLookupLocations>>();
339-
const moduleNameToDirectoryMap = createMap<PerModuleNameCache>();
338+
return createModuleResolutionCacheWithMaps(
339+
createMap<Map<ResolvedModuleWithFailedLookupLocations>>(),
340+
createMap<PerModuleNameCache>(),
341+
currentDirectory,
342+
getCanonicalFileName
343+
);
344+
}
345+
346+
/*@internal*/
347+
export function createModuleResolutionCacheWithMaps(
348+
directoryToModuleNameMap: Map<Map<ResolvedModuleWithFailedLookupLocations>>,
349+
moduleNameToDirectoryMap: Map<PerModuleNameCache>,
350+
currentDirectory: string,
351+
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
340352

341353
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
342354

@@ -445,7 +457,7 @@ namespace ts {
445457

446458
if (result) {
447459
if (traceEnabled) {
448-
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
460+
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
449461
}
450462
}
451463
else {
@@ -1187,7 +1199,7 @@ namespace ts {
11871199
const result = cache && cache.get(containingDirectory);
11881200
if (result) {
11891201
if (traceEnabled) {
1190-
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
1202+
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
11911203
}
11921204
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
11931205
}

src/compiler/resolutionCache.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace ts {
4242

4343
export interface ResolutionCacheHost extends ModuleResolutionHost {
4444
toPath(fileName: string): Path;
45+
getCanonicalFileName: GetCanonicalFileName;
4546
getCompilationSettings(): CompilerOptions;
4647
watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher;
4748
onInvalidatedResolution(): void;
@@ -78,18 +79,25 @@ namespace ts {
7879
let filesWithInvalidatedResolutions: Map<true> | undefined;
7980
let allFilesHaveInvalidatedResolution = false;
8081

82+
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
83+
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
84+
8185
// The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
8286
// The key in the map is source file's path.
8387
// The values are Map of resolutions with key being name lookedup.
8488
const resolvedModuleNames = createMap<Map<ResolvedModuleWithFailedLookupLocations>>();
8589
const perDirectoryResolvedModuleNames = createMap<Map<ResolvedModuleWithFailedLookupLocations>>();
90+
const nonRelaticeModuleNameCache = createMap<PerModuleNameCache>();
91+
const moduleResolutionCache = createModuleResolutionCacheWithMaps(
92+
perDirectoryResolvedModuleNames,
93+
nonRelaticeModuleNameCache,
94+
getCurrentDirectory(),
95+
resolutionHost.getCanonicalFileName
96+
);
8697

8798
const resolvedTypeReferenceDirectives = createMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
8899
const perDirectoryResolvedTypeReferenceDirectives = createMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
89100

90-
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
91-
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
92-
93101
/**
94102
* These are the extensions that failed lookup files will have by default,
95103
* any other extension of failed lookup will be store that path in custom failed lookup path
@@ -173,6 +181,7 @@ namespace ts {
173181

174182
function clearPerDirectoryResolutions() {
175183
perDirectoryResolvedModuleNames.clear();
184+
nonRelaticeModuleNameCache.clear();
176185
perDirectoryResolvedTypeReferenceDirectives.clear();
177186
}
178187

@@ -189,7 +198,7 @@ namespace ts {
189198
}
190199

191200
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
192-
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host);
201+
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache);
193202
// return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
194203
if (!resolutionHost.getGlobalCache) {
195204
return primaryResult;

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7016,9 +7016,13 @@ namespace ts.projectSystem {
70167016
return foundModule;
70177017
}
70187018

7019-
function getExpectedMissedLocationResolutionTrace(host: TestServerHost, expectedTrace: string[], dirPath: string, module: FileOrFolder, moduleName: string, useNodeModules: boolean) {
7019+
function getExpectedMissedLocationResolutionTrace(host: TestServerHost, expectedTrace: string[], dirPath: string, module: FileOrFolder, moduleName: string, useNodeModules: boolean, cacheLocation?: string) {
70207020
let foundModule = false;
70217021
forEachAncestorDirectory(dirPath, dirPath => {
7022+
if (dirPath === cacheLocation) {
7023+
return foundModule;
7024+
}
7025+
70227026
const directory = useNodeModules ? combinePaths(dirPath, nodeModules) : dirPath;
70237027
if (useNodeModules && !foundModule && !host.directoryExists(directory)) {
70247028
expectedTrace.push(`Directory '${directory}' does not exist, skipping all lookups in it.`);
@@ -7043,8 +7047,10 @@ namespace ts.projectSystem {
70437047
);
70447048
}
70457049

7046-
function getExpectedResolutionTraceFooter(expectedTrace: string[], module: FileOrFolder, moduleName: string, addRealPathTrace: boolean) {
7047-
expectedTrace.push(`File '${module.path}' exist - use it as a name resolution result.`);
7050+
function getExpectedResolutionTraceFooter(expectedTrace: string[], module: FileOrFolder, moduleName: string, addRealPathTrace: boolean, ignoreModuleFileFound?: boolean) {
7051+
if (!ignoreModuleFileFound) {
7052+
expectedTrace.push(`File '${module.path}' exist - use it as a name resolution result.`);
7053+
}
70487054
if (addRealPathTrace) {
70497055
expectedTrace.push(`Resolving real path for '${module.path}', result '${module.path}'.`);
70507056
}
@@ -7067,6 +7073,15 @@ namespace ts.projectSystem {
70677073
return expectedTrace;
70687074
}
70697075

7076+
function getExpectedNonRelativeModuleResolutionFromCacheTrace(host: TestServerHost, file: FileOrFolder, module: FileOrFolder, moduleName: string, cacheLocation: string, expectedTrace: string[] = []) {
7077+
getExpectedResolutionTraceHeader(expectedTrace, file, moduleName);
7078+
expectedTrace.push(`Loading module '${moduleName}' from 'node_modules' folder, target file type 'TypeScript'.`);
7079+
getExpectedMissedLocationResolutionTrace(host, expectedTrace, getDirectoryPath(file.path), module, moduleName, /*useNodeModules*/ true, cacheLocation);
7080+
expectedTrace.push(`Resolution for module '${moduleName}' was found in cache from location '${cacheLocation}'.`);
7081+
getExpectedResolutionTraceFooter(expectedTrace, module, moduleName, /*addRealPathTrace*/ true, /*ignoreModuleFileFound*/ true);
7082+
return expectedTrace;
7083+
}
7084+
70707085
function getExpectedReusingResolutionFromOldProgram(file: FileOrFolder, moduleName: string) {
70717086
return `Reusing resolution of module '${moduleName}' to file '${file.path}' from old program.`;
70727087
}
@@ -7223,12 +7238,12 @@ namespace ts.projectSystem {
72237238
service.openClientFile(file1.path);
72247239
const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file1, module1, module1Name);
72257240
getExpectedNonRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace);
7226-
getExpectedNonRelativeModuleResolutionTrace(host, file2, module1, module1Name, expectedTrace);
7227-
getExpectedNonRelativeModuleResolutionTrace(host, file2, module2, module2Name, expectedTrace);
7228-
getExpectedNonRelativeModuleResolutionTrace(host, file4, module1, module1Name, expectedTrace);
7229-
getExpectedNonRelativeModuleResolutionTrace(host, file4, module2, module2Name, expectedTrace);
7230-
getExpectedNonRelativeModuleResolutionTrace(host, file3, module1, module1Name, expectedTrace);
7231-
getExpectedNonRelativeModuleResolutionTrace(host, file3, module2, module2Name, expectedTrace);
7241+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module1, module1Name, getDirectoryPath(file1.path), expectedTrace);
7242+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module2, module2Name, getDirectoryPath(file1.path), expectedTrace);
7243+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module1, module1Name, `${projectLocation}/product`, expectedTrace);
7244+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module2, module2Name, `${projectLocation}/product`, expectedTrace);
7245+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module1, module1Name, getDirectoryPath(file4.path), expectedTrace);
7246+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module2, module2Name, getDirectoryPath(file4.path), expectedTrace);
72327247
verifyTrace(resolutionTrace, expectedTrace);
72337248
verifyWatchesWithConfigFile(host, files, file1);
72347249

@@ -7266,12 +7281,12 @@ namespace ts.projectSystem {
72667281
getExpectedRelativeModuleResolutionTrace(host, file1, file3, file3Name, expectedTrace);
72677282
getExpectedNonRelativeModuleResolutionTrace(host, file1, module1, module1Name, expectedTrace);
72687283
getExpectedNonRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace);
7269-
getExpectedNonRelativeModuleResolutionTrace(host, file2, module1, module1Name, expectedTrace);
7270-
getExpectedNonRelativeModuleResolutionTrace(host, file2, module2, module2Name, expectedTrace);
7271-
getExpectedNonRelativeModuleResolutionTrace(host, file4, module1, module1Name, expectedTrace);
7272-
getExpectedNonRelativeModuleResolutionTrace(host, file4, module2, module2Name, expectedTrace);
7273-
getExpectedNonRelativeModuleResolutionTrace(host, file3, module1, module1Name, expectedTrace);
7274-
getExpectedNonRelativeModuleResolutionTrace(host, file3, module2, module2Name, expectedTrace);
7284+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module1, module1Name, getDirectoryPath(file1.path), expectedTrace);
7285+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module2, module2Name, getDirectoryPath(file1.path), expectedTrace);
7286+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module1, module1Name, `${projectLocation}/product`, expectedTrace);
7287+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module2, module2Name, `${projectLocation}/product`, expectedTrace);
7288+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module1, module1Name, getDirectoryPath(file4.path), expectedTrace);
7289+
getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module2, module2Name, getDirectoryPath(file4.path), expectedTrace);
72757290
verifyTrace(resolutionTrace, expectedTrace);
72767291

72777292
const currentDirectory = getDirectoryPath(file1.path);

src/server/project.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ namespace ts.server {
210210
/*@internal*/
211211
public directoryStructureHost: DirectoryStructureHost;
212212

213+
/*@internal*/
214+
public readonly getCanonicalFileName: GetCanonicalFileName;
215+
213216
/*@internal*/
214217
constructor(
215218
/*@internal*/readonly projectName: string,
@@ -224,6 +227,7 @@ namespace ts.server {
224227
currentDirectory: string | undefined) {
225228
this.directoryStructureHost = directoryStructureHost;
226229
this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || "");
230+
this.getCanonicalFileName = this.projectService.toCanonicalFileName;
227231

228232
this.cancellationToken = new ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds);
229233
if (!this.compilerOptions) {

tests/baselines/reference/cacheResolutions.trace.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
"File '/tslib.jsx' does not exist.",
2828
"======== Module name 'tslib' was not resolved. ========",
2929
"======== Resolving module 'tslib' from '/a/b/c/lib1.ts'. ========",
30-
"Resolution for module 'tslib' was found in cache.",
30+
"Resolution for module 'tslib' was found in cache from location '/a/b/c'.",
3131
"======== Module name 'tslib' was not resolved. ========",
3232
"======== Resolving module 'tslib' from '/a/b/c/lib2.ts'. ========",
33-
"Resolution for module 'tslib' was found in cache.",
33+
"Resolution for module 'tslib' was found in cache from location '/a/b/c'.",
3434
"======== Module name 'tslib' was not resolved. ========"
3535
]

tests/baselines/reference/cachedModuleResolution1.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========",
1414
"Explicitly specified module resolution kind: 'NodeJs'.",
1515
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
16-
"Resolution for module 'foo' was found in cache.",
16+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
1717
"Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'.",
1818
"======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========"
1919
]

tests/baselines/reference/cachedModuleResolution2.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
1414
"Directory '/a/b/c/d/e/node_modules' does not exist, skipping all lookups in it.",
1515
"Directory '/a/b/c/d/node_modules' does not exist, skipping all lookups in it.",
16-
"Resolution for module 'foo' was found in cache.",
16+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
1717
"Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'.",
1818
"======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========"
1919
]

tests/baselines/reference/cachedModuleResolution3.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
"======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========",
1717
"======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========",
1818
"Explicitly specified module resolution kind: 'Classic'.",
19-
"Resolution for module 'foo' was found in cache.",
19+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
2020
"======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========"
2121
]

tests/baselines/reference/cachedModuleResolution4.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
"File '/a/b/c/d/foo.ts' does not exist.",
1717
"File '/a/b/c/d/foo.tsx' does not exist.",
1818
"File '/a/b/c/d/foo.d.ts' does not exist.",
19-
"Resolution for module 'foo' was found in cache.",
19+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
2020
"======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========"
2121
]

tests/baselines/reference/cachedModuleResolution5.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"======== Resolving module 'foo' from '/a/b/lib.ts'. ========",
1414
"Explicitly specified module resolution kind: 'NodeJs'.",
1515
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
16-
"Resolution for module 'foo' was found in cache.",
16+
"Resolution for module 'foo' was found in cache from location '/a/b'.",
1717
"Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'.",
1818
"======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========"
1919
]

tests/baselines/reference/cachedModuleResolution6.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
"======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========",
2020
"Explicitly specified module resolution kind: 'NodeJs'.",
2121
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
22-
"Resolution for module 'foo' was found in cache.",
22+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
2323
"======== Module name 'foo' was not resolved. ========"
2424
]

tests/baselines/reference/cachedModuleResolution7.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
"Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.",
1818
"Directory '/a/b/c/d/e/node_modules' does not exist, skipping all lookups in it.",
1919
"Directory '/a/b/c/d/node_modules' does not exist, skipping all lookups in it.",
20-
"Resolution for module 'foo' was found in cache.",
20+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
2121
"======== Module name 'foo' was not resolved. ========"
2222
]

tests/baselines/reference/cachedModuleResolution8.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@
4040
"======== Module name 'foo' was not resolved. ========",
4141
"======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========",
4242
"Explicitly specified module resolution kind: 'Classic'.",
43-
"Resolution for module 'foo' was found in cache.",
43+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
4444
"======== Module name 'foo' was not resolved. ========"
4545
]

tests/baselines/reference/cachedModuleResolution9.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@
3434
"File '/a/b/c/d/foo.ts' does not exist.",
3535
"File '/a/b/c/d/foo.tsx' does not exist.",
3636
"File '/a/b/c/d/foo.d.ts' does not exist.",
37-
"Resolution for module 'foo' was found in cache.",
37+
"Resolution for module 'foo' was found in cache from location '/a/b/c'.",
3838
"======== Module name 'foo' was not resolved. ========"
3939
]

tests/baselines/reference/typeReferenceDirectives12.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"Resolving real path for '/types/lib/index.d.ts', result '/types/lib/index.d.ts'.",
1717
"======== Type reference directive 'lib' was successfully resolved to '/types/lib/index.d.ts', primary: true. ========",
1818
"======== Resolving module './main' from '/mod1.ts'. ========",
19-
"Resolution for module './main' was found in cache.",
19+
"Resolution for module './main' was found in cache from location '/'.",
2020
"======== Module name './main' was successfully resolved to '/main.ts'. ========",
2121
"======== Resolving type reference directive 'lib', containing file '/__inferred type names__.ts', root directory '/types'. ========",
2222
"Resolving with primary search path '/types'.",

tests/baselines/reference/typeReferenceDirectives9.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"Resolving real path for '/types/lib/index.d.ts', result '/types/lib/index.d.ts'.",
1717
"======== Type reference directive 'lib' was successfully resolved to '/types/lib/index.d.ts', primary: true. ========",
1818
"======== Resolving module './main' from '/mod1.ts'. ========",
19-
"Resolution for module './main' was found in cache.",
19+
"Resolution for module './main' was found in cache from location '/'.",
2020
"======== Module name './main' was successfully resolved to '/main.ts'. ========",
2121
"======== Resolving type reference directive 'lib', containing file '/__inferred type names__.ts', root directory '/types'. ========",
2222
"Resolving with primary search path '/types'.",

0 commit comments

Comments
 (0)