Skip to content

Commit 0acc400

Browse files
committed
WIP, needs test
1 parent 4fdc4fd commit 0acc400

File tree

7 files changed

+33
-27
lines changed

7 files changed

+33
-27
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,9 @@ namespace ts {
297297
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
298298
* is assumed to be the same as root directory of the project.
299299
*/
300-
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache, resolutionMode?: SourceFile["impliedNodeFormat"]): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
301-
Debug.assert(typeof typeReferenceDirectiveName === "string", "Non-string value passed to `ts.resolveTypeReferenceDirective`, likely by a wrapping package working with an outdated `resolveTypeReferenceDirectives` signature. This is probably not a problem in TS itself.");
300+
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string | FileReference, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache, resolutionMode?: SourceFile["impliedNodeFormat"]): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
301+
resolutionMode = typeof typeReferenceDirectiveName !== "string" && typeReferenceDirectiveName.resolutionMode || resolutionMode;
302+
typeReferenceDirectiveName = typeof typeReferenceDirectiveName !== "string" ? typeReferenceDirectiveName.fileName : typeReferenceDirectiveName;
302303
const traceEnabled = isTraceEnabled(options, host);
303304
if (redirectedReference) {
304305
options = redirectedReference.commandLine.options;
@@ -397,7 +398,7 @@ namespace ts {
397398
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
398399
}
399400
return firstDefined(typeRoots, typeRoot => {
400-
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
401+
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName as string);
401402
const candidateDirectory = getDirectoryPath(candidate);
402403
const directoryExists = directoryProbablyExists(candidateDirectory, host);
403404
if (!directoryExists && traceEnabled) {
@@ -424,12 +425,12 @@ namespace ts {
424425
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
425426
}
426427
let result: Resolved | undefined;
427-
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
428-
const searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
428+
if (!isExternalModuleNameRelative(typeReferenceDirectiveName as string)) {
429+
const searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName as string, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
429430
result = searchResult && searchResult.value;
430431
}
431432
else {
432-
const { path: candidate } = normalizePathForCJSResolution(initialLocationForSecondaryLookup, typeReferenceDirectiveName);
433+
const { path: candidate } = normalizePathForCJSResolution(initialLocationForSecondaryLookup, typeReferenceDirectiveName as string);
433434
result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
434435
}
435436
return resolvedTypeScriptOnly(result);
@@ -922,7 +923,9 @@ namespace ts {
922923
return perFolderCache.get(moduleName, mode);
923924
}
924925

925-
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations {
926+
export function resolveModuleName(moduleName: string | FileReference, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations {
927+
resolutionMode = typeof moduleName !== "string" && moduleName.resolutionMode || resolutionMode;
928+
moduleName = typeof moduleName !== "string" ? moduleName.fileName : moduleName;
926929
const traceEnabled = isTraceEnabled(compilerOptions, host);
927930
if (redirectedReference) {
928931
compilerOptions = redirectedReference.commandLine.options;

src/compiler/program.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -614,16 +614,17 @@ namespace ts {
614614
}
615615

616616
/* @internal */
617-
export function loadWithModeAwareCache<T>(names: string[], containingFile: SourceFile, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
617+
export function loadWithModeAwareCache<T>(names: string[] | readonly FileReference[], containingFile: SourceFile, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
618618
if (names.length === 0) {
619619
return [];
620620
}
621621
const resolutions: T[] = [];
622622
const cache = new Map<string, T>();
623623
let i = 0;
624-
for (const name of names) {
624+
for (let name of names) {
625625
let result: T;
626-
const mode = getModeForResolutionAtIndex(containingFile, i);
626+
const mode = typeof name !== "string" ? name.resolutionMode : getModeForResolutionAtIndex(containingFile, i);
627+
name = typeof name !== "string" ? name.fileName : name;
627628
i++;
628629
const cacheKey = mode !== undefined ? `${mode}|${name}` : name;
629630
if (cache.has(cacheKey)) {
@@ -1072,7 +1073,7 @@ namespace ts {
10721073

10731074
let moduleResolutionCache: ModuleResolutionCache | undefined;
10741075
let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
1075-
let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: SourceFile, containingFileName: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
1076+
let actualResolveModuleNamesWorker: (moduleNames: string[] | readonly FileReference[], containingFile: SourceFile, containingFileName: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
10761077
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
10771078
if (host.resolveModuleNames) {
10781079
actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.checkEachDefined(moduleNames), containingFileName, reusedNames, redirectedReference, options, containingFile).map(resolved => {
@@ -1364,7 +1365,7 @@ namespace ts {
13641365

13651366
return program;
13661367

1367-
function resolveModuleNamesWorker(moduleNames: string[], containingFile: SourceFile, reusedNames: string[] | undefined): readonly ResolvedModuleFull[] {
1368+
function resolveModuleNamesWorker(moduleNames: string[] | readonly FileReference[], containingFile: SourceFile, reusedNames: string[] | undefined): readonly ResolvedModuleFull[] {
13681369
if (!moduleNames.length) return emptyArray;
13691370
const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
13701371
const redirectedReference = getRedirectReferenceForResolution(containingFile);
@@ -1505,6 +1506,7 @@ namespace ts {
15051506

15061507
/** An ordered list of module names for which we cannot recover the resolution. */
15071508
let unknownModuleNames: string[] | undefined;
1509+
let unknownModuleModes: (SourceFile["impliedNodeFormat"])[] | undefined;
15081510
/**
15091511
* The indexing of elements in this list matches that of `moduleNames`.
15101512
*
@@ -1562,11 +1564,12 @@ namespace ts {
15621564
else {
15631565
// Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
15641566
(unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
1567+
(unknownModuleModes ||= []).push(getModeForResolutionAtIndex(file, i));
15651568
}
15661569
}
15671570

15681571
const resolutions = unknownModuleNames && unknownModuleNames.length
1569-
? resolveModuleNamesWorker(unknownModuleNames, file, reusedNames)
1572+
? resolveModuleNamesWorker(unknownModuleNames.map<FileReference>((n, i) => ({fileName: n, pos: -1, end: -1, resolutionMode: unknownModuleModes![i]})), file, reusedNames)
15701573
: emptyArray;
15711574

15721575
// Combine results of resolutions and predicted results

src/compiler/resolutionCache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace ts {
55
startRecordingFilesWithChangedResolutions(): void;
66
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
77

8-
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[];
8+
resolveModuleNames(moduleNames: string[] | readonly FileReference[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[];
99
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined;
1010
resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[];
1111

@@ -393,7 +393,7 @@ namespace ts {
393393
const seenNamesInFile = createModeAwareCache<true>();
394394
let i = 0;
395395
for (const entry of names) {
396-
const name = isString(entry) ? entry : entry.fileName.toLowerCase();
396+
const name = isString(entry) ? entry : entry.fileName;
397397
// Imports supply a `containingSourceFile` but no `containingSourceFileMode` - it would be redundant
398398
// they require calculating the mode for a given import from it's position in the resolution table, since a given
399399
// import's syntax may override the file's default mode.
@@ -515,7 +515,7 @@ namespace ts {
515515

516516
function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[] {
517517
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>({
518-
names: typeDirectiveNames,
518+
names: typeDirectiveNames.map(n => typeof n === "string" ? n.toLowerCase() : ({ ...n, fileName: n.fileName.toLowerCase() } as FileReference)) as string[] | FileReference[],
519519
containingFile,
520520
redirectedReference,
521521
cache: resolvedTypeReferenceDirectives,
@@ -527,7 +527,7 @@ namespace ts {
527527
});
528528
}
529529

530-
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[] {
530+
function resolveModuleNames(moduleNames: string[] | readonly FileReference[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[] {
531531
return resolveNamesWithLocalCache<CachedResolvedModuleWithFailedLookupLocations, ResolvedModuleFull>({
532532
names: moduleNames,
533533
containingFile,

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6742,7 +6742,7 @@ namespace ts {
67426742
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
67436743
* 'throw new Error("NotImplemented")'
67446744
*/
6745-
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[];
6745+
resolveModuleNames?(moduleNames: string[] | readonly FileReference[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[];
67466746
/**
67476747
* Returns the module resolution cache used by a provided `resolveModuleNames` implementation so that any non-name module resolution operations (eg, package.json lookup) can reuse it
67486748
*/

src/compiler/watchPublic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ namespace ts {
101101
getEnvironmentVariable?(name: string): string | undefined;
102102

103103
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
104-
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[];
104+
resolveModuleNames?(moduleNames: string[] | readonly FileReference[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[];
105105
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
106106
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined): (ResolvedTypeReferenceDirective | undefined)[];
107107
}

0 commit comments

Comments
 (0)