From 9e505d9741ef3cee6f34acd6f5a118d7861b0dbf Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 27 Mar 2024 14:25:06 -0700 Subject: [PATCH 1/2] Sometimes modification of file can send "create" event instead of "update" --- .../unittests/helpers/virtualFileSystemWithWatch.ts | 9 ++++++--- src/testRunner/unittests/tsserver/moduleResolution.ts | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts index 7e24e71306d72..4c9e295785be9 100644 --- a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts +++ b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts @@ -290,6 +290,8 @@ export interface WatchInvokeOptions { invokeFileDeleteCreateAsPartInsteadOfChange: boolean; /** Dont invoke delete watches */ ignoreDelete: boolean; + /** ignore all watches */ + ignoreWatches?: boolean; /** Skip inode check on file or folder create*/ skipInodeCheckOnCreate: boolean; /** When invoking rename event on fs watch, send event with file name suffixed with tilde */ @@ -501,6 +503,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, else { currentEntry.content = content; currentEntry.modifiedTime = this.now(); + if (options?.ignoreWatches) return; if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) { const directoryFullPath = getDirectoryPath(currentEntry.fullPath); this.fs.get(getDirectoryPath(currentEntry.path))!.modifiedTime = this.now(); @@ -628,7 +631,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.fs.set(fileOrDirectory.path, fileOrDirectory); this.setInode(fileOrDirectory.path); - if (ignoreWatch) { + if (ignoreWatch || options?.ignoreWatches) { return; } const inodeWatching = this.inodeWatching; @@ -651,9 +654,9 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, if (isFsFolder(fileOrDirectory)) { Debug.assert(fileOrDirectory.entries.length === 0 || isRenaming); } - if (!options?.ignoreDelete) this.invokeFileAndFsWatches(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted, /*modifiedTime*/ undefined, options?.useTildeAsSuffixInRenameEventFileName); + if (!options?.ignoreDelete && !options?.ignoreWatches) this.invokeFileAndFsWatches(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted, /*modifiedTime*/ undefined, options?.useTildeAsSuffixInRenameEventFileName); this.inodes?.delete(fileOrDirectory.path); - if (!options?.ignoreDelete) this.invokeFileAndFsWatches(baseFolder.fullPath, FileWatcherEventKind.Changed, baseFolder.modifiedTime, options?.useTildeAsSuffixInRenameEventFileName); + if (!options?.ignoreDelete && !options?.ignoreWatches) this.invokeFileAndFsWatches(baseFolder.fullPath, FileWatcherEventKind.Changed, baseFolder.modifiedTime, options?.useTildeAsSuffixInRenameEventFileName); } deleteFile(filePath: string) { diff --git a/src/testRunner/unittests/tsserver/moduleResolution.ts b/src/testRunner/unittests/tsserver/moduleResolution.ts index f893b95d1255a..b930725d33db9 100644 --- a/src/testRunner/unittests/tsserver/moduleResolution.ts +++ b/src/testRunner/unittests/tsserver/moduleResolution.ts @@ -76,14 +76,16 @@ describe("unittests:: tsserver:: moduleResolution", () => { const { host, session, packageFile, verifyErr } = setup(jsonToReadableText({ name: "app", version: "1.0.0" })); session.logger.info("Modify package json file to add type module"); - host.writeFile( + host.modifyFile( packageFile.path, jsonToReadableText({ name: "app", version: "1.0.0", type: "module", }), + { ignoreWatches: true }, ); + host.invokeFsWatches(packageFile.path, "rename", /*modifiedTime*/ undefined, /*useTildeSuffix*/ undefined); // Create event instead of change host.runQueuedTimeoutCallbacks(); // Failed lookup updates host.runQueuedTimeoutCallbacks(); // Actual update verifyErr(); From d5a546c0ed61655281239e24b93d9faf409ee2da Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 27 Mar 2024 14:27:18 -0700 Subject: [PATCH 2/2] Handle the case when change event can come as "create" --- src/server/editorServices.ts | 1 - .../moduleResolution/package-json-file-is-edited.js | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 168ecb744b67f..7c50a738c81b2 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -4682,7 +4682,6 @@ export class ProjectService { (fileName, eventKind) => { switch (eventKind) { case FileWatcherEventKind.Created: - return Debug.fail(); case FileWatcherEventKind.Changed: this.packageJsonCache.addOrUpdate(fileName, path); this.onPackageJsonChange(result); diff --git a/tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited.js b/tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited.js index 26deef03b4c40..e1dcef5e5731c 100644 --- a/tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited.js +++ b/tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited.js @@ -244,11 +244,11 @@ ScriptInfos:: /user/username/projects/myproject/src/tsconfig.json Info seq [hh:mm:ss:mss] Modify package json file to add type module -Info seq [hh:mm:ss:mss] FileWatcher:: Triggered with /user/username/projects/myproject/package.json 1:: WatchInfo: /user/username/projects/myproject/package.json 2000 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Triggered with /user/username/projects/myproject/package.json 0:: WatchInfo: /user/username/projects/myproject/package.json 2000 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: File location affecting resolution Info seq [hh:mm:ss:mss] Scheduled: /user/username/projects/myproject/src/tsconfig.jsonFailedLookupInvalidation -Info seq [hh:mm:ss:mss] Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/package.json 1:: WatchInfo: /user/username/projects/myproject/package.json 2000 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: File location affecting resolution -Info seq [hh:mm:ss:mss] FileWatcher:: Triggered with /user/username/projects/myproject/package.json 1:: WatchInfo: /user/username/projects/myproject/package.json 250 undefined WatchType: package.json file -Info seq [hh:mm:ss:mss] Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/package.json 1:: WatchInfo: /user/username/projects/myproject/package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/package.json 0:: WatchInfo: /user/username/projects/myproject/package.json 2000 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Triggered with /user/username/projects/myproject/package.json 0:: WatchInfo: /user/username/projects/myproject/package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/package.json 0:: WatchInfo: /user/username/projects/myproject/package.json 250 undefined WatchType: package.json file Before running Timeout callback:: count: 1 1: /user/username/projects/myproject/src/tsconfig.jsonFailedLookupInvalidation //// [/user/username/projects/myproject/package.json]