Skip to content

Commit 6c0b456

Browse files
committed
Enable incremental program updates through tsbuildinfo in tsc --watch mode
1 parent 8527be9 commit 6c0b456

File tree

4 files changed

+480
-9
lines changed

4 files changed

+480
-9
lines changed

src/compiler/watch.ts

+30-9
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ namespace ts {
129129
const diagnostics = program.getConfigFileParsingDiagnostics().slice();
130130
const configFileParsingDiagnosticsLength = diagnostics.length;
131131
addRange(diagnostics, program.getSyntacticDiagnostics());
132-
let reportSemanticDiagnostics = false;
133132

134133
// If we didn't have any syntactic errors, then also try getting the global and
135134
// semantic errors.
@@ -138,18 +137,14 @@ namespace ts {
138137
addRange(diagnostics, program.getGlobalDiagnostics());
139138

140139
if (diagnostics.length === configFileParsingDiagnosticsLength) {
141-
reportSemanticDiagnostics = true;
140+
addRange(diagnostics, program.getSemanticDiagnostics());
142141
}
143142
}
144143

145144
// Emit and report any errors we ran into.
146145
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit(/*targetSourceFile*/ undefined, writeFile);
147146
addRange(diagnostics, emitDiagnostics);
148147

149-
if (reportSemanticDiagnostics) {
150-
addRange(diagnostics, program.getSemanticDiagnostics());
151-
}
152-
153148
sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
154149
if (writeFileName) {
155150
const currentDir = program.getCurrentDirectory();
@@ -506,6 +501,9 @@ namespace ts {
506501
/** Gets the existing program without synchronizing with changes on host */
507502
/*@internal*/
508503
getCurrentProgram(): T;
504+
/** Closes the watch */
505+
/*@internal*/
506+
close(): void;
509507
}
510508

511509
/**
@@ -603,8 +601,9 @@ namespace ts {
603601
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
604602

605603
writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames}`);
604+
let configFileWatcher: FileWatcher | undefined;
606605
if (configFileName) {
607-
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, WatchType.ConfigFile);
606+
configFileWatcher = watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, WatchType.ConfigFile);
608607
}
609608

610609
const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions, directoryStructureHost) as CompilerHost & ResolutionCacheHost;
@@ -653,8 +652,30 @@ namespace ts {
653652
watchConfigFileWildCardDirectories();
654653

655654
return configFileName ?
656-
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram } :
657-
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram, updateRootFileNames };
655+
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram, close } :
656+
{ getCurrentProgram: getCurrentBuilderProgram, getProgram: synchronizeProgram, updateRootFileNames, close };
657+
658+
function close() {
659+
resolutionCache.clear();
660+
clearMap(sourceFilesCache, value => {
661+
if (value && value.fileWatcher) {
662+
value.fileWatcher.close();
663+
value.fileWatcher = undefined;
664+
}
665+
});
666+
if (configFileWatcher) {
667+
configFileWatcher.close();
668+
configFileWatcher = undefined;
669+
}
670+
if (watchedWildcardDirectories) {
671+
clearMap(watchedWildcardDirectories, closeFileWatcherOf);
672+
watchedWildcardDirectories = undefined!;
673+
}
674+
if (missingFilesMap) {
675+
clearMap(missingFilesMap, closeFileWatcher);
676+
missingFilesMap = undefined!;
677+
}
678+
}
658679

659680
function readBuilderProgram() {
660681
if (compilerOptions.out || compilerOptions.outFile) return;

src/testRunner/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
"unittests/tscWatch/consoleClearing.ts",
102102
"unittests/tscWatch/emit.ts",
103103
"unittests/tscWatch/emitAndErrorUpdates.ts",
104+
"unittests/tscWatch/incremental.ts",
104105
"unittests/tscWatch/programUpdates.ts",
105106
"unittests/tscWatch/resolutionCache.ts",
106107
"unittests/tscWatch/watchEnvironment.ts",

src/testRunner/unittests/tscWatch/helpers.ts

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace ts.tscWatch {
3232
export interface Watch {
3333
(): Program;
3434
getBuilderProgram(): EmitAndSemanticDiagnosticsBuilderProgram;
35+
close(): void;
3536
}
3637

3738
export function createWatchOfConfigFile(configFileName: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) {
@@ -40,6 +41,7 @@ namespace ts.tscWatch {
4041
const watch = createWatchProgram(compilerHost);
4142
const result = (() => watch.getCurrentProgram().getProgram()) as Watch;
4243
result.getBuilderProgram = () => watch.getCurrentProgram();
44+
result.close = () => watch.close();
4345
return result;
4446
}
4547

0 commit comments

Comments
 (0)