Skip to content

Commit 2fb03db

Browse files
committed
[WIP] added verbose diagnostics when resolving modules
1 parent c64d739 commit 2fb03db

File tree

3 files changed

+163
-39
lines changed

3 files changed

+163
-39
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,7 @@
23532353
"category": "Message",
23542354
"code": 6084
23552355
},
2356-
"Resolving module '{0}' from '{1}'.": {
2356+
"=== Resolving module '{0}' from '{1}'.": {
23572357
"category": "Message",
23582358
"code": 6085
23592359
},
@@ -2365,14 +2365,90 @@
23652365
"category": "Message",
23662366
"code": 6087
23672367
},
2368-
"Module name '{0}' was successfully resolved to '{1}'.": {
2368+
"=== Module name '{0}' was successfully resolved to '{1}'.": {
23692369
"category": "Message",
23702370
"code": 6088
23712371
},
2372-
"Module name '{0}' was not resolved.": {
2372+
"=== Module name '{0}' was not resolved.": {
23732373
"category": "Message",
23742374
"code": 6089
23752375
},
2376+
"Resolving rooted module name '{0}' - use it as a candidate location.": {
2377+
"category": "Message",
2378+
"code": 6090
2379+
},
2380+
"Resolving relative module name '{0}'.": {
2381+
"category": "Message",
2382+
"code": 6091
2383+
},
2384+
"Resolving non-relative module name '{0}'.": {
2385+
"category": "Message",
2386+
"code": 6092
2387+
},
2388+
"Converting relative module name '{0}' to absolute using '{1}' as a base directory => '{2}'.": {
2389+
"category": "Message",
2390+
"code": 6093
2391+
},
2392+
"'rootDirs' option is specified, searching for a longest matching prefix...": {
2393+
"category": "Message",
2394+
"code": 6094
2395+
},
2396+
"Found longest matching rootDir '{0}', 'converted relative path '{1}', to non-relative path '{2}'": {
2397+
"category": "Message",
2398+
"code": 6095
2399+
},
2400+
"'rootDirs' option is not specified, using '{0}' as candidate location.": {
2401+
"category": "Message",
2402+
"code": 6096
2403+
},
2404+
"'paths' option is specified, looking for a pattern to match module name '{0}'.": {
2405+
"category": "Message",
2406+
"code": 6097
2407+
},
2408+
"Module name '{0}', matched pattern '{1}'.": {
2409+
"category": "Message",
2410+
"code": 6098
2411+
},
2412+
"Trying substitution '{0}', candidate module location: '{1}'.": {
2413+
"category": "Message",
2414+
"code": 6099
2415+
},
2416+
"Resolving module name '{0}' relative to base url '{1}' - '{2}'.": {
2417+
"category": "Message",
2418+
"code": 6100
2419+
},
2420+
"Loading module '{0}' as file / folder, candidate module location '{1}'.": {
2421+
"category": "Message",
2422+
"code": 6101
2423+
},
2424+
"File '{0}' does not exist.": {
2425+
"category": "Message",
2426+
"code": 6102
2427+
},
2428+
"File '{0}' exist - use it as a module resolution result.": {
2429+
"category": "Message",
2430+
"code": 6103
2431+
},
2432+
"Loading module '{0}' from 'node_modules' folder.": {
2433+
"category": "Message",
2434+
"code": 6104
2435+
},
2436+
"Found 'package.json' at '{0}'.": {
2437+
"category": "Message",
2438+
"code": 6105
2439+
},
2440+
"'package.json' does not have 'typings' field.": {
2441+
"category": "Message",
2442+
"code": 6106
2443+
},
2444+
"'package.json' has 'typings' field '{0}' that references '{1}'.": {
2445+
"category": "Message",
2446+
"code": 6107
2447+
},
2448+
"Module name '{0}' contains '!' character.": {
2449+
"category": "Message",
2450+
"code": 6108
2451+
},
23762452
"Variable '{0}' implicitly has an '{1}' type.": {
23772453
"category": "Error",
23782454
"code": 7005

src/compiler/program.ts

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,25 @@ namespace ts {
3838

3939
function trace(message: DiagnosticMessage, ...args: any[]): void;
4040
function trace(message: DiagnosticMessage): void {
41-
// this will be bound to the trace method on the host
42-
this.trace(createCompilerDiagnostic.apply(undefined, arguments));
41+
// 'this' will be bound to the trace method on the host
42+
this.trace((<Diagnostic>createCompilerDiagnostic.apply(undefined, arguments)).messageText);
4343
}
4444

4545
function noTrace(message: DiagnosticMessage, ...args: any[]): void;
4646
function noTrace(message: DiagnosticMessage): void {
4747
}
4848

49-
type Trace = typeof trace;
49+
type ModuleResolutionTracer = typeof trace;
5050

51-
function getTrace(compilerOptions: CompilerOptions, host: ModuleResolutionHost): Trace {
51+
function getTrace(compilerOptions: CompilerOptions, host: ModuleResolutionHost): ModuleResolutionTracer {
5252
return compilerOptions.traceModuleResolution && host.trace ? trace.bind(host) : noTrace;
5353
}
5454

5555
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
5656
const traceWorker = getTrace(compilerOptions, host);
57-
57+
5858
traceWorker(Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
59-
59+
6060
let moduleResolution = compilerOptions.moduleResolution;
6161
if (moduleResolution === undefined) {
6262
if (compilerOptions.module === ModuleKind.CommonJS) {
@@ -76,13 +76,13 @@ namespace ts {
7676

7777
let result: ResolvedModuleWithFailedLookupLocations;
7878
switch (moduleResolution) {
79-
case ModuleResolutionKind.NodeJs:
80-
result = nodeModuleNameResolver(moduleName, containingFile, host);
79+
case ModuleResolutionKind.NodeJs:
80+
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host);
8181
break;
82-
case ModuleResolutionKind.Classic:
82+
case ModuleResolutionKind.Classic:
8383
result = classicNameResolver(moduleName, containingFile, compilerOptions, host);
8484
break;
85-
case ModuleResolutionKind.BaseUrl:
85+
case ModuleResolutionKind.BaseUrl:
8686
result = baseUrlModuleNameResolver(moduleName, containingFile, compilerOptions, host);
8787
break;
8888
}
@@ -177,8 +177,10 @@ namespace ts {
177177
const traceWorker = getTrace(options, host);
178178

179179
if (isRootedDiskPath(moduleName)) {
180-
let failedLookupLocations: string[] = [];
181-
const resolvedFileName = loadModuleFromFile(supportedExtensions, moduleName, failedLookupLocations, host);
180+
traceWorker(Diagnostics.Resolving_rooted_module_name_0_use_it_as_a_candidate_location, moduleName);
181+
182+
const failedLookupLocations: string[] = [];
183+
const resolvedFileName = loadModuleFromFile(supportedExtensions, moduleName, failedLookupLocations, host, traceWorker);
182184
return {
183185
resolvedModule: resolvedFileName ? { resolvedFileName } : undefined,
184186
failedLookupLocations
@@ -187,21 +189,27 @@ namespace ts {
187189

188190
if (nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
189191
// relative name
192+
traceWorker(Diagnostics.Resolving_relative_module_name_0, moduleName);
190193
return baseUrlResolveRelativeModuleName(moduleName, containingFile, baseUrl, options, host, traceWorker);
191194
}
192195
else {
193196
// non-relative name
194-
return baseUrlResolveNonRelativeModuleName(moduleName, baseUrl, options, host);
197+
traceWorker(Diagnostics.Resolving_non_relative_module_name_0, moduleName);
198+
return baseUrlResolveNonRelativeModuleName(moduleName, baseUrl, options, host, traceWorker);
195199
}
196200
}
197201

198-
function baseUrlResolveRelativeModuleName(moduleName: string, containingFile: string, baseUrl: string, options: CompilerOptions, host: ModuleResolutionHost, traceWorker: Trace): ResolvedModuleWithFailedLookupLocations {
202+
function baseUrlResolveRelativeModuleName(moduleName: string, containingFile: string, baseUrl: string, options: CompilerOptions, host: ModuleResolutionHost, traceWorker: ModuleResolutionTracer): ResolvedModuleWithFailedLookupLocations {
199203
const failedLookupLocations: string[] = [];
200204

201205
const containingDirectory = getDirectoryPath(containingFile);
202206
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
203207

208+
traceWorker(Diagnostics.Converting_relative_module_name_0_to_absolute_using_1_as_a_base_directory_2, moduleName, containingDirectory, candidate);
209+
204210
if (options.rootDirs) {
211+
traceWorker(Diagnostics.rootDirs_option_is_specified_searching_for_a_longest_matching_prefix);
212+
205213
let matchedPrefix: string;
206214
for (const rootDir of options.rootDirs) {
207215
let normalizedRoot = getNormalizedAbsolutePath(rootDir, baseUrl);
@@ -214,26 +222,32 @@ namespace ts {
214222
}
215223
if (matchedPrefix) {
216224
const suffix = candidate.substr(matchedPrefix.length);
217-
return baseUrlResolveNonRelativeModuleName(suffix, baseUrl, options, host);
225+
traceWorker(Diagnostics.Found_longest_matching_rootDir_0_converted_relative_path_1_to_non_relative_path_2, matchedPrefix, moduleName, suffix);
226+
227+
return baseUrlResolveNonRelativeModuleName(suffix, baseUrl, options, host, traceWorker);
218228
}
219229
return { resolvedModule: undefined, failedLookupLocations };
220230
}
221231
else {
222-
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
232+
traceWorker(Diagnostics.rootDirs_option_is_not_specified_using_0_as_candidate_location, candidate);
233+
234+
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host, traceWorker);
223235
return {
224236
resolvedModule: resolvedFileName ? { resolvedFileName } : undefined,
225237
failedLookupLocations
226238
};
227239
}
228240
}
229241

230-
function baseUrlResolveNonRelativeModuleName(moduleName: string, baseUrl: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
242+
function baseUrlResolveNonRelativeModuleName(moduleName: string, baseUrl: string, options: CompilerOptions, host: ModuleResolutionHost, traceWorker: ModuleResolutionTracer): ResolvedModuleWithFailedLookupLocations {
231243
let longestMatchPrefixLength = -1;
232244
let matchedPattern: string;
233245
let matchedStar: string;
234246

235247
const failedLookupLocations: string[] = [];
236248
if (options.paths) {
249+
traceWorker(Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
250+
237251
for (const key in options.paths) {
238252
const pattern: string = key;
239253
const indexOfStar = pattern.indexOf("*");
@@ -262,10 +276,15 @@ namespace ts {
262276
}
263277

264278
if (matchedPattern) {
279+
traceWorker(Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPattern);
280+
265281
for (const subst of options.paths[matchedPattern]) {
266282
const path = matchedStar ? subst.replace("\*", matchedStar) : subst;
267283
const candidate = normalizePath(combinePaths(baseUrl, path));
268-
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
284+
285+
traceWorker(Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
286+
287+
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host, traceWorker);
269288
if (resolvedFileName) {
270289
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
271290
}
@@ -275,7 +294,10 @@ namespace ts {
275294
}
276295
else {
277296
const candidate = normalizePath(combinePaths(baseUrl, moduleName));
278-
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
297+
298+
traceWorker(Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
299+
300+
const resolvedFileName = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host, traceWorker);
279301
return {
280302
resolvedModule: resolvedFileName ? { resolvedFileName } : undefined,
281303
failedLookupLocations
@@ -292,46 +314,57 @@ namespace ts {
292314
return str.indexOf(suffix, expectedPos) === expectedPos;
293315
}
294316

295-
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
317+
export function nodeModuleNameResolver(moduleName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
296318
const containingDirectory = getDirectoryPath(containingFile);
297319

320+
const traceWorker = getTrace(options, host);
321+
298322
if (isRootedDiskPath(moduleName) || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
299323
const failedLookupLocations: string[] = [];
300324
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
301-
let resolvedFileName = loadModuleFromFile(supportedJsExtensions, candidate, failedLookupLocations, host);
325+
326+
traceWorker(Diagnostics.Loading_module_0_as_file_Slash_folder_candidate_module_location_1, moduleName, candidate);
327+
328+
let resolvedFileName = loadModuleFromFile(supportedJsExtensions, candidate, failedLookupLocations, host, traceWorker);
302329

303330
if (resolvedFileName) {
304331
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
305332
}
306333

307-
resolvedFileName = loadNodeModuleFromDirectory(supportedJsExtensions, candidate, failedLookupLocations, host);
334+
resolvedFileName = loadNodeModuleFromDirectory(supportedJsExtensions, candidate, failedLookupLocations, host, traceWorker);
308335
return resolvedFileName
309336
? { resolvedModule: { resolvedFileName }, failedLookupLocations }
310337
: { resolvedModule: undefined, failedLookupLocations };
311338
}
312339
else {
313-
return loadModuleFromNodeModules(moduleName, containingDirectory, host);
340+
traceWorker(Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
341+
342+
return loadModuleFromNodeModules(moduleName, containingDirectory, host, traceWorker);
314343
}
315344
}
316345

317-
function loadModuleFromFile(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
346+
function loadModuleFromFile(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost, traceWorker: ModuleResolutionTracer): string {
318347
return forEach(extensions, tryLoad);
319348

320349
function tryLoad(ext: string): string {
321350
const fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
351+
322352
if (host.fileExists(fileName)) {
353+
traceWorker(Diagnostics.File_0_exist_use_it_as_a_module_resolution_result, fileName);
323354
return fileName;
324355
}
325356
else {
357+
traceWorker(Diagnostics.File_0_does_not_exist, fileName);
326358
failedLookupLocation.push(fileName);
327359
return undefined;
328360
}
329361
}
330362
}
331363

332-
function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost): string {
364+
function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], host: ModuleResolutionHost, traceWorker: ModuleResolutionTracer): string {
333365
const packageJsonPath = combinePaths(candidate, "package.json");
334366
if (host.fileExists(packageJsonPath)) {
367+
traceWorker(Diagnostics.Found_package_json_at_0, packageJsonPath);
335368

336369
let jsonContent: { typings?: string };
337370

@@ -345,34 +378,40 @@ namespace ts {
345378
}
346379

347380
if (jsonContent.typings) {
348-
const result = loadModuleFromFile(extensions, normalizePath(combinePaths(candidate, jsonContent.typings)), failedLookupLocation, host);
381+
const typingsFile = normalizePath(combinePaths(candidate, jsonContent.typings));
382+
traceWorker(Diagnostics.package_json_has_typings_field_0_that_references_1, jsonContent.typings, typingsFile);
383+
const result = loadModuleFromFile(extensions, typingsFile , failedLookupLocation, host, traceWorker);
349384
if (result) {
350385
return result;
351386
}
352387
}
388+
else {
389+
traceWorker(Diagnostics.package_json_does_not_have_typings_field);
390+
}
353391
}
354392
else {
393+
traceWorker(Diagnostics.package_json_does_not_have_typings_field);
355394
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
356395
failedLookupLocation.push(packageJsonPath);
357396
}
358397

359-
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, host);
398+
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, host, traceWorker);
360399
}
361400

362-
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
401+
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost, traceWorker: ModuleResolutionTracer): ResolvedModuleWithFailedLookupLocations {
363402
const failedLookupLocations: string[] = [];
364403
directory = normalizeSlashes(directory);
365404
while (true) {
366405
const baseName = getBaseFileName(directory);
367406
if (baseName !== "node_modules") {
368407
const nodeModulesFolder = combinePaths(directory, "node_modules");
369408
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
370-
let result = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host);
409+
let result = loadModuleFromFile(supportedExtensions, candidate, failedLookupLocations, host, traceWorker);
371410
if (result) {
372411
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
373412
}
374413

375-
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host);
414+
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, host, traceWorker);
376415
if (result) {
377416
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
378417
}
@@ -412,8 +451,11 @@ namespace ts {
412451

413452
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
414453

454+
const traceWorker = getTrace(compilerOptions, host);
455+
415456
// module names that contain '!' are used to reference resources and are not resolved to actual files on disk
416457
if (moduleName.indexOf("!") != -1) {
458+
traceWorker(Diagnostics.Module_name_0_contains_character, moduleName);
417459
return { resolvedModule: undefined, failedLookupLocations: [] };
418460
}
419461

@@ -435,9 +477,11 @@ namespace ts {
435477

436478
const candidate = searchName + extension;
437479
if (host.fileExists(candidate)) {
480+
traceWorker(Diagnostics.File_0_exist_use_it_as_a_module_resolution_result, candidate);
438481
return candidate;
439482
}
440483
else {
484+
traceWorker(Diagnostics.File_0_does_not_exist, candidate);
441485
failedLookupLocations.push(candidate);
442486
}
443487
});

0 commit comments

Comments
 (0)