diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts
index a2f366e9bf7..c0ab1065755 100644
--- a/src/compiler/sys.ts
+++ b/src/compiler/sys.ts
@@ -1147,7 +1147,12 @@ namespace ts {
(!relativeName ||
relativeName === lastDirectoryPart ||
(relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator!) !== -1 && relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator!) === relativeName.length - lastDirectoryPartWithDirectorySeparator!.length))) {
- updateWatcher(!fileSystemEntryExists(fileOrDirectory, entryKind) ? watchMissingFileSystemEntry : watchPresentFileSystemEntry);
+ if (inodeWatching) {
+ updateWatcher(!fileSystemEntryExists(fileOrDirectory, entryKind) ? watchMissingFileSystemEntry : watchPresentFileSystemEntry);
+ }
+ else if (!fileSystemEntryExists(fileOrDirectory, entryKind)) {
+ updateWatcher(watchMissingFileSystemEntry);
+ }
}
}
diff --git a/src/testRunner/unittests/tscWatch/watchEnvironment.ts b/src/testRunner/unittests/tscWatch/watchEnvironment.ts
index c050451193e..7428d9d1a15 100644
--- a/src/testRunner/unittests/tscWatch/watchEnvironment.ts
+++ b/src/testRunner/unittests/tscWatch/watchEnvironment.ts
@@ -582,6 +582,41 @@ namespace ts.tscWatch {
});
});
+ verifyTscWatch({
+ scenario,
+ subScenario: `fsWatch/when using file watching thats when rename occurs when file is still on the disk`,
+ commandLineArgs: ["-w", "--extendedDiagnostics"],
+ sys: () => createWatchedSystem(
+ {
+ [libFile.path]: libFile.content,
+ [`${projectRoot}/main.ts`]: `import { foo } from "./foo"; foo();`,
+ [`${projectRoot}/foo.ts`]: `export declare function foo(): string;`,
+ [`${projectRoot}/tsconfig.json`]: JSON.stringify({
+ watchOptions: { watchFile: "useFsEvents" },
+ files: ["foo.ts", "main.ts"]
+ }),
+ },
+ { currentDirectory: projectRoot, }
+ ),
+ changes: [
+ {
+ caption: "Introduce error such that when callback happens file is already appeared",
+ // vm's wq generates this kind of event
+ // Skip delete event so inode changes but when the create's rename occurs file is on disk
+ change: sys => sys.modifyFile(`${projectRoot}/foo.ts`, `export declare function foo2(): string;`, {
+ invokeFileDeleteCreateAsPartInsteadOfChange: true,
+ ignoreDelete: true,
+ }),
+ timeouts: sys => sys.checkTimeoutQueueLengthAndRun(1),
+ },
+ {
+ caption: "Replace file with rename event that fixes error",
+ change: sys => sys.modifyFile(`${projectRoot}/foo.ts`, `export declare function foo(): string;`, { invokeFileDeleteCreateAsPartInsteadOfChange: true, }),
+ timeouts: sys => sys.checkTimeoutQueueLengthAndRun(1),
+ },
+ ]
+ });
+
describe("with fsWatch on inodes", () => {
verifyTscWatch({
scenario,
diff --git a/tests/baselines/reference/tscWatch/watchEnvironment/fsWatch/when-using-file-watching-thats-when-rename-occurs-when-file-is-still-on-the-disk.js b/tests/baselines/reference/tscWatch/watchEnvironment/fsWatch/when-using-file-watching-thats-when-rename-occurs-when-file-is-still-on-the-disk.js
new file mode 100644
index 00000000000..129e3ec2f79
--- /dev/null
+++ b/tests/baselines/reference/tscWatch/watchEnvironment/fsWatch/when-using-file-watching-thats-when-rename-occurs-when-file-is-still-on-the-disk.js
@@ -0,0 +1,220 @@
+Input::
+//// [/a/lib/lib.d.ts]
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+
+//// [/user/username/projects/myproject/main.ts]
+import { foo } from "./foo"; foo();
+
+//// [/user/username/projects/myproject/foo.ts]
+export declare function foo(): string;
+
+//// [/user/username/projects/myproject/tsconfig.json]
+{"watchOptions":{"watchFile":"useFsEvents"},"files":["foo.ts","main.ts"]}
+
+
+/a/lib/tsc.js -w --extendedDiagnostics
+Output::
+[[90m12:00:23 AM[0m] Starting compilation in watch mode...
+
+Current directory: /user/username/projects/myproject CaseSensitiveFileNames: false
+FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFile":4} Config file
+Synchronizing program
+CreatingProgramWith::
+ roots: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+ options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/main.ts 250 {"watchFile":4} Source file
+FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 {"watchFile":4} Source file
+DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 {"watchFile":4} Type roots
+Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 {"watchFile":4} Type roots
+[[90m12:00:28 AM[0m] Found 0 errors. Watching for file changes.
+
+
+
+Program root files: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+Program options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+Program structureReused: Not
+Program files::
+/a/lib/lib.d.ts
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Semantic diagnostics in builder refreshed for::
+/a/lib/lib.d.ts
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Shape signatures in builder refreshed for::
+/a/lib/lib.d.ts (used version)
+/user/username/projects/myproject/foo.ts (used version)
+/user/username/projects/myproject/main.ts (used version)
+
+WatchedFiles::
+/user/username/projects/myproject/node_modules/@types:
+ {"fileName":"/user/username/projects/myproject/node_modules/@types","pollingInterval":500}
+
+FsWatches::
+/user/username/projects/myproject/tsconfig.json:
+ {"directoryName":"/user/username/projects/myproject/tsconfig.json"}
+/user/username/projects/myproject/foo.ts:
+ {"directoryName":"/user/username/projects/myproject/foo.ts"}
+/user/username/projects/myproject/main.ts:
+ {"directoryName":"/user/username/projects/myproject/main.ts"}
+/a/lib/lib.d.ts:
+ {"directoryName":"/a/lib/lib.d.ts"}
+
+FsWatchesRecursive::
+
+exitCode:: ExitStatus.undefined
+
+//// [/user/username/projects/myproject/foo.js]
+"use strict";
+exports.__esModule = true;
+
+
+//// [/user/username/projects/myproject/main.js]
+"use strict";
+exports.__esModule = true;
+var foo_1 = require("./foo");
+(0, foo_1.foo)();
+
+
+
+Change:: Introduce error such that when callback happens file is already appeared
+
+Input::
+//// [/user/username/projects/myproject/foo.ts]
+export declare function foo2(): string;
+
+
+Output::
+FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 0:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+Scheduling update
+Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 0:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+Synchronizing program
+[[90m12:00:32 AM[0m] File change detected. Starting incremental compilation...
+
+CreatingProgramWith::
+ roots: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+ options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+[96mmain.ts[0m:[93m1[0m:[93m10[0m - [91merror[0m[90m TS2724: [0m'"./foo"' has no exported member named 'foo'. Did you mean 'foo2'?
+
+[7m1[0m import { foo } from "./foo"; foo();
+[7m [0m [91m ~~~[0m
+
+ [96mfoo.ts[0m:[93m1[0m:[93m25[0m
+ [7m1[0m export declare function foo2(): string;
+ [7m [0m [96m ~~~~[0m
+ 'foo2' is declared here.
+
+[[90m12:00:39 AM[0m] Found 1 error. Watching for file changes.
+
+
+
+Program root files: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+Program options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+Program structureReused: Completely
+Program files::
+/a/lib/lib.d.ts
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Semantic diagnostics in builder refreshed for::
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Shape signatures in builder refreshed for::
+/user/username/projects/myproject/foo.ts (computed .d.ts)
+/user/username/projects/myproject/main.ts (computed .d.ts)
+
+WatchedFiles::
+/user/username/projects/myproject/node_modules/@types:
+ {"fileName":"/user/username/projects/myproject/node_modules/@types","pollingInterval":500}
+
+FsWatches::
+/user/username/projects/myproject/tsconfig.json:
+ {"directoryName":"/user/username/projects/myproject/tsconfig.json"}
+/user/username/projects/myproject/foo.ts:
+ {"directoryName":"/user/username/projects/myproject/foo.ts"}
+/user/username/projects/myproject/main.ts:
+ {"directoryName":"/user/username/projects/myproject/main.ts"}
+/a/lib/lib.d.ts:
+ {"directoryName":"/a/lib/lib.d.ts"}
+
+FsWatchesRecursive::
+
+exitCode:: ExitStatus.undefined
+
+//// [/user/username/projects/myproject/foo.js] file written with same contents
+//// [/user/username/projects/myproject/main.js] file written with same contents
+
+Change:: Replace file with rename event that fixes error
+
+Input::
+//// [/user/username/projects/myproject/foo.ts]
+export declare function foo(): string;
+
+
+Output::
+FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 2:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+Scheduling update
+Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 2:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 0:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+Scheduling update
+Elapsed:: *ms FileWatcher:: Triggered with /user/username/projects/myproject/foo.ts 0:: WatchInfo: /user/username/projects/myproject/foo.ts 250 {"watchFile":4} Source file
+Synchronizing program
+[[90m12:00:43 AM[0m] File change detected. Starting incremental compilation...
+
+CreatingProgramWith::
+ roots: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+ options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+[[90m12:00:50 AM[0m] Found 0 errors. Watching for file changes.
+
+
+
+Program root files: ["/user/username/projects/myproject/foo.ts","/user/username/projects/myproject/main.ts"]
+Program options: {"watch":true,"extendedDiagnostics":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
+Program structureReused: SafeModules
+Program files::
+/a/lib/lib.d.ts
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Semantic diagnostics in builder refreshed for::
+/user/username/projects/myproject/foo.ts
+/user/username/projects/myproject/main.ts
+
+Shape signatures in builder refreshed for::
+/user/username/projects/myproject/foo.ts (computed .d.ts)
+/user/username/projects/myproject/main.ts (computed .d.ts)
+
+WatchedFiles::
+/user/username/projects/myproject/node_modules/@types:
+ {"fileName":"/user/username/projects/myproject/node_modules/@types","pollingInterval":500}
+
+FsWatches::
+/user/username/projects/myproject/tsconfig.json:
+ {"directoryName":"/user/username/projects/myproject/tsconfig.json"}
+/user/username/projects/myproject/foo.ts:
+ {"directoryName":"/user/username/projects/myproject/foo.ts"}
+/user/username/projects/myproject/main.ts:
+ {"directoryName":"/user/username/projects/myproject/main.ts"}
+/a/lib/lib.d.ts:
+ {"directoryName":"/a/lib/lib.d.ts"}
+
+FsWatchesRecursive::
+
+exitCode:: ExitStatus.undefined
+
+//// [/user/username/projects/myproject/foo.js] file written with same contents
+//// [/user/username/projects/myproject/main.js] file written with same contents