diff --git a/src/compiler/program.ts b/src/compiler/program.ts index cdfcfe6173bc7..ccec076ce7e48 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2031,6 +2031,7 @@ namespace ts { redirect.resolvedPath = resolvedPath; redirect.originalFileName = originalFileName; redirect.redirectInfo = { redirectTarget, unredirected }; + sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); Object.defineProperties(redirect, { id: { get(this: SourceFile) { return this.redirectInfo!.redirectTarget.id; }, diff --git a/src/testRunner/unittests/programMissingFiles.ts b/src/testRunner/unittests/programMissingFiles.ts index 37d4c7911961a..eb68e3bd6654d 100644 --- a/src/testRunner/unittests/programMissingFiles.ts +++ b/src/testRunner/unittests/programMissingFiles.ts @@ -98,4 +98,27 @@ namespace ts { ]); }); }); + + describe("Program.isSourceFileFromExternalLibrary", () => { + it("works on redirect files", () => { + // In this example '/node_modules/foo/index.d.ts' will redirect to '/node_modules/bar/node_modules/foo/index.d.ts'. + const a = new documents.TextDocument("/a.ts", 'import * as bar from "bar"; import * as foo from "foo";'); + const bar = new documents.TextDocument("/node_modules/bar/index.d.ts", 'import * as foo from "foo";'); + const fooPackageJsonText = '{ "name": "foo", "version": "1.2.3" }'; + const fooIndexText = "export const x: number;"; + const barFooPackage = new documents.TextDocument("/node_modules/bar/node_modules/foo/package.json", fooPackageJsonText); + const barFooIndex = new documents.TextDocument("/node_modules/bar/node_modules/foo/index.d.ts", fooIndexText); + const fooPackage = new documents.TextDocument("/node_modules/foo/package.json", fooPackageJsonText); + const fooIndex = new documents.TextDocument("/node_modules/foo/index.d.ts", fooIndexText); + + const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [a, bar, barFooPackage, barFooIndex, fooPackage, fooIndex], cwd: "/" }); + const program = createProgram(["/a.ts"], emptyOptions, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + + for (const file of [a, bar, barFooIndex, fooIndex]) { + const isExternalExpected = file !== a; + const isExternalActual = program.isSourceFileFromExternalLibrary(program.getSourceFile(file.file)!); + assert.equal(isExternalActual, isExternalExpected, `Expected ${file.file} isSourceFileFromExternalLibrary to be ${isExternalExpected}, got ${isExternalActual}`); + } + }); + }); }