Skip to content

Commit 0e4b10d

Browse files
committed
Use resolution options of project reference if the file is from the project reference
1 parent 0ac9658 commit 0e4b10d

File tree

11 files changed

+97
-57
lines changed

11 files changed

+97
-57
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3763,6 +3763,10 @@
37633763
"category": "Message",
37643764
"code": 6214
37653765
},
3766+
"Using compiler options of project reference redirect '{0}'.": {
3767+
"category": "Message",
3768+
"code": 6215
3769+
},
37663770

37673771
"Projects to reference": {
37683772
"category": "Message",
@@ -4684,4 +4688,4 @@
46844688
"category": "Message",
46854689
"code": 95068
46864690
}
4687-
}
4691+
}

src/compiler/moduleNameResolver.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,11 @@ namespace ts {
258258
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
259259
* is assumed to be the same as root directory of the project.
260260
*/
261-
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
261+
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
262262
const traceEnabled = isTraceEnabled(options, host);
263+
if (redirectedReference) {
264+
options = redirectedReference.commandLine.options;
265+
}
263266
const failedLookupLocations: string[] = [];
264267
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations };
265268

@@ -281,6 +284,9 @@ namespace ts {
281284
trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
282285
}
283286
}
287+
if (redirectedReference) {
288+
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
289+
}
284290
}
285291

286292
let resolved = primaryLookup();
@@ -542,10 +548,16 @@ namespace ts {
542548
return perFolderCache && perFolderCache.get(moduleName);
543549
}
544550

545-
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
551+
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
546552
const traceEnabled = isTraceEnabled(compilerOptions, host);
553+
if (redirectedReference) {
554+
compilerOptions = redirectedReference.commandLine.options;
555+
}
547556
if (traceEnabled) {
548557
trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
558+
if (redirectedReference) {
559+
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
560+
}
549561
}
550562
const containingDirectory = getDirectoryPath(containingFile);
551563
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);

src/compiler/program.ts

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ namespace ts {
406406
}
407407
}
408408

409-
function loadWithLocalCache<T>(names: string[], containingFile: string, loader: (name: string, containingFile: string) => T): T[] {
409+
function loadWithLocalCache<T>(names: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
410410
if (names.length === 0) {
411411
return [];
412412
}
@@ -418,7 +418,7 @@ namespace ts {
418418
result = cache.get(name)!;
419419
}
420420
else {
421-
cache.set(name, result = loader(name, containingFile));
421+
cache.set(name, result = loader(name, containingFile, redirectedReference));
422422
}
423423
resolutions.push(result);
424424
}
@@ -638,10 +638,10 @@ namespace ts {
638638
let _referencesArrayLiteralSyntax: ArrayLiteralExpression | null | undefined;
639639

640640
let moduleResolutionCache: ModuleResolutionCache | undefined;
641-
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[]) => ResolvedModuleFull[];
641+
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
642642
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
643643
if (host.resolveModuleNames) {
644-
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames).map(resolved => {
644+
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames, redirectedReference).map(resolved => {
645645
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
646646
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
647647
return resolved as ResolvedModuleFull;
@@ -653,17 +653,17 @@ namespace ts {
653653
}
654654
else {
655655
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
656-
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule!; // TODO: GH#18217
657-
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, loader);
656+
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule!; // TODO: GH#18217
657+
resolveModuleNamesWorker = (moduleNames, containingFile, _reusedNames, redirectedReference) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader);
658658
}
659659

660-
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[];
660+
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference) => ResolvedTypeReferenceDirective[];
661661
if (host.resolveTypeReferenceDirectives) {
662-
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile);
662+
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile, redirectedReference);
663663
}
664664
else {
665-
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective!; // TODO: GH#18217
666-
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, loader);
665+
const loader = (typesRef: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective!; // TODO: GH#18217
666+
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader);
667667
}
668668

669669
// Map from a stringified PackageId to the source file with that id.
@@ -760,12 +760,6 @@ namespace ts {
760760

761761
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
762762
oldProgram = undefined;
763-
// Do not use our own command line for projectReferenceRedirects
764-
if (projectReferenceRedirects) {
765-
Debug.assert(!!options.configFilePath);
766-
const path = toPath(options.configFilePath!);
767-
projectReferenceRedirects.delete(path);
768-
}
769763

770764
program = {
771765
getRootFileNames: () => rootNames,
@@ -887,7 +881,7 @@ namespace ts {
887881
if (structuralIsReused === StructureIsReused.Not && !file.ambientModuleNames.length) {
888882
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
889883
// the best we can do is fallback to the default logic.
890-
return resolveModuleNamesWorker(moduleNames, containingFile);
884+
return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getProjectReferenceRedirectProject(file.originalFileName));
891885
}
892886

893887
const oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
@@ -967,7 +961,7 @@ namespace ts {
967961
}
968962

969963
const resolutions = unknownModuleNames && unknownModuleNames.length
970-
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames)
964+
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getProjectReferenceRedirectProject(file.originalFileName))
971965
: emptyArray;
972966

