@@ -378,16 +378,24 @@ function createDynamicPriorityPollingWatchFile(host: {
378
378
}
379
379
}
380
380
381
- function createUseFsEventsOnParentDirectoryWatchFile ( fsWatch : FsWatch , useCaseSensitiveFileNames : boolean ) : HostWatchFile {
381
+ function createUseFsEventsOnParentDirectoryWatchFile (
382
+ fsWatch : FsWatch ,
383
+ useCaseSensitiveFileNames : boolean ,
384
+ getModifiedTime : NonNullable < System [ "getModifiedTime" ] > ,
385
+ fsWatchWithTimestamp : boolean | undefined ,
386
+ ) : HostWatchFile {
382
387
// One file can have multiple watchers
383
388
const fileWatcherCallbacks = createMultiMap < string , FileWatcherCallback > ( ) ;
389
+ const fileTimestamps = fsWatchWithTimestamp ? new Map < string , Date > ( ) : undefined ;
384
390
const dirWatchers = new Map < string , DirectoryWatcher > ( ) ;
385
391
const toCanonicalName = createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
386
392
return nonPollingWatchFile ;
387
393
388
394
function nonPollingWatchFile ( fileName : string , callback : FileWatcherCallback , _pollingInterval : PollingInterval , fallbackOptions : WatchOptions | undefined ) : FileWatcher {
389
395
const filePath = toCanonicalName ( fileName ) ;
390
- fileWatcherCallbacks . add ( filePath , callback ) ;
396
+ if ( fileWatcherCallbacks . add ( filePath , callback ) . length === 1 && fileTimestamps ) {
397
+ fileTimestamps . set ( filePath , getModifiedTime ( fileName ) || missingFileModifiedTime ) ;
398
+ }
391
399
const dirPath = getDirectoryPath ( filePath ) || "." ;
392
400
const watcher = dirWatchers . get ( dirPath ) ||
393
401
createDirectoryWatcher ( getDirectoryPath ( fileName ) || "." , dirPath , fallbackOptions ) ;
@@ -410,15 +418,29 @@ function createUseFsEventsOnParentDirectoryWatchFile(fsWatch: FsWatch, useCaseSe
410
418
const watcher = fsWatch (
411
419
dirName ,
412
420
FileSystemEntryKind . Directory ,
413
- ( _eventName : string , relativeFileName , modifiedTime ) => {
421
+ ( eventName : string , relativeFileName ) => {
414
422
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
415
423
if ( ! isString ( relativeFileName ) ) return ;
416
424
const fileName = getNormalizedAbsolutePath ( relativeFileName , dirName ) ;
425
+ const filePath = toCanonicalName ( fileName ) ;
417
426
// Some applications save a working file via rename operations
418
- const callbacks = fileName && fileWatcherCallbacks . get ( toCanonicalName ( fileName ) ) ;
427
+ const callbacks = fileName && fileWatcherCallbacks . get ( filePath ) ;
419
428
if ( callbacks ) {
429
+ let currentModifiedTime ;
430
+ let eventKind = FileWatcherEventKind . Changed ;
431
+ if ( fileTimestamps ) {
432
+ const existingTime = fileTimestamps . get ( filePath ) ! ;
433
+ if ( eventName === "change" ) {
434
+ currentModifiedTime = getModifiedTime ( fileName ) || missingFileModifiedTime ;
435
+ if ( currentModifiedTime . getTime ( ) === existingTime . getTime ( ) ) return ;
436
+ }
437
+ currentModifiedTime ||= getModifiedTime ( fileName ) || missingFileModifiedTime ;
438
+ fileTimestamps . set ( filePath , currentModifiedTime ) ;
439
+ if ( existingTime === missingFileModifiedTime ) eventKind = FileWatcherEventKind . Created ;
440
+ else if ( currentModifiedTime === missingFileModifiedTime ) eventKind = FileWatcherEventKind . Deleted ;
441
+ }
420
442
for ( const fileCallback of callbacks ) {
421
- fileCallback ( fileName , FileWatcherEventKind . Changed , modifiedTime ) ;
443
+ fileCallback ( fileName , eventKind , currentModifiedTime ) ;
422
444
}
423
445
}
424
446
} ,
@@ -974,7 +996,7 @@ export function createSystemWatchFunctions({
974
996
) ;
975
997
case WatchFileKind . UseFsEventsOnParentDirectory :
976
998
if ( ! nonPollingWatchFile ) {
977
- nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile ( fsWatch , useCaseSensitiveFileNames ) ;
999
+ nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile ( fsWatch , useCaseSensitiveFileNames , getModifiedTime , fsWatchWithTimestamp ) ;
978
1000
}
979
1001
return nonPollingWatchFile ( fileName , callback , pollingInterval , getFallbackOptions ( options ) ) ;
980
1002
default :
@@ -1191,7 +1213,7 @@ export function createSystemWatchFunctions({
1191
1213
return watchPresentFileSystemEntryWithFsWatchFile ( ) ;
1192
1214
}
1193
1215
try {
1194
- const presentWatcher = ( ! fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp ) (
1216
+ const presentWatcher = ( entryKind === FileSystemEntryKind . Directory || ! fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp ) (
1195
1217
fileOrDirectory ,
1196
1218
recursive ,
1197
1219
inodeWatching ?
0 commit comments