From 4d413a6a55ab92d90c8c9f3b59e45c24e5e100cd Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 2 Oct 2018 13:11:12 -0700 Subject: [PATCH] Fix the fileByName cache when program is used completely which breaks the getSourceFile not return redirected file by its name --- src/compiler/program.ts | 28 +++++++++++--------- src/testRunner/unittests/tsbuildWatchMode.ts | 15 +++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 416c2d218e..e7caa7048c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1095,7 +1095,6 @@ namespace ts { // check if program source files has changed in the way that can affect structure of the program const newSourceFiles: SourceFile[] = []; - const filePaths: Path[] = []; const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = []; oldProgram.structureIsReused = StructureIsReused.Completely; @@ -1148,7 +1147,6 @@ namespace ts { newSourceFile.originalFileName = oldSourceFile.originalFileName; newSourceFile.resolvedPath = oldSourceFile.resolvedPath; newSourceFile.fileName = oldSourceFile.fileName; - filePaths.push(newSourceFile.path); const packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); if (packageName !== undefined) { @@ -1266,11 +1264,12 @@ namespace ts { missingFilePaths = oldProgram.getMissingFilePaths(); // update fileName -> file mapping - for (let i = 0; i < newSourceFiles.length; i++) { - filesByName.set(filePaths[i], newSourceFiles[i]); + for (const newSourceFile of newSourceFiles) { + const filePath = newSourceFile.path; + addFileToFilesByName(newSourceFile, filePath, newSourceFile.resolvedPath); // Set the file as found during node modules search if it was found that way in old progra, - if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i])!)) { - sourceFilesFoundSearchingNodeModules.set(filePaths[i], true); + if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePath)!)) { + sourceFilesFoundSearchingNodeModules.set(filePath, true); } } @@ -2113,7 +2112,7 @@ namespace ts { return file; } - let redirectedPath: string | undefined; + let redirectedPath: Path | undefined; if (refFile) { const redirect = getProjectReferenceRedirect(fileName); if (redirect) { @@ -2147,7 +2146,7 @@ namespace ts { // Instead of creating a duplicate, just redirect to the existing one. const dupFile = createRedirectSourceFile(fileFromPackageId, file!, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217 redirectTargetsMap.add(fileFromPackageId.path, fileName); - filesByName.set(path, dupFile); + addFileToFilesByName(dupFile, path, redirectedPath); sourceFileToPackageName.set(path, packageId.name); processingOtherFiles!.push(dupFile); return dupFile; @@ -2158,11 +2157,7 @@ namespace ts { sourceFileToPackageName.set(path, packageId.name); } } - - filesByName.set(path, file); - if (redirectedPath) { - filesByName.set(redirectedPath, file); - } + addFileToFilesByName(file, path, redirectedPath); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -2205,6 +2200,13 @@ namespace ts { return file; } + function addFileToFilesByName(file: SourceFile | undefined, path: Path, redirectedPath: Path | undefined) { + filesByName.set(path, file); + if (redirectedPath) { + filesByName.set(redirectedPath, file); + } + } + function getProjectReferenceRedirect(fileName: string): string | undefined { // Ignore dts or any of the non ts files if (!resolvedProjectReferences || !resolvedProjectReferences.length || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) { diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index 87116a2820..4226ae2e02 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -562,6 +562,21 @@ export function gfoo() { const { host, watch } = createSolutionAndWatchMode(); verifyProgram(host, watch); }); + + it("non local edit updates the program and watch correctly", () => { + const { host, watch, solutionBuilder } = createSolutionAndWatchMode(); + + // edit + host.writeFile(bTs.path, `${bTs.content} +export function gfoo() { +}`); + solutionBuilder.invalidateProject(bTsconfig.path); + solutionBuilder.buildInvalidatedProject(); + + host.checkTimeoutQueueLengthAndRun(1); + checkOutputErrorsIncremental(host, emptyArray); + verifyProgram(host, watch); + }); }); }); });