diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 5c040bbf2ab..796d963f44b 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -281,7 +281,7 @@ interface Array { length: number; [n: number]: T; }` export const timeIncrements = 1000; - export class TestServerHost extends VirtualServerBaseHost implements server.ServerHost { + export class TestServerHost extends VirtualServerHost implements server.ServerHost { private readonly output: string[] = []; private time = timeIncrements; private timeoutCallbacks = new Callbacks(this); @@ -289,7 +289,6 @@ interface Array { length: number; [n: number]: T; }` readonly screenClears: number[] = []; private readonly environmentVariables?: ESMap; public require: ((initialPath: string, moduleName: string) => RequireResult) | undefined; - private readonly runWithoutRecursiveWatches?: boolean; runWithFallbackPolling: boolean; public defaultWatchFileKind?: () => WatchFileKind | undefined; @@ -299,42 +298,14 @@ interface Array { length: number; [n: number]: T; }` options: TestServerHostCreationParameters = {}) { super({ ...options, - executingFilePath: options.executingFilePath || getExecutingFilePathFromLibFile() - }); - const { environmentVariables, runWithoutRecursiveWatches, runWithFallbackPolling } = options; + executingFilePath: options.executingFilePath || getExecutingFilePathFromLibFile(), + }, + options, + () => this.defaultWatchFileKind?.()); + const { environmentVariables, runWithFallbackPolling } = options; fileOrFolderOrSymLinkList = fileOrFolderOrSymLinkList.concat(withSafeList ? safeList : []); - const tscWatchFile = environmentVariables && environmentVariables.get("TSC_WATCHFILE"); - const tscWatchDirectory = environmentVariables && environmentVariables.get("TSC_WATCHDIRECTORY"); - this.runWithoutRecursiveWatches = runWithoutRecursiveWatches; this.runWithFallbackPolling = !!runWithFallbackPolling; this.environmentVariables = environmentVariables; - const { watchFile, watchDirectory } = createSystemWatchFunctions({ - // We dont have polling watch file - // it is essentially fsWatch but lets get that separate from fsWatch and - // into watchedFiles for easier testing - pollingWatchFile: tscWatchFile === Tsc_WatchFile.SingleFileWatcherPerName ? - createSingleFileWatcherPerName( - this.watchFileWorker.bind(this), - this.useCaseSensitiveFileNames - ) : - this.watchFileWorker.bind(this), - getModifiedTime: this.getModifiedTime.bind(this), - setTimeout: this.setTimeout.bind(this), - clearTimeout: this.clearTimeout.bind(this), - fsWatch: this.fsWatch.bind(this), - fileExists: this.fileExists.bind(this), - useCaseSensitiveFileNames: this.useCaseSensitiveFileNames, - getCurrentDirectory: this.getCurrentDirectory.bind(this), - fsSupportsRecursiveFsWatch: tscWatchDirectory ? false : !this.runWithoutRecursiveWatches, - directoryExists: this.directoryExists.bind(this), - getAccessibleSortedChildDirectories: path => this.getDirectories(path), - realpath: this.realpath.bind(this), - tscWatchFile: tscWatchFile, - tscWatchDirectory: tscWatchDirectory, - defaultWatchFileKind: () => this.defaultWatchFileKind?.(), - }); - this.watchFile = watchFile; - this.watchDirectory = watchDirectory; this.reloadFS(fileOrFolderOrSymLinkList); } diff --git a/src/vfs/virtualFileSystemWithWatch.ts b/src/vfs/virtualFileSystemWithWatch.ts index 4c8f181789f..5d26eb43145 100644 --- a/src/vfs/virtualFileSystemWithWatch.ts +++ b/src/vfs/virtualFileSystemWithWatch.ts @@ -122,7 +122,7 @@ namespace ts.VirtualFS { * * also implements {server.ServerHost} but that would create a circular dependency */ - export abstract class VirtualServerBaseHost implements FormatDiagnosticsHost, ModuleResolutionHost { + export class VirtualServerHost implements FormatDiagnosticsHost, ModuleResolutionHost { args: string[] = []; protected fs: ESMap = new Map(); @@ -144,7 +144,9 @@ namespace ts.VirtualFS { constructor({ useCaseSensitiveFileNames, executingFilePath, currentDirectory, newLine, windowsStyleRoot - }: VirtualServerHostCreationParameters) { + }: VirtualServerHostCreationParameters, + testOptions?: { environmentVariables?: ESMap; runWithoutRecursiveWatches?: boolean; }, + defaultWatchFileKind?: (() => WatchFileKind | undefined)) { this.useCaseSensitiveFileNames = !!useCaseSensitiveFileNames; this.newLine = newLine || "\n"; this.windowsStyleRoot = windowsStyleRoot; @@ -153,6 +155,36 @@ namespace ts.VirtualFS { this.toPath = s => toPath(s, currentDirectory, this.getCanonicalFileName); this.executingFilePath = this.getHostSpecificPath(executingFilePath); this.currentDirectory = this.getHostSpecificPath(currentDirectory); + const { environmentVariables, runWithoutRecursiveWatches } = testOptions || {}; + const tscWatchFile = environmentVariables && environmentVariables.get("TSC_WATCHFILE"); + const tscWatchDirectory = environmentVariables && environmentVariables.get("TSC_WATCHDIRECTORY"); + const { watchFile, watchDirectory } = createSystemWatchFunctions({ + // We dont have polling watch file + // it is essentially fsWatch but lets get that separate from fsWatch and + // into watchedFiles for easier testing + pollingWatchFile: tscWatchFile === Tsc_WatchFile.SingleFileWatcherPerName ? + createSingleFileWatcherPerName( + this.watchFileWorker.bind(this), + this.useCaseSensitiveFileNames + ) : + this.watchFileWorker.bind(this), + getModifiedTime: this.getModifiedTime.bind(this), + setTimeout: this.setTimeout.bind(this), + clearTimeout: this.clearTimeout.bind(this), + fsWatch: this.fsWatch.bind(this), + fileExists: this.fileExists.bind(this), + useCaseSensitiveFileNames: this.useCaseSensitiveFileNames, + getCurrentDirectory: this.getCurrentDirectory.bind(this), + fsSupportsRecursiveFsWatch: tscWatchDirectory ? false : !runWithoutRecursiveWatches, + directoryExists: this.directoryExists.bind(this), + getAccessibleSortedChildDirectories: path => this.getDirectories(path), + realpath: this.realpath.bind(this), + defaultWatchFileKind: defaultWatchFileKind ?? (() => undefined), + tscWatchFile, + tscWatchDirectory, + }); + this.watchFile = watchFile; + this.watchDirectory = watchDirectory; } getNewLine() { @@ -621,34 +653,6 @@ namespace ts.VirtualFS { } } - export class VirtualServerHost extends VirtualServerBaseHost { - constructor(options: VirtualServerHostCreationParameters) { - super(options); - const { watchFile, watchDirectory } = createSystemWatchFunctions({ - // We dont have polling watch file - // it is essentially fsWatch but lets get that separate from fsWatch and - // into watchedFiles for easier testing - pollingWatchFile: this.watchFileWorker.bind(this), - getModifiedTime: this.getModifiedTime.bind(this), - setTimeout: this.setTimeout.bind(this), - clearTimeout: this.clearTimeout.bind(this), - fsWatch: this.fsWatch.bind(this), - fileExists: this.fileExists.bind(this), - useCaseSensitiveFileNames: this.useCaseSensitiveFileNames, - getCurrentDirectory: this.getCurrentDirectory.bind(this), - fsSupportsRecursiveFsWatch: true, - directoryExists: this.directoryExists.bind(this), - getAccessibleSortedChildDirectories: path => this.getDirectories(path), - realpath: this.realpath.bind(this), - tscWatchFile: undefined, - tscWatchDirectory: undefined, - defaultWatchFileKind: () => undefined, - }); - this.watchFile = watchFile; - this.watchDirectory = watchDirectory; - } - } - function diffFsFile(baseline: string[], fsEntry: FsFile) { baseline.push(`//// [${fsEntry.fullPath}]\r\n${fsEntry.content}`, ""); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f72d1afadd5..3b1b4c63be9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6985,7 +6985,8 @@ declare namespace ts.server { trace?(s: string): void; require?(initialPath: string, moduleName: string): RequireResult; } - type FileServerHost = Pick & { + type FileServerHost = Pick & { + deleteFile(path: string, deleteEmptyParentFolders?: boolean): void; ensureFileOrFolder(fileOrDirectoryOrSymLink: { path: string; } & ({