Skip to content

Commit 69bb5ea

Browse files
committed
Do not trigger the failed lookup location invalidation for creation of program emit files
Handles microsoft#20934
1 parent c5ed864 commit 69bb5ea

8 files changed

Lines changed: 53 additions & 8 deletions

File tree

src/compiler/emitter.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ namespace ts {
1818
* If an array, the full list of source files to emit.
1919
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
2020
*/
21-
export function forEachEmittedFile(
22-
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
21+
export function forEachEmittedFile<T>(
22+
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => T,
2323
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
2424
emitOnlyDtsFiles?: boolean) {
2525

@@ -30,15 +30,21 @@ namespace ts {
3030
const jsFilePath = options.outFile || options.out;
3131
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
3232
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : "";
33-
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
33+
const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
34+
if (result) {
35+
return result;
36+
}
3437
}
3538
}
3639
else {
3740
for (const sourceFile of sourceFiles) {
3841
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
3942
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
4043
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
41-
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
44+
const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
45+
if (result) {
46+
return result;
47+
}
4248
}
4349
}
4450
}

src/compiler/program.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,8 @@ namespace ts {
667667
dropDiagnosticsProducingTypeChecker,
668668
getSourceFileFromReference,
669669
sourceFileToPackageName,
670-
redirectTargetsSet
670+
redirectTargetsSet,
671+
isEmittedFile
671672
};
672673

673674
verifyCompilerOptions();
@@ -2343,6 +2344,20 @@ namespace ts {
23432344
hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
23442345
programDiagnostics.add(diag);
23452346
}
2347+
2348+
function isEmittedFile(file: string) {
2349+
if (options.noEmit) {
2350+
return false;
2351+
}
2352+
2353+
return forEachEmittedFile(getEmitHost(), ({ jsFilePath, declarationFilePath }) =>
2354+
isSameFile(jsFilePath, file) ||
2355+
(declarationFilePath && isSameFile(declarationFilePath, file)));
2356+
}
2357+
2358+
function isSameFile(file1: string, file2: string) {
2359+
return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
2360+
}
23462361
}
23472362

23482363
/* @internal */

src/compiler/resolutionCache.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace ts {
5252
getGlobalCache?(): string | undefined;
5353
writeLog(s: string): void;
5454
maxNumberOfFilesToIterateForInvalidation?: number;
55+
getCurrentProgram(): Program;
5556
}
5657

5758
interface DirectoryWatchesOfFailedLookup {
@@ -472,6 +473,11 @@ namespace ts {
472473
resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
473474
}
474475

476+
// Ignore emits from the program
477+
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) {
478+
return;
479+
}
480+
475481
// If the files are added to project root or node_modules directory, always run through the invalidation process
476482
// Otherwise run through invalidation only if adding to the immediate directory
477483
if (!allFilesHaveInvalidatedResolution &&

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,6 +2659,8 @@ namespace ts {
26592659
/* @internal */ sourceFileToPackageName: Map<string>;
26602660
/** Set of all source files that some other source file redirects to. */
26612661
/* @internal */ redirectTargetsSet: Map<true>;
2662+
/** Is the file emitted file */
2663+
/* @internal */ isEmittedFile(file: string): boolean;
26622664
}
26632665

26642666
/* @internal */

src/compiler/watch.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ namespace ts {
305305
scheduleProgramUpdate();
306306
},
307307
maxNumberOfFilesToIterateForInvalidation: watchingHost.maxNumberOfFilesToIterateForInvalidation,
308+
getCurrentProgram,
308309
writeLog
309310
};
310311
// Cache for the module resolution
@@ -322,7 +323,11 @@ namespace ts {
322323
// Update the wild card directory watch
323324
watchConfigFileWildCardDirectories();
324325

325-
return () => program;
326+
return getCurrentProgram;
327+
328+
function getCurrentProgram() {
329+
return program;
330+
}
326331

327332
function synchronizeProgram() {
328333
writeLog(`Synchronizing program`);

src/compiler/watchUtilities.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ namespace ts {
8282
}
8383
}
8484

85+
export function isEmittedFileOfProgram(program: Program | undefined, file: string) {
86+
if (!program) {
87+
return false;
88+
}
89+
90+
return program.isEmittedFile(file);
91+
}
92+
8593
export function addFileWatcher(host: System, file: string, cb: FileWatcherCallback): FileWatcher {
8694
return host.watchFile(file, cb);
8795
}

src/harness/unittests/tscWatchMode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ namespace ts.tscWatch {
10961096
assert.isTrue(host.fileExists("build/src/file2.js"));
10971097

10981098
// This should be 0
1099-
host.checkTimeoutQueueLengthAndRun(1);
1099+
host.checkTimeoutQueueLengthAndRun(0);
11001100
});
11011101
});
11021102

src/server/project.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,10 @@ namespace ts.server {
830830
return !hasChanges;
831831
}
832832

833-
833+
/* @internal */
834+
getCurrentProgram() {
835+
return this.program;
836+
}
834837

835838
protected removeExistingTypings(include: string[]): string[] {
836839
const existing = ts.getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost);

0 commit comments

Comments
 (0)