diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index ce18f9f839a..5c040bbf2ab 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -289,8 +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 tscWatchFile?: string; - private readonly tscWatchDirectory?: string; private readonly runWithoutRecursiveWatches?: boolean; runWithFallbackPolling: boolean; public defaultWatchFileKind?: () => WatchFileKind | undefined; @@ -305,8 +303,8 @@ interface Array { length: number; [n: number]: T; }` }); const { environmentVariables, runWithoutRecursiveWatches, runWithFallbackPolling } = options; fileOrFolderOrSymLinkList = fileOrFolderOrSymLinkList.concat(withSafeList ? safeList : []); - this.tscWatchFile = environmentVariables && environmentVariables.get("TSC_WATCHFILE"); - this.tscWatchDirectory = environmentVariables && environmentVariables.get("TSC_WATCHDIRECTORY"); + const tscWatchFile = environmentVariables && environmentVariables.get("TSC_WATCHFILE"); + const tscWatchDirectory = environmentVariables && environmentVariables.get("TSC_WATCHDIRECTORY"); this.runWithoutRecursiveWatches = runWithoutRecursiveWatches; this.runWithFallbackPolling = !!runWithFallbackPolling; this.environmentVariables = environmentVariables; @@ -314,7 +312,7 @@ interface Array { length: number; [n: number]: T; }` // 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.tscWatchFile === Tsc_WatchFile.SingleFileWatcherPerName ? + pollingWatchFile: tscWatchFile === Tsc_WatchFile.SingleFileWatcherPerName ? createSingleFileWatcherPerName( this.watchFileWorker.bind(this), this.useCaseSensitiveFileNames @@ -327,12 +325,12 @@ interface Array { length: number; [n: number]: T; }` fileExists: this.fileExists.bind(this), useCaseSensitiveFileNames: this.useCaseSensitiveFileNames, getCurrentDirectory: this.getCurrentDirectory.bind(this), - fsSupportsRecursiveFsWatch: this.tscWatchDirectory ? false : !this.runWithoutRecursiveWatches, + fsSupportsRecursiveFsWatch: tscWatchDirectory ? false : !this.runWithoutRecursiveWatches, directoryExists: this.directoryExists.bind(this), getAccessibleSortedChildDirectories: path => this.getDirectories(path), realpath: this.realpath.bind(this), - tscWatchFile: this.tscWatchFile, - tscWatchDirectory: this.tscWatchDirectory, + tscWatchFile: tscWatchFile, + tscWatchDirectory: tscWatchDirectory, defaultWatchFileKind: () => this.defaultWatchFileKind?.(), }); this.watchFile = watchFile; @@ -508,20 +506,6 @@ interface Array { length: number; [n: number]: T; }` ); } - readFile(s: string): string | undefined { - const fsEntry = this.getRealFile(this.toFullPath(s)); - return fsEntry ? fsEntry.content : undefined; - } - - getFileSize(s: string) { - const path = this.toFullPath(s); - const entry = this.fs.get(path)!; - if (isFsFile(entry)) { - return entry.fileSize ? entry.fileSize : entry.content.length; - } - return undefined!; // TODO: GH#18217 - } - createHash(s: string): string { return `${generateDjb2Hash(s)}-${s}`; } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index fe87465d94f..f37329f2000 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -3698,13 +3698,8 @@ namespace ts.server { updateFileSystem(updatedFiles: protocol.FileSystemRequestArgs[] | undefined, deletedFiles?: string[]) { Debug.assert(this.fshost instanceof VirtualFS.VirtualServerHost); if (updatedFiles) { - for (const { file: path, fileContent: content } of updatedFiles) { - if (this.fshost.fileExists(path)) { - this.fshost.modifyFile(path, content); - } - else { - this.fshost.ensureFileOrFolder({ path, content }); - } + for (const { file, fileContent } of updatedFiles) { + this.fshost.ensureFileOrFolder({ path: file, content: fileContent }); } } if (deletedFiles) { diff --git a/src/server/project.ts b/src/server/project.ts index bfe2d0829da..bd55843d6fa 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1741,7 +1741,7 @@ namespace ts.server { fileExists: this.projectService.fshost.fileExists.bind(this.projectService.fshost), directoryExists: this.projectService.fshost.directoryExists.bind(this.projectService.fshost), realpath: this.projectService.fshost.realpath?.bind(this.projectService.fshost), - getCurrentDirectory: this.getCurrentDirectory.bind(this), // TODO: Not sure whether this should be this.projectService.fshost.getCurrentDirectory.bind(this.projectService.fshost) + getCurrentDirectory: this.projectService.fshost.getCurrentDirectory.bind(this.projectService.fshost), readFile: this.projectService.fshost.readFile.bind(this.projectService.fshost), getDirectories: this.projectService.fshost.getDirectories.bind(this.projectService.fshost), trace: this.projectService.host.trace?.bind(this.projectService.host), diff --git a/src/testRunner/unittests/tsserver/updateFileSystem.ts b/src/testRunner/unittests/tsserver/updateFileSystem.ts index cdfd4a42dbf..e283db6e6e8 100644 --- a/src/testRunner/unittests/tsserver/updateFileSystem.ts +++ b/src/testRunner/unittests/tsserver/updateFileSystem.ts @@ -85,6 +85,17 @@ ${file.fileContent}`; deleted: [], } }], + ["change app.ts content", { + command: protocol.CommandTypes.UpdateFileSystem, + arguments: { + fileSystem: "memfs", + files: [{ + file: "/fshost/b/app.ts", + fileContent: "import { xyz } from './file3'; let y = xyz" + }], + deleted: [], + }, + }], ["delete", { command: protocol.CommandTypes.UpdateFileSystem, arguments:{ diff --git a/src/vfs/virtualFileSystemWithWatch.ts b/src/vfs/virtualFileSystemWithWatch.ts index 12ea978c455..4c8f181789f 100644 --- a/src/vfs/virtualFileSystemWithWatch.ts +++ b/src/vfs/virtualFileSystemWithWatch.ts @@ -209,7 +209,10 @@ namespace ts.VirtualFS { if (isFile(fileOrDirectoryOrSymLink)) { const file = this.toFsFile(fileOrDirectoryOrSymLink); // file may already exist when updating existing type declaration file - if (!this.fs.get(file.path)) { + if (this.fs.get(file.path)) { + this.modifyFile(file.path, file.content); + } + else { const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath), ignoreParentWatch); this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate); } diff --git a/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.js b/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.js index e16ce95b9a5..d80453f205b 100644 --- a/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.js +++ b/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.js @@ -80,7 +80,9 @@ Open files: response:{"responseRequired":false} request:{"command":"updateFileSystem","arguments":{"fileSystem":"memfs","files":[],"deleted":[]},"seq":4,"type":"request"} response:{"response":true,"responseRequired":true} -request:{"command":"updateFileSystem","arguments":{"fileSystem":"memfs","files":[],"deleted":["/fshost/b/commonFile1.ts"]},"seq":5,"type":"request"} +request:{"command":"updateFileSystem","arguments":{"fileSystem":"memfs","files":[{"file":"/fshost/b/app.ts","fileContent":"import { xyz } from './file3'; let y = xyz"}],"deleted":[]},"seq":5,"type":"request"} +response:{"response":true,"responseRequired":true} +request:{"command":"updateFileSystem","arguments":{"fileSystem":"memfs","files":[],"deleted":["/fshost/b/commonFile1.ts"]},"seq":6,"type":"request"} FileWatcher:: Triggered with /fshost/b/commonFile1.ts 2:: WatchInfo: /fshost/b/commonFile1.ts 500 undefined WatchType: Closed Script info FileWatcher:: Close:: WatchInfo: /fshost/b/commonFile1.ts 500 undefined WatchType: Closed Script info Scheduled: /fshost/b/tsconfig.json @@ -91,7 +93,7 @@ Scheduled: /fshost/b/tsconfig.json Scheduled: *ensureProjectForOpenFiles* Elapsed:: *ms DirectoryWatcher:: Triggered with /fshost/b/commonFile1.ts :: WatchInfo: /fshost/b 1 undefined Config: /fshost/b/tsconfig.json WatchType: Wild card directory response:{"response":true,"responseRequired":true} -request:{"command":"close","arguments":{"file":"/fshost/b/app.ts"},"seq":6,"type":"request"} +request:{"command":"close","arguments":{"file":"/fshost/b/app.ts"},"seq":7,"type":"request"} FileWatcher:: Added:: WatchInfo: /fshost/b/app.ts 500 undefined WatchType: Closed Script info Project '/fshost/b/tsconfig.json' (Configured) Files (4) diff --git a/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.txt b/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.txt index 0171292f0bc..f6a29462bd2 100644 --- a/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.txt +++ b/tests/baselines/reference/tsserver/updateFileSystem/open-and-close-files.txt @@ -39,6 +39,12 @@ interface Array { length: number; [n: number]: T; } #### non-delete +#### change app.ts content +//// [/fshost/b/app.ts] +import { xyz } from './file3'; let y = xyz + + + #### delete //// [/fshost/b/commonFile1.ts] deleted