Skip to content

Commit 0cabb00

Browse files
committed
Use watch factory instead of direct host functions in tsbuild to provide detailed information on watch invokations
1 parent b8def16 commit 0cabb00

File tree

6 files changed

+94
-56
lines changed

6 files changed

+94
-56
lines changed

src/compiler/tsbuild.ts

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ namespace ts {
443443
let nextProjectToBuild = 0;
444444
let timerToBuildInvalidatedProject: any;
445445
let reportFileChangeDetected = false;
446+
const { watchFile, watchFilePath, watchDirectory } = createWatchFactory<ResolvedConfigFileName>(host, options);
446447

447448
// Watches for the solution
448449
const allWatchedWildcardDirectories = createFileMap<Map<WildcardDirectoryWatcher>>(toPath);
@@ -542,9 +543,16 @@ namespace ts {
542543

543544
function watchConfigFile(resolved: ResolvedConfigFileName) {
544545
if (options.watch && !allWatchedConfigFiles.hasKey(resolved)) {
545-
allWatchedConfigFiles.setValue(resolved, hostWithWatch.watchFile(resolved, () => {
546+
allWatchedConfigFiles.setValue(resolved, watchFile(
547+
hostWithWatch,
548+
resolved,
549+
() => {
546550
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Full);
547-
}));
551+
},
552+
PollingInterval.High,
553+
WatchType.ConfigFile,
554+
resolved
555+
));
548556
}
549557
}
550558

@@ -554,20 +562,27 @@ namespace ts {
554562
getOrCreateValueMapFromConfigFileMap(allWatchedWildcardDirectories, resolved),
555563
createMapFromTemplate(parsed.configFileSpecs!.wildcardDirectories),
556564
(dir, flags) => {
557-
return hostWithWatch.watchDirectory(dir, fileOrDirectory => {
558-
const fileOrDirectoryPath = toPath(fileOrDirectory);
559-
if (fileOrDirectoryPath !== toPath(dir) && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
560-
// writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
561-
return;
562-
}
563-
564-
if (isOutputFile(fileOrDirectory, parsed)) {
565-
// writeLog(`${fileOrDirectory} is output file`);
566-
return;
567-
}
568-
569-
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Partial);
570-
}, !!(flags & WatchDirectoryFlags.Recursive));
565+
return watchDirectory(
566+
hostWithWatch,
567+
dir,
568+
fileOrDirectory => {
569+
const fileOrDirectoryPath = toPath(fileOrDirectory);
570+
if (fileOrDirectoryPath !== toPath(dir) && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
571+
// writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
572+
return;
573+
}
574+
575+
if (isOutputFile(fileOrDirectory, parsed)) {
576+
// writeLog(`${fileOrDirectory} is output file`);
577+
return;
578+
}
579+
580+
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Partial);
581+
},
582+
flags,
583+
WatchType.WildcardDirectory,
584+
resolved
585+
);
571586
}
572587
);
573588
}
@@ -578,9 +593,15 @@ namespace ts {
578593
getOrCreateValueMapFromConfigFileMap(allWatchedInputFiles, resolved),
579594
arrayToMap(parsed.fileNames, toPath),
580595
{
581-
createNewValue: (_key, input) => hostWithWatch.watchFile(input, () => {
582-
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.None);
583-
}),
596+
createNewValue: (path, input) => watchFilePath(
597+
hostWithWatch,
598+
input,
599+
() => invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.None),
600+
PollingInterval.Low,
601+
path as Path,
602+
WatchType.SourceFile,
603+
resolved
604+
),
584605
onDeleteValue: closeFileWatcher,
585606
}
586607
);

src/compiler/watch.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,30 @@ namespace ts {
194194
};
195195
}
196196

197+
export const enum WatchType {
198+
ConfigFile = "Config file",
199+
SourceFile = "Source file",
200+
MissingFile = "Missing file",
201+
WildcardDirectory = "Wild card directory",
202+
FailedLookupLocations = "Failed Lookup Locations",
203+
TypeRoots = "Type roots"
204+
}
205+
206+
interface WatchFactory<X, Y= undefined> extends ts.WatchFactory<X, Y> {
207+
watchLogLevel: WatchLogLevel;
208+
writeLog: (s: string) => void;
209+
}
210+
211+
export function createWatchFactory<Y = undefined>(host: { trace?(s: string): void; }, options: { extendedDiagnostics?: boolean; diagnostics?: boolean; }) {
212+
const watchLogLevel = host.trace ? options.extendedDiagnostics ? WatchLogLevel.Verbose :
213+
options.diagnostics ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
214+
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? (s => host.trace!(s)) : noop;
215+
const result = getWatchFactory<WatchType, Y>(watchLogLevel, writeLog) as WatchFactory<WatchType, Y>;
216+
result.watchLogLevel = watchLogLevel;
217+
result.writeLog = writeLog;
218+
return result;
219+
}
220+
197221
/**
198222
* Creates the watch compiler host that can be extended with config file or root file names and options host
199223
*/
@@ -224,7 +248,7 @@ namespace ts {
224248
watchDirectory,
225249
setTimeout,
226250
clearTimeout,
227-
trace: s => system.write(s),
251+
trace: s => system.write(s + system.newLine),
228252
onWatchStatusChange,
229253
createDirectory: path => system.createDirectory(path),
230254
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
@@ -517,17 +541,12 @@ namespace ts {
517541
newLine = updateNewLine();
518542
}
519543

520-
const trace = host.trace && ((s: string) => { host.trace!(s + newLine); });
521-
const watchLogLevel = trace ? compilerOptions.extendedDiagnostics ? WatchLogLevel.Verbose :
522-
compilerOptions.diagnostics ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
523-
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? trace! : noop; // TODO: GH#18217
524-
const { watchFile, watchFilePath, watchDirectory } = getWatchFactory<string>(watchLogLevel, writeLog);
525-
544+
const { watchFile, watchFilePath, watchDirectory, watchLogLevel, writeLog } = createWatchFactory<string>(host, compilerOptions);
526545
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
527546

528547
writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames}`);
529548
if (configFileName) {
530-
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, "Config file");
549+
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, WatchType.ConfigFile);
531550
}
532551

533552
const compilerHost: CompilerHost & ResolutionCacheHost = {
@@ -543,7 +562,7 @@ namespace ts {
543562
getNewLine: () => newLine,
544563
fileExists,
545564
readFile,
546-
trace,
565+
trace: host.trace && (s => host.trace!(s)),
547566
directoryExists: directoryStructureHost.directoryExists && (path => directoryStructureHost.directoryExists!(path)),
548567
getDirectories: (directoryStructureHost.getDirectories && ((path: string) => directoryStructureHost.getDirectories!(path)))!, // TODO: GH#18217
549568
realpath: host.realpath && (s => host.realpath!(s)),
@@ -553,8 +572,8 @@ namespace ts {
553572
// Members for ResolutionCacheHost
554573
toPath,
555574
getCompilationSettings: () => compilerOptions,
556-
watchDirectoryOfFailedLookupLocation: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Failed Lookup Locations"),
557-
watchTypeRootsDirectory: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Type roots"),
575+
watchDirectoryOfFailedLookupLocation: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, WatchType.FailedLookupLocations),
576+
watchTypeRootsDirectory: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, WatchType.TypeRoots),
558577
getCachedDirectoryStructureHost: () => cachedDirectoryStructureHost,
559578
onInvalidatedResolution: scheduleProgramUpdate,
560579
onChangedAutomaticTypeDirectiveNames: () => {
@@ -719,7 +738,7 @@ namespace ts {
719738
(hostSourceFile as FilePresentOnHost).sourceFile = sourceFile;
720739
sourceFile.version = hostSourceFile.version.toString();
721740
if (!(hostSourceFile as FilePresentOnHost).fileWatcher) {
722-
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
741+
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, WatchType.SourceFile);
723742
}
724743
}
725744
else {
@@ -733,7 +752,7 @@ namespace ts {
733752
else {
734753
if (sourceFile) {
735754
sourceFile.version = initialVersion.toString();
736-
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
755+
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, WatchType.SourceFile);
737756
sourceFilesCache.set(path, { sourceFile, version: initialVersion, fileWatcher });
738757
}
739758
else {
@@ -907,7 +926,7 @@ namespace ts {
907926
}
908927

909928
function watchMissingFilePath(missingFilePath: Path) {
910-
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath, "Missing file");
929+
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath, WatchType.MissingFile);
911930
}
912931

913932
function onMissingFileChange(fileName: string, eventKind: FileWatcherEventKind, missingFilePath: Path) {
@@ -971,7 +990,7 @@ namespace ts {
971990
}
972991
},
973992
flags,
974-
"Wild card directories"
993+
WatchType.WildcardDirectory
975994
);
976995
}
977996

src/compiler/watchUtilities.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,10 @@ namespace ts {
343343
export interface WatchDirectoryHost {
344344
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
345345
}
346-
export type WatchFile<X, Y> = (host: WatchFileHost, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
346+
export type WatchFile<X, Y> = (host: WatchFileHost, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
347347
export type FilePathWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, filePath: Path) => void;
348-
export type WatchFilePath<X, Y> = (host: WatchFileHost, file: string, callback: FilePathWatcherCallback, pollingInterval: PollingInterval, path: Path, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
349-
export type WatchDirectory<X, Y> = (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
348+
export type WatchFilePath<X, Y> = (host: WatchFileHost, file: string, callback: FilePathWatcherCallback, pollingInterval: PollingInterval, path: Path, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
349+
export type WatchDirectory<X, Y> = (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
350350

351351
export interface WatchFactory<X, Y> {
352352
watchFile: WatchFile<X, Y>;
@@ -444,7 +444,7 @@ namespace ts {
444444
}
445445

446446
function getWatchInfo<T, X, Y>(file: string, flags: T, detailInfo1: X, detailInfo2: Y | undefined, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined) {
447-
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo1}`;
447+
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo2 === undefined ? detailInfo1 : `${detailInfo1} ${detailInfo2}`}`;
448448
}
449449

450450
export function closeFileWatcherOf<T extends { watcher: FileWatcher; }>(objWithWatcher: T) {

src/server/editorServices.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -332,19 +332,6 @@ namespace ts.server {
332332
}
333333
}
334334

335-
/* @internal */
336-
export const enum WatchType {
337-
ConfigFilePath = "Config file for the program",
338-
MissingFilePath = "Missing file from program",
339-
WildcardDirectories = "Wild card directory",
340-
ClosedScriptInfo = "Closed Script info",
341-
ConfigFileForInferredRoot = "Config file for the inferred project root",
342-
FailedLookupLocation = "Directory of Failed lookup locations in module resolution",
343-
TypeRoots = "Type root directory",
344-
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
345-
MissingSourceMapFile = "Missing source map file"
346-
}
347-
348335
const enum ConfigFileWatcherStatus {
349336
ReloadingFiles = "Reloading configured projects for files",
350337
ReloadingInferredRootFiles = "Reloading configured projects for only inferred root files",
@@ -1035,7 +1022,7 @@ namespace ts.server {
10351022
}
10361023
},
10371024
flags,
1038-
WatchType.WildcardDirectories,
1025+
WatchType.WildcardDirectory,
10391026
project
10401027
);
10411028
}
@@ -1338,7 +1325,7 @@ namespace ts.server {
13381325
watches.push(WatchType.ConfigFileForInferredRoot);
13391326
}
13401327
if (this.configuredProjects.has(canonicalConfigFilePath)) {
1341-
watches.push(WatchType.ConfigFilePath);
1328+
watches.push(WatchType.ConfigFile);
13421329
}
13431330
this.logger.info(`ConfigFilePresence:: Current Watches: ${watches}:: File: ${configFileName} Currently impacted open files: RootsOfInferredProjects: ${inferredRoots} OtherOpenFiles: ${otherFiles} Status: ${status}`);
13441331
}
@@ -1705,7 +1692,7 @@ namespace ts.server {
17051692
configFileName,
17061693
(_fileName, eventKind) => this.onConfigChangedForConfiguredProject(project, eventKind),
17071694
PollingInterval.High,
1708-
WatchType.ConfigFilePath,
1695+
WatchType.ConfigFile,
17091696
project
17101697
);
17111698
this.configuredProjects.set(project.canonicalConfigFilePath, project);

src/server/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ namespace ts.server {
428428
directory,
429429
cb,
430430
flags,
431-
WatchType.FailedLookupLocation,
431+
WatchType.FailedLookupLocations,
432432
this
433433
);
434434
}
@@ -989,7 +989,7 @@ namespace ts.server {
989989
}
990990
},
991991
PollingInterval.Medium,
992-
WatchType.MissingFilePath,
992+
WatchType.MissingFile,
993993
this
994994
);
995995
return fileWatcher;

src/server/utilities.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,14 @@ namespace ts.server {
217217
return indentStr + JSON.stringify(json);
218218
}
219219
}
220+
221+
/* @internal */
222+
namespace ts {
223+
// Additional tsserver specific watch information
224+
export const enum WatchType {
225+
ClosedScriptInfo = "Closed Script info",
226+
ConfigFileForInferredRoot = "Config file for the inferred project root",
227+
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
228+
MissingSourceMapFile = "Missing source map file",
229+
}
230+
}

0 commit comments

Comments
 (0)