Skip to content

Commit

Permalink
Add more tracing to node16/nodenext resolution (#51168)
Browse files Browse the repository at this point in the history
* Add more tracing to node16/nodenext resolution

* Update baselines after diagnostic change

* Trace non-matching conditions
  • Loading branch information
andrewbranch authored Oct 14, 2022
1 parent 83c5581 commit f6cf510
Show file tree
Hide file tree
Showing 21 changed files with 1,789 additions and 638 deletions.
16 changes: 16 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5414,6 +5414,22 @@
"category": "Message",
"code": 6401
},
"Resolving in {0} mode with conditions {1}.": {
"category": "Message",
"code": 6402
},
"Matched '{0}' condition '{1}'.": {
"category": "Message",
"code": 6403
},
"Using '{0}' subpath '{1}' with target '{2}'.": {
"category": "Message",
"code": 6404
},
"Saw non-matching condition '{0}'.": {
"category": "Message",
"code": 6405
},

"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
Expand Down
46 changes: 35 additions & 11 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,10 @@ namespace ts {
reportDiagnostic: diag => void diagnostics.push(diag),
};

if (traceEnabled && getEmitModuleResolutionKind(compilerOptions) >= ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) <= ModuleResolutionKind.NodeNext) {
trace(host, Diagnostics.Resolving_in_0_mode_with_conditions_1, features & NodeResolutionFeatures.EsmMode ? "ESM" : "CJS", conditions.map(c => `'${c}'`).join(", "));
}

const result = forEach(extensions, ext => tryResolve(ext));
return createResolvedModuleWithFailedLookupLocations(
result?.value?.resolved,
Expand Down Expand Up @@ -2032,7 +2036,7 @@ namespace ts {
}
if (mainExport) {
const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, subpath, scope, /*isImports*/ false);
return loadModuleFromTargetImportOrExport(mainExport, "", /*pattern*/ false);
return loadModuleFromTargetImportOrExport(mainExport, "", /*pattern*/ false, ".");
}
}
else if (allKeysStartWithDot(scope.contents.packageJsonContent.exports as MapLike<unknown>)) {
Expand Down Expand Up @@ -2111,25 +2115,25 @@ namespace ts {

if (!endsWith(moduleName, directorySeparator) && moduleName.indexOf("*") === -1 && hasProperty(lookupTable, moduleName)) {
const target = (lookupTable as {[idx: string]: unknown})[moduleName];
return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false);
return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false, moduleName);
}
const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike<unknown>), k => k.indexOf("*") !== -1 || endsWith(k, "/")), comparePatternKeys);
for (const potentialTarget of expandingKeys) {
if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) {
const target = (lookupTable as {[idx: string]: unknown})[potentialTarget];
const starPos = potentialTarget.indexOf("*");
const subpath = moduleName.substring(potentialTarget.substring(0, starPos).length, moduleName.length - (potentialTarget.length - 1 - starPos));
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true);
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true, potentialTarget);
}
else if (endsWith(potentialTarget, "*") && startsWith(moduleName, potentialTarget.substring(0, potentialTarget.length - 1))) {
const target = (lookupTable as {[idx: string]: unknown})[potentialTarget];
const subpath = moduleName.substring(potentialTarget.length - 1);
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true);
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true, potentialTarget);
}
else if (startsWith(moduleName, potentialTarget)) {
const target = (lookupTable as {[idx: string]: unknown})[potentialTarget];
const subpath = moduleName.substring(potentialTarget.length);
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ false);
return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ false, potentialTarget);
}
}

Expand All @@ -2146,7 +2150,7 @@ namespace ts {
*/
function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, scope: PackageJsonInfo, isImports: boolean) {
return loadModuleFromTargetImportOrExport;
function loadModuleFromTargetImportOrExport(target: unknown, subpath: string, pattern: boolean): SearchResult<Resolved> | undefined {
function loadModuleFromTargetImportOrExport(target: unknown, subpath: string, pattern: boolean, key: string): SearchResult<Resolved> | undefined {
if (typeof target === "string") {
if (!pattern && subpath.length > 0 && !endsWith(target, "/")) {
if (state.traceEnabled) {
Expand All @@ -2157,6 +2161,8 @@ namespace ts {
if (!startsWith(target, "./")) {
if (isImports && !startsWith(target, "../") && !startsWith(target, "/") && !isRootedDiskPath(target)) {
const combinedLookup = pattern ? target.replace(/\*/g, subpath) : target + subpath;
traceIfEnabled(state, Diagnostics.Using_0_subpath_1_with_target_2, "imports", key, combinedLookup);
traceIfEnabled(state, Diagnostics.Resolving_module_0_from_1, combinedLookup, scope.packageDirectory + "/");
const result = nodeModuleNameResolverWorker(state.features, combinedLookup, scope.packageDirectory + "/", state.compilerOptions, state.host, cache, [extensions], redirectedReference);
return toSearchResult(result.resolvedModule ? { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId, originalPath: result.resolvedModule.originalPath } : undefined);
}
Expand All @@ -2183,21 +2189,33 @@ namespace ts {
}
return toSearchResult(/*value*/ undefined);
}

if (state.traceEnabled) {
trace(state.host,
Diagnostics.Using_0_subpath_1_with_target_2,
isImports ? "imports" : "exports",
key,
pattern ? target.replace(/\*/g, subpath) : target + subpath);
}
const finalPath = toAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath);
const inputLink = tryLoadInputFileForPath(finalPath, subpath, combinePaths(scope.packageDirectory, "package.json"), isImports);
if (inputLink) return inputLink;
return toSearchResult(withPackageId(scope, loadJSOrExactTSFileName(extensions, finalPath, /*onlyRecordFailures*/ false, state)));
}
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null
if (!Array.isArray(target)) {
for (const key of getOwnKeys(target as MapLike<unknown>)) {
if (key === "default" || state.conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(state.conditions, key)) {
const subTarget = (target as MapLike<unknown>)[key];
const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern);
for (const condition of getOwnKeys(target as MapLike<unknown>)) {
if (condition === "default" || state.conditions.indexOf(condition) >= 0 || isApplicableVersionedTypesKey(state.conditions, condition)) {
traceIfEnabled(state, Diagnostics.Matched_0_condition_1, isImports ? "imports" : "exports", condition);
const subTarget = (target as MapLike<unknown>)[condition];
const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern, key);
if (result) {
return result;
}
}
else {
traceIfEnabled(state, Diagnostics.Saw_non_matching_condition_0, condition);
}
}
return undefined;
}
Expand All @@ -2209,7 +2227,7 @@ namespace ts {
return toSearchResult(/*value*/ undefined);
}
for (const elem of target) {
const result = loadModuleFromTargetImportOrExport(elem, subpath, pattern);
const result = loadModuleFromTargetImportOrExport(elem, subpath, pattern, key);
if (result) {
return result;
}
Expand Down Expand Up @@ -2685,4 +2703,10 @@ namespace ts {
function toSearchResult<T>(value: T | undefined): SearchResult<T> {
return value !== undefined ? { value } : undefined;
}

function traceIfEnabled(state: ModuleResolutionState, diagnostic: DiagnosticMessage, ...args: string[]) {
if (state.traceEnabled) {
trace(state.host, diagnostic, ...args);
}
}
}
Loading

0 comments on commit f6cf510

Please # to comment.