973967
// Combine results of resolutions and predicted results
@@ -1248,7 +1242,7 @@ namespace ts {
12481242
if (resolveTypeReferenceDirectiveNamesWorker) {
12491243
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
12501244
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
1251-
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
1245+
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getProjectReferenceRedirectProject(newSourceFile.originalFileName));
12521246
// ensure that types resolutions are still correct
12531247
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
12541248
if (resolutionsChanged) {
@@ -2219,16 +2213,35 @@ namespace ts {
22192213

22202214
// If this file is produced by a referenced project, we need to rewrite it to
22212215
// look in the output folder of the referenced project rather than the input
2216+
const referencedProject = getProjectReferenceRedirectProject(fileName);
2217+
if (!referencedProject) {
2218+
return undefined;
2219+
}
2220+
2221+
const out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
2222+
return out ?
2223+
changeExtension(out, Extension.Dts) :
2224+
getOutputDeclarationFileName(fileName, referencedProject.commandLine);
2225+
}
2226+
2227+
/**
2228+
* Get the referenced project if the file is input file from that reference project
2229+
*/
2230+
function getProjectReferenceRedirectProject(fileName: string) {
2231+
if (!resolvedProjectReferences || !resolvedProjectReferences.length) {
2232+
return undefined;
2233+
}
2234+
2235+
// If this file is input file of the referenced projec
22222236
return forEachEntry(projectReferenceRedirects!, referencedProject => {
22232237
// not input file from the referenced project, ignore
2224-
if (!referencedProject || !contains(referencedProject.commandLine.fileNames, fileName, isSameFile)) {
2238+
if (!referencedProject ||
2239+
options.configFilePath === referencedProject.commandLine.options.configFilePath ||
2240+
!contains(referencedProject.commandLine.fileNames, fileName, isSameFile)) {
22252241
return undefined;
22262242
}
22272243

2228-
const out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
2229-
return out ?
2230-
changeExtension(out, Extension.Dts) :
2231-
getOutputDeclarationFileName(fileName, referencedProject.commandLine);
2244+
return referencedProject;
22322245
});
22332246
}
22342247

@@ -2246,7 +2259,7 @@ namespace ts {
22462259
return;
22472260
}
22482261

2249-
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName);
2262+
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getProjectReferenceRedirectProject(file.originalFileName));
22502263

22512264
for (let i = 0; i < typeDirectives.length; i++) {
22522265
const ref = file.typeReferenceDirectives[i];

src/compiler/resolutionCache.ts

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

8-
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[];
8+
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): ResolvedModuleFull[];
99
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined;
10-
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
10+
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
1111

1212
invalidateResolutionOfFile(filePath: Path): void;
1313
removeResolutionsOfFile(filePath: Path): void;
@@ -217,8 +217,8 @@ namespace ts {
217217
});
218218
}
219219

220-
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
221-
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache);
220+
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): CachedResolvedModuleWithFailedLookupLocations {
221+
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
222222
// return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
223223
if (!resolutionHost.getGlobalCache) {
224224
return primaryResult;
@@ -242,9 +242,10 @@ namespace ts {
242242
function resolveNamesWithLocalCache<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
243243
names: string[],
244244
containingFile: string,
245+
redirectedReference: ResolvedProjectReference | undefined,
245246
cache: Map<Map<T>>,
246247
perDirectoryCache: Map<Map<T>>,
247-
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T,
248+
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T,
248249
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
249250
reusedNames: string[] | undefined,
250251
logChanges: boolean): R[] {
@@ -274,7 +275,7 @@ namespace ts {
274275
resolution = resolutionInDirectory;
275276
}
276277
else {
277-
resolution = loader(name, containingFile, compilerOptions, resolutionHost);
278+
resolution = loader(name, containingFile, compilerOptions, resolutionHost, redirectedReference);
278279
perDirectoryResolution.set(name, resolution);
279280
}
280281
resolutionsInFile.set(name, resolution);
@@ -323,18 +324,18 @@ namespace ts {
323324
}
324325
}
325326

326-
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
327+
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[] {
327328
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>(
328-
typeDirectiveNames, containingFile,
329+
typeDirectiveNames, containingFile, redirectedReference,
329330
resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives,
330331
resolveTypeReferenceDirective, getResolvedTypeReferenceDirective,
331332
/*reusedNames*/ undefined, /*logChanges*/ false
332333
);
333334
}
334335

335-
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[] {
336+
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): ResolvedModuleFull[] {
336337
return resolveNamesWithLocalCache<CachedResolvedModuleWithFailedLookupLocations, ResolvedModuleFull>(
337-
moduleNames, containingFile,
338+
moduleNames, containingFile, redirectedReference,
338339
resolvedModuleNames, perDirectoryResolvedModuleNames,
339340
resolveModuleName, getResolvedModule,
340341
reusedNames, logChangesWhenResolvingModule

0 commit comments

Comments
 (0)