@@ -53,6 +53,7 @@ const serviceSizeMap = new FileMap<number>();
5353const configWatchers = new FileMap < ts . FileWatcher > ( ) ;
5454const extendedConfigWatchers = new FileMap < ts . FileWatcher > ( ) ;
5555const extendedConfigToTsConfigPath = new FileMap < FileSet > ( ) ;
56+ const configFileModifiedTime = new FileMap < Date | undefined > ( ) ;
5657const configFileForOpenFiles = new FileMap < string > ( ) ;
5758const pendingReloads = new FileSet ( ) ;
5859
@@ -559,6 +560,7 @@ async function createLanguageService(
559560 }
560561
561562 if ( ! configWatchers . has ( tsconfigPath ) && tsconfigPath ) {
563+ configFileModifiedTime . set ( tsconfigPath , tsSystem . getModifiedTime ?.( tsconfigPath ) ) ;
562564 configWatchers . set (
563565 tsconfigPath ,
564566 // for some reason setting the polling interval is necessary, else some error in TS is thrown
@@ -571,6 +573,7 @@ async function createLanguageService(
571573 continue ;
572574 }
573575
576+ configFileModifiedTime . set ( config , tsSystem . getModifiedTime ?.( config ) ) ;
574577 extendedConfigWatchers . set (
575578 config ,
576579 // for some reason setting the polling interval is necessary, else some error in TS is thrown
@@ -579,7 +582,18 @@ async function createLanguageService(
579582 }
580583 }
581584
582- async function watchConfigCallback ( fileName : string , kind : ts . FileWatcherEventKind ) {
585+ async function watchConfigCallback (
586+ fileName : string ,
587+ kind : ts . FileWatcherEventKind ,
588+ modifiedTime : Date | undefined
589+ ) {
590+ if (
591+ kind === ts . FileWatcherEventKind . Changed &&
592+ ! configFileModified ( fileName , modifiedTime ?? tsSystem . getModifiedTime ?.( fileName ) )
593+ ) {
594+ return ;
595+ }
596+
583597 dispose ( ) ;
584598
585599 if ( kind === ts . FileWatcherEventKind . Changed ) {
@@ -651,7 +665,21 @@ function exceedsTotalSizeLimitForNonTsFiles(
651665 * So that GC won't drop it and cause memory leaks
652666 */
653667function createWatchExtendedConfigCallback ( docContext : LanguageServiceDocumentContext ) {
654- return async ( fileName : string ) => {
668+ return async (
669+ fileName : string ,
670+ kind : ts . FileWatcherEventKind ,
671+ modifiedTime : Date | undefined
672+ ) => {
673+ if (
674+ kind === ts . FileWatcherEventKind . Changed &&
675+ ! configFileModified (
676+ fileName ,
677+ modifiedTime ?? docContext . tsSystem . getModifiedTime ?.( fileName )
678+ )
679+ ) {
680+ return ;
681+ }
682+
655683 docContext . extendedConfigCache . delete ( fileName ) ;
656684
657685 const promises = Array . from ( extendedConfigToTsConfigPath . get ( fileName ) ?? [ ] ) . map (
@@ -667,6 +695,23 @@ function createWatchExtendedConfigCallback(docContext: LanguageServiceDocumentCo
667695 } ;
668696}
669697
698+ /**
699+ * check if file content is modified instead of attributes changed
700+ */
701+ function configFileModified ( fileName : string , modifiedTime : Date | undefined ) {
702+ const previousModifiedTime = configFileModifiedTime . get ( fileName ) ;
703+ if ( ! modifiedTime || ! previousModifiedTime ) {
704+ return true ;
705+ }
706+
707+ if ( previousModifiedTime >= modifiedTime ) {
708+ return false ;
709+ }
710+
711+ configFileModifiedTime . set ( fileName , modifiedTime ) ;
712+ return true ;
713+ }
714+
670715/**
671716 * schedule to the service reload to the next time the
672717 * service in requested
0 commit comments