Skip to content

Commit 3eafb64

Browse files
authored
Handle reusing type reference resolution in resolution cache correctly (microsoft#51475)
* Add tests where typeRef resolution is not in the cache * Ensure that type ref reuse is actually handled since type ref resolution only sends containingSourceFileMode and not containingSourceFile
1 parent 10125e4 commit 3eafb64

File tree

3 files changed

+817
-3
lines changed

3 files changed

+817
-3
lines changed

src/compiler/resolutionCache.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,12 +581,13 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
581581
resolvedModules.push(getResolutionWithResolvedFileName(resolution));
582582
}
583583

584-
if (containingSourceFile && resolutionInfo) {
584+
// If resolving type reference directive we dont need containingSourceFile to determine if we can use resolutionInfo
585+
if (resolutionInfo && (loader === resolveTypeReferenceDirective as unknown || containingSourceFile)) {
585586
resolutionInfo.reusedNames?.forEach(entry => seenNamesInFile.set(
586587
getResolutionName(entry),
587588
!isString(entry) && isStringLiteralLike(entry) ?
588-
getModeForUsageLocation(containingSourceFile, entry) :
589-
getModeForFileReference(entry, containingSourceFile.impliedNodeFormat),
589+
getModeForUsageLocation(containingSourceFile!, entry) :
590+
getModeForFileReference(entry, containingSourceFileMode),
590591
true,
591592
));
592593
reusedNames = undefined;

src/testRunner/unittests/tscWatch/resolutionCache.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as ts from "../../_namespaces/ts";
2+
import * as Utils from "../../_namespaces/Utils";
23
import { createWatchedSystem, File, libFile, SymLink } from "../virtualFileSystemWithWatch";
34
import { createBaseline, createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline, runWatchBaseline, verifyTscWatch } from "./helpers";
45

@@ -565,4 +566,50 @@ declare namespace NodeJS {
565566
]
566567
});
567568
});
569+
570+
verifyTscWatch({
571+
scenario,
572+
subScenario: "reusing type ref resolution",
573+
sys: () => createWatchedSystem({
574+
"/src/project/tsconfig.json": JSON.stringify({
575+
compilerOptions: {
576+
composite: true,
577+
traceResolution: true,
578+
outDir: "outDir",
579+
},
580+
}),
581+
"/src/project/fileWithImports.ts": Utils.dedent`
582+
import type { Import0 } from "pkg0";
583+
import type { Import1 } from "pkg1";
584+
`,
585+
"/src/project/node_modules/pkg0/index.d.ts": `export interface Import0 {}`,
586+
"/src/project/fileWithTypeRefs.ts": Utils.dedent`
587+
/// <reference types="pkg2"/>
588+
/// <reference types="pkg3"/>
589+
interface LocalInterface extends Import2, Import3 {}
590+
export {}
591+
`,
592+
"/src/project/node_modules/pkg2/index.d.ts": `interface Import2 {}`,
593+
[libFile.path]: libFile.content,
594+
}, { currentDirectory: "/src/project" }),
595+
commandLineArgs: ["-w", "--explainFiles", "--extendedDiagnostics"],
596+
changes: [
597+
{
598+
caption: "write file not resolved by import",
599+
change: sys => sys.ensureFileOrFolder({ path: "/src/project/node_modules/pkg1/index.d.ts", content: `export interface Import1 {}` }),
600+
timeouts: sys => {
601+
sys.runQueuedTimeoutCallbacks(); // failed lookup
602+
sys.runQueuedTimeoutCallbacks(); // actual update
603+
}
604+
},
605+
{
606+
caption: "write file not resolved by typeRef",
607+
change: sys => sys.ensureFileOrFolder({ path: "/src/project/node_modules/pkg3/index.d.ts", content: `export interface Import3 {}` }),
608+
timeouts: sys => {
609+
sys.runQueuedTimeoutCallbacks(); // failed lookup
610+
sys.runQueuedTimeoutCallbacks(); // actual update
611+
}
612+
},
613+
]
614+
});
568615
});

0 commit comments

Comments
 (0)