mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 03:20:56 -06:00
Use watch factory instead of direct host functions in tsbuild to provide detailed information on watch invokations
This commit is contained in:
parent
b8def16e92
commit
0cabb00b34
@ -443,6 +443,7 @@ namespace ts {
|
||||
let nextProjectToBuild = 0;
|
||||
let timerToBuildInvalidatedProject: any;
|
||||
let reportFileChangeDetected = false;
|
||||
const { watchFile, watchFilePath, watchDirectory } = createWatchFactory<ResolvedConfigFileName>(host, options);
|
||||
|
||||
// Watches for the solution
|
||||
const allWatchedWildcardDirectories = createFileMap<Map<WildcardDirectoryWatcher>>(toPath);
|
||||
@ -542,9 +543,16 @@ namespace ts {
|
||||
|
||||
function watchConfigFile(resolved: ResolvedConfigFileName) {
|
||||
if (options.watch && !allWatchedConfigFiles.hasKey(resolved)) {
|
||||
allWatchedConfigFiles.setValue(resolved, hostWithWatch.watchFile(resolved, () => {
|
||||
allWatchedConfigFiles.setValue(resolved, watchFile(
|
||||
hostWithWatch,
|
||||
resolved,
|
||||
() => {
|
||||
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Full);
|
||||
}));
|
||||
},
|
||||
PollingInterval.High,
|
||||
WatchType.ConfigFile,
|
||||
resolved
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,20 +562,27 @@ namespace ts {
|
||||
getOrCreateValueMapFromConfigFileMap(allWatchedWildcardDirectories, resolved),
|
||||
createMapFromTemplate(parsed.configFileSpecs!.wildcardDirectories),
|
||||
(dir, flags) => {
|
||||
return hostWithWatch.watchDirectory(dir, fileOrDirectory => {
|
||||
const fileOrDirectoryPath = toPath(fileOrDirectory);
|
||||
if (fileOrDirectoryPath !== toPath(dir) && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
|
||||
// writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
|
||||
return;
|
||||
}
|
||||
return watchDirectory(
|
||||
hostWithWatch,
|
||||
dir,
|
||||
fileOrDirectory => {
|
||||
const fileOrDirectoryPath = toPath(fileOrDirectory);
|
||||
if (fileOrDirectoryPath !== toPath(dir) && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
|
||||
// writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isOutputFile(fileOrDirectory, parsed)) {
|
||||
// writeLog(`${fileOrDirectory} is output file`);
|
||||
return;
|
||||
}
|
||||
if (isOutputFile(fileOrDirectory, parsed)) {
|
||||
// writeLog(`${fileOrDirectory} is output file`);
|
||||
return;
|
||||
}
|
||||
|
||||
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Partial);
|
||||
}, !!(flags & WatchDirectoryFlags.Recursive));
|
||||
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.Partial);
|
||||
},
|
||||
flags,
|
||||
WatchType.WildcardDirectory,
|
||||
resolved
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -578,9 +593,15 @@ namespace ts {
|
||||
getOrCreateValueMapFromConfigFileMap(allWatchedInputFiles, resolved),
|
||||
arrayToMap(parsed.fileNames, toPath),
|
||||
{
|
||||
createNewValue: (_key, input) => hostWithWatch.watchFile(input, () => {
|
||||
invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.None);
|
||||
}),
|
||||
createNewValue: (path, input) => watchFilePath(
|
||||
hostWithWatch,
|
||||
input,
|
||||
() => invalidateProjectAndScheduleBuilds(resolved, ConfigFileProgramReloadLevel.None),
|
||||
PollingInterval.Low,
|
||||
path as Path,
|
||||
WatchType.SourceFile,
|
||||
resolved
|
||||
),
|
||||
onDeleteValue: closeFileWatcher,
|
||||
}
|
||||
);
|
||||
|
||||
@ -194,6 +194,30 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export const enum WatchType {
|
||||
ConfigFile = "Config file",
|
||||
SourceFile = "Source file",
|
||||
MissingFile = "Missing file",
|
||||
WildcardDirectory = "Wild card directory",
|
||||
FailedLookupLocations = "Failed Lookup Locations",
|
||||
TypeRoots = "Type roots"
|
||||
}
|
||||
|
||||
interface WatchFactory<X, Y= undefined> extends ts.WatchFactory<X, Y> {
|
||||
watchLogLevel: WatchLogLevel;
|
||||
writeLog: (s: string) => void;
|
||||
}
|
||||
|
||||
export function createWatchFactory<Y = undefined>(host: { trace?(s: string): void; }, options: { extendedDiagnostics?: boolean; diagnostics?: boolean; }) {
|
||||
const watchLogLevel = host.trace ? options.extendedDiagnostics ? WatchLogLevel.Verbose :
|
||||
options.diagnostics ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
|
||||
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? (s => host.trace!(s)) : noop;
|
||||
const result = getWatchFactory<WatchType, Y>(watchLogLevel, writeLog) as WatchFactory<WatchType, Y>;
|
||||
result.watchLogLevel = watchLogLevel;
|
||||
result.writeLog = writeLog;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the watch compiler host that can be extended with config file or root file names and options host
|
||||
*/
|
||||
@ -224,7 +248,7 @@ namespace ts {
|
||||
watchDirectory,
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
trace: s => system.write(s),
|
||||
trace: s => system.write(s + system.newLine),
|
||||
onWatchStatusChange,
|
||||
createDirectory: path => system.createDirectory(path),
|
||||
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
|
||||
@ -517,17 +541,12 @@ namespace ts {
|
||||
newLine = updateNewLine();
|
||||
}
|
||||
|
||||
const trace = host.trace && ((s: string) => { host.trace!(s + newLine); });
|
||||
const watchLogLevel = trace ? compilerOptions.extendedDiagnostics ? WatchLogLevel.Verbose :
|
||||
compilerOptions.diagnostics ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
|
||||
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? trace! : noop; // TODO: GH#18217
|
||||
const { watchFile, watchFilePath, watchDirectory } = getWatchFactory<string>(watchLogLevel, writeLog);
|
||||
|
||||
const { watchFile, watchFilePath, watchDirectory, watchLogLevel, writeLog } = createWatchFactory<string>(host, compilerOptions);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames}`);
|
||||
if (configFileName) {
|
||||
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, "Config file");
|
||||
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, WatchType.ConfigFile);
|
||||
}
|
||||
|
||||
const compilerHost: CompilerHost & ResolutionCacheHost = {
|
||||
@ -543,7 +562,7 @@ namespace ts {
|
||||
getNewLine: () => newLine,
|
||||
fileExists,
|
||||
readFile,
|
||||
trace,
|
||||
trace: host.trace && (s => host.trace!(s)),
|
||||
directoryExists: directoryStructureHost.directoryExists && (path => directoryStructureHost.directoryExists!(path)),
|
||||
getDirectories: (directoryStructureHost.getDirectories && ((path: string) => directoryStructureHost.getDirectories!(path)))!, // TODO: GH#18217
|
||||
realpath: host.realpath && (s => host.realpath!(s)),
|
||||
@ -553,8 +572,8 @@ namespace ts {
|
||||
// Members for ResolutionCacheHost
|
||||
toPath,
|
||||
getCompilationSettings: () => compilerOptions,
|
||||
watchDirectoryOfFailedLookupLocation: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Failed Lookup Locations"),
|
||||
watchTypeRootsDirectory: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Type roots"),
|
||||
watchDirectoryOfFailedLookupLocation: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, WatchType.FailedLookupLocations),
|
||||
watchTypeRootsDirectory: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, WatchType.TypeRoots),
|
||||
getCachedDirectoryStructureHost: () => cachedDirectoryStructureHost,
|
||||
onInvalidatedResolution: scheduleProgramUpdate,
|
||||
onChangedAutomaticTypeDirectiveNames: () => {
|
||||
@ -719,7 +738,7 @@ namespace ts {
|
||||
(hostSourceFile as FilePresentOnHost).sourceFile = sourceFile;
|
||||
sourceFile.version = hostSourceFile.version.toString();
|
||||
if (!(hostSourceFile as FilePresentOnHost).fileWatcher) {
|
||||
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
|
||||
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, WatchType.SourceFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -733,7 +752,7 @@ namespace ts {
|
||||
else {
|
||||
if (sourceFile) {
|
||||
sourceFile.version = initialVersion.toString();
|
||||
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
|
||||
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, WatchType.SourceFile);
|
||||
sourceFilesCache.set(path, { sourceFile, version: initialVersion, fileWatcher });
|
||||
}
|
||||
else {
|
||||
@ -907,7 +926,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function watchMissingFilePath(missingFilePath: Path) {
|
||||
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath, "Missing file");
|
||||
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath, WatchType.MissingFile);
|
||||
}
|
||||
|
||||
function onMissingFileChange(fileName: string, eventKind: FileWatcherEventKind, missingFilePath: Path) {
|
||||
@ -971,7 +990,7 @@ namespace ts {
|
||||
}
|
||||
},
|
||||
flags,
|
||||
"Wild card directories"
|
||||
WatchType.WildcardDirectory
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -343,10 +343,10 @@ namespace ts {
|
||||
export interface WatchDirectoryHost {
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
}
|
||||
export type WatchFile<X, Y> = (host: WatchFileHost, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
|
||||
export type WatchFile<X, Y> = (host: WatchFileHost, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
|
||||
export type FilePathWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, filePath: Path) => void;
|
||||
export type WatchFilePath<X, Y> = (host: WatchFileHost, file: string, callback: FilePathWatcherCallback, pollingInterval: PollingInterval, path: Path, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
|
||||
export type WatchDirectory<X, Y> = (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags, detailInfo1?: X, detailInfo2?: Y) => FileWatcher;
|
||||
export type WatchFilePath<X, Y> = (host: WatchFileHost, file: string, callback: FilePathWatcherCallback, pollingInterval: PollingInterval, path: Path, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
|
||||
export type WatchDirectory<X, Y> = (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags, detailInfo1: X, detailInfo2?: Y) => FileWatcher;
|
||||
|
||||
export interface WatchFactory<X, Y> {
|
||||
watchFile: WatchFile<X, Y>;
|
||||
@ -444,7 +444,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getWatchInfo<T, X, Y>(file: string, flags: T, detailInfo1: X, detailInfo2: Y | undefined, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined) {
|
||||
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo1}`;
|
||||
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo2 === undefined ? detailInfo1 : `${detailInfo1} ${detailInfo2}`}`;
|
||||
}
|
||||
|
||||
export function closeFileWatcherOf<T extends { watcher: FileWatcher; }>(objWithWatcher: T) {
|
||||
|
||||
@ -332,19 +332,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum WatchType {
|
||||
ConfigFilePath = "Config file for the program",
|
||||
MissingFilePath = "Missing file from program",
|
||||
WildcardDirectories = "Wild card directory",
|
||||
ClosedScriptInfo = "Closed Script info",
|
||||
ConfigFileForInferredRoot = "Config file for the inferred project root",
|
||||
FailedLookupLocation = "Directory of Failed lookup locations in module resolution",
|
||||
TypeRoots = "Type root directory",
|
||||
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
|
||||
MissingSourceMapFile = "Missing source map file"
|
||||
}
|
||||
|
||||
const enum ConfigFileWatcherStatus {
|
||||
ReloadingFiles = "Reloading configured projects for files",
|
||||
ReloadingInferredRootFiles = "Reloading configured projects for only inferred root files",
|
||||
@ -1035,7 +1022,7 @@ namespace ts.server {
|
||||
}
|
||||
},
|
||||
flags,
|
||||
WatchType.WildcardDirectories,
|
||||
WatchType.WildcardDirectory,
|
||||
project
|
||||
);
|
||||
}
|
||||
@ -1338,7 +1325,7 @@ namespace ts.server {
|
||||
watches.push(WatchType.ConfigFileForInferredRoot);
|
||||
}
|
||||
if (this.configuredProjects.has(canonicalConfigFilePath)) {
|
||||
watches.push(WatchType.ConfigFilePath);
|
||||
watches.push(WatchType.ConfigFile);
|
||||
}
|
||||
this.logger.info(`ConfigFilePresence:: Current Watches: ${watches}:: File: ${configFileName} Currently impacted open files: RootsOfInferredProjects: ${inferredRoots} OtherOpenFiles: ${otherFiles} Status: ${status}`);
|
||||
}
|
||||
@ -1705,7 +1692,7 @@ namespace ts.server {
|
||||
configFileName,
|
||||
(_fileName, eventKind) => this.onConfigChangedForConfiguredProject(project, eventKind),
|
||||
PollingInterval.High,
|
||||
WatchType.ConfigFilePath,
|
||||
WatchType.ConfigFile,
|
||||
project
|
||||
);
|
||||
this.configuredProjects.set(project.canonicalConfigFilePath, project);
|
||||
|
||||
@ -428,7 +428,7 @@ namespace ts.server {
|
||||
directory,
|
||||
cb,
|
||||
flags,
|
||||
WatchType.FailedLookupLocation,
|
||||
WatchType.FailedLookupLocations,
|
||||
this
|
||||
);
|
||||
}
|
||||
@ -989,7 +989,7 @@ namespace ts.server {
|
||||
}
|
||||
},
|
||||
PollingInterval.Medium,
|
||||
WatchType.MissingFilePath,
|
||||
WatchType.MissingFile,
|
||||
this
|
||||
);
|
||||
return fileWatcher;
|
||||
|
||||
@ -217,3 +217,14 @@ namespace ts.server {
|
||||
return indentStr + JSON.stringify(json);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
// Additional tsserver specific watch information
|
||||
export const enum WatchType {
|
||||
ClosedScriptInfo = "Closed Script info",
|
||||
ConfigFileForInferredRoot = "Config file for the inferred project root",
|
||||
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
|
||||
MissingSourceMapFile = "Missing source map file",
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user