@@ -378,16 +378,24 @@ function createDynamicPriorityPollingWatchFile(host: {
378378 }
379379}
380380
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 {
382387 // One file can have multiple watchers
383388 const fileWatcherCallbacks = createMultiMap < string , FileWatcherCallback > ( ) ;
389+ const fileTimestamps = fsWatchWithTimestamp ? new Map < string , Date > ( ) : undefined ;
384390 const dirWatchers = new Map < string , DirectoryWatcher > ( ) ;
385391 const toCanonicalName = createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
386392 return nonPollingWatchFile ;
387393
388394 function nonPollingWatchFile ( fileName : string , callback : FileWatcherCallback , _pollingInterval : PollingInterval , fallbackOptions : WatchOptions | undefined ) : FileWatcher {
389395 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+ }
391399 const dirPath = getDirectoryPath ( filePath ) || "." ;
392400 const watcher = dirWatchers . get ( dirPath ) ||
393401 createDirectoryWatcher ( getDirectoryPath ( fileName ) || "." , dirPath , fallbackOptions ) ;
@@ -410,15 +418,29 @@ function createUseFsEventsOnParentDirectoryWatchFile(fsWatch: FsWatch, useCaseSe
410418 const watcher = fsWatch (
411419 dirName ,
412420 FileSystemEntryKind . Directory ,
413- ( _eventName : string , relativeFileName , modifiedTime ) => {
421+ ( eventName : string , relativeFileName ) => {
414422 // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
415423 if ( ! isString ( relativeFileName ) ) return ;
416424 const fileName = getNormalizedAbsolutePath ( relativeFileName , dirName ) ;
425+ const filePath = toCanonicalName ( fileName ) ;
417426 // Some applications save a working file via rename operations
418- const callbacks = fileName && fileWatcherCallbacks . get ( toCanonicalName ( fileName ) ) ;
427+ const callbacks = fileName && fileWatcherCallbacks . get ( filePath ) ;
419428 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+ }
420442 for ( const fileCallback of callbacks ) {
421- fileCallback ( fileName , FileWatcherEventKind . Changed , modifiedTime ) ;
443+ fileCallback ( fileName , eventKind , currentModifiedTime ) ;
422444 }
423445 }
424446 } ,
@@ -974,7 +996,7 @@ export function createSystemWatchFunctions({
974996 ) ;
975997 case WatchFileKind . UseFsEventsOnParentDirectory :
976998 if ( ! nonPollingWatchFile ) {
977- nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile ( fsWatch , useCaseSensitiveFileNames ) ;
999+ nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile ( fsWatch , useCaseSensitiveFileNames , getModifiedTime , fsWatchWithTimestamp ) ;
9781000 }
9791001 return nonPollingWatchFile ( fileName , callback , pollingInterval , getFallbackOptions ( options ) ) ;
9801002 default :
@@ -1191,7 +1213,7 @@ export function createSystemWatchFunctions({
11911213 return watchPresentFileSystemEntryWithFsWatchFile ( ) ;
11921214 }
11931215 try {
1194- const presentWatcher = ( ! fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp ) (
1216+ const presentWatcher = ( entryKind === FileSystemEntryKind . Directory || ! fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp ) (
11951217 fileOrDirectory ,
11961218 recursive ,
11971219 inodeWatching ?
0 commit comments