11/// <reference path="core.ts"/>
22
33namespace ts {
4- export type FileWatcherCallback = ( path : string , removed ?: boolean ) => void ;
5- export type DirectoryWatcherCallback = ( path : string ) => void ;
4+ export type FileWatcherCallback = ( fileName : string , removed ?: boolean ) => void ;
5+ export type DirectoryWatcherCallback = ( directoryName : string ) => void ;
66
77 export interface System {
88 args : string [ ] ;
@@ -12,7 +12,7 @@ namespace ts {
1212 readFile ( path : string , encoding ?: string ) : string ;
1313 getFileSize ?( path : string ) : number ;
1414 writeFile ( path : string , data : string , writeByteOrderMark ?: boolean ) : void ;
15- watchFile ?( path : Path , callback : FileWatcherCallback ) : FileWatcher ;
15+ watchFile ?( path : string , callback : FileWatcherCallback ) : FileWatcher ;
1616 watchDirectory ?( path : string , callback : DirectoryWatcherCallback , recursive ?: boolean ) : FileWatcher ;
1717 resolvePath ( path : string ) : string ;
1818 fileExists ( path : string ) : boolean ;
@@ -27,7 +27,7 @@ namespace ts {
2727 }
2828
2929 interface WatchedFile {
30- filePath : Path ;
30+ fileName : string ;
3131 callback : FileWatcherCallback ;
3232 mtime ?: Date ;
3333 }
@@ -37,7 +37,7 @@ namespace ts {
3737 }
3838
3939 export interface DirectoryWatcher extends FileWatcher {
40- directoryPath : Path ;
40+ directoryName : string ;
4141 referenceCount : number ;
4242 }
4343
@@ -246,13 +246,13 @@ namespace ts {
246246 return ;
247247 }
248248
249- _fs . stat ( watchedFile . filePath , ( err : any , stats : any ) => {
249+ _fs . stat ( watchedFile . fileName , ( err : any , stats : any ) => {
250250 if ( err ) {
251- watchedFile . callback ( watchedFile . filePath ) ;
251+ watchedFile . callback ( watchedFile . fileName ) ;
252252 }
253253 else if ( watchedFile . mtime . getTime ( ) !== stats . mtime . getTime ( ) ) {
254- watchedFile . mtime = getModifiedTime ( watchedFile . filePath ) ;
255- watchedFile . callback ( watchedFile . filePath , watchedFile . mtime . getTime ( ) === 0 ) ;
254+ watchedFile . mtime = getModifiedTime ( watchedFile . fileName ) ;
255+ watchedFile . callback ( watchedFile . fileName , watchedFile . mtime . getTime ( ) === 0 ) ;
256256 }
257257 } ) ;
258258 }
@@ -280,11 +280,11 @@ namespace ts {
280280 } , interval ) ;
281281 }
282282
283- function addFile ( filePath : Path , callback : FileWatcherCallback ) : WatchedFile {
283+ function addFile ( fileName : string , callback : FileWatcherCallback ) : WatchedFile {
284284 const file : WatchedFile = {
285- filePath ,
285+ fileName ,
286286 callback,
287- mtime : getModifiedTime ( filePath )
287+ mtime : getModifiedTime ( fileName )
288288 } ;
289289
290290 watchedFiles . push ( file ) ;
@@ -308,26 +308,26 @@ namespace ts {
308308 }
309309
310310 function createWatchedFileSet ( ) {
311- const dirWatchers = createFileMap < DirectoryWatcher > ( ) ;
311+ const dirWatchers : Map < DirectoryWatcher > = { } ;
312312 // One file can have multiple watchers
313- const fileWatcherCallbacks = createFileMap < FileWatcherCallback [ ] > ( ) ;
313+ const fileWatcherCallbacks : Map < FileWatcherCallback [ ] > = { } ;
314314 return { addFile, removeFile } ;
315315
316- function reduceDirWatcherRefCountForFile ( filePath : Path ) {
317- const dirPath = getDirectoryPath ( filePath ) ;
318- if ( dirWatchers . contains ( dirPath ) ) {
319- const watcher = dirWatchers . get ( dirPath ) ;
316+ function reduceDirWatcherRefCountForFile ( fileName : string ) {
317+ const dirName = getDirectoryPath ( fileName ) ;
318+ if ( hasProperty ( dirWatchers , dirName ) ) {
319+ const watcher = dirWatchers [ dirName ] ;
320320 watcher . referenceCount -= 1 ;
321321 if ( watcher . referenceCount <= 0 ) {
322322 watcher . close ( ) ;
323- dirWatchers . remove ( dirPath ) ;
323+ delete dirWatchers [ dirName ] ;
324324 }
325325 }
326326 }
327327
328- function addDirWatcher ( dirPath : Path ) : void {
329- if ( dirWatchers . contains ( dirPath ) ) {
330- const watcher = dirWatchers . get ( dirPath ) ;
328+ function addDirWatcher ( dirPath : string ) : void {
329+ if ( hasProperty ( dirWatchers , dirPath ) ) {
330+ const watcher = dirWatchers [ dirPath ] ;
331331 watcher . referenceCount += 1 ;
332332 return ;
333333 }
@@ -338,52 +338,52 @@ namespace ts {
338338 ( eventName : string , relativeFileName : string ) => fileEventHandler ( eventName , relativeFileName , dirPath )
339339 ) ;
340340 watcher . referenceCount = 1 ;
341- dirWatchers . set ( dirPath , watcher ) ;
341+ dirWatchers [ dirPath ] = watcher ;
342342 return ;
343343 }
344344
345- function addFileWatcherCallback ( filePath : Path , callback : FileWatcherCallback ) : void {
346- if ( fileWatcherCallbacks . contains ( filePath ) ) {
347- fileWatcherCallbacks . get ( filePath ) . push ( callback ) ;
345+ function addFileWatcherCallback ( filePath : string , callback : FileWatcherCallback ) : void {
346+ if ( hasProperty ( fileWatcherCallbacks , filePath ) ) {
347+ fileWatcherCallbacks [ filePath ] . push ( callback ) ;
348348 }
349349 else {
350- fileWatcherCallbacks . set ( filePath , [ callback ] ) ;
350+ fileWatcherCallbacks [ filePath ] = [ callback ] ;
351351 }
352352 }
353353
354- function addFile ( filePath : Path , callback : FileWatcherCallback ) : WatchedFile {
355- addFileWatcherCallback ( filePath , callback ) ;
356- addDirWatcher ( getDirectoryPath ( filePath ) ) ;
354+ function addFile ( fileName : string , callback : FileWatcherCallback ) : WatchedFile {
355+ addFileWatcherCallback ( fileName , callback ) ;
356+ addDirWatcher ( getDirectoryPath ( fileName ) ) ;
357357
358- return { filePath , callback } ;
358+ return { fileName , callback } ;
359359 }
360360
361361 function removeFile ( watchedFile : WatchedFile ) {
362- removeFileWatcherCallback ( watchedFile . filePath , watchedFile . callback ) ;
363- reduceDirWatcherRefCountForFile ( watchedFile . filePath ) ;
362+ removeFileWatcherCallback ( watchedFile . fileName , watchedFile . callback ) ;
363+ reduceDirWatcherRefCountForFile ( watchedFile . fileName ) ;
364364 }
365365
366- function removeFileWatcherCallback ( filePath : Path , callback : FileWatcherCallback ) {
367- if ( fileWatcherCallbacks . contains ( filePath ) ) {
368- const newCallbacks = copyListRemovingItem ( callback , fileWatcherCallbacks . get ( filePath ) ) ;
366+ function removeFileWatcherCallback ( filePath : string , callback : FileWatcherCallback ) {
367+ if ( hasProperty ( fileWatcherCallbacks , filePath ) ) {
368+ const newCallbacks = copyListRemovingItem ( callback , fileWatcherCallbacks [ filePath ] ) ;
369369 if ( newCallbacks . length === 0 ) {
370- fileWatcherCallbacks . remove ( filePath ) ;
370+ delete fileWatcherCallbacks [ filePath ] ;
371371 }
372372 else {
373- fileWatcherCallbacks . set ( filePath , newCallbacks ) ;
373+ fileWatcherCallbacks [ filePath ] = newCallbacks ;
374374 }
375375 }
376376 }
377377
378- function fileEventHandler ( eventName : string , relativeFileName : string , baseDirPath : Path ) {
378+ function fileEventHandler ( eventName : string , relativeFileName : string , baseDirPath : string ) {
379379 // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
380- const filePath = typeof relativeFileName !== "string"
380+ const fileName = typeof relativeFileName !== "string"
381381 ? undefined
382- : toPath ( relativeFileName , baseDirPath , createGetCanonicalFileName ( sys . useCaseSensitiveFileNames ) ) ;
382+ : ts . getNormalizedAbsolutePath ( relativeFileName , baseDirPath ) ;
383383 // Some applications save a working file via rename operations
384- if ( ( eventName === "change" || eventName === "rename" ) && fileWatcherCallbacks . contains ( filePath ) ) {
385- for ( const fileCallback of fileWatcherCallbacks . get ( filePath ) ) {
386- fileCallback ( filePath ) ;
384+ if ( ( eventName === "change" || eventName === "rename" ) && hasProperty ( fileWatcherCallbacks , fileName ) ) {
385+ for ( const fileCallback of fileWatcherCallbacks [ fileName ] ) {
386+ fileCallback ( fileName ) ;
387387 }
388388 }
389389 }
@@ -495,6 +495,11 @@ namespace ts {
495495 const files = _fs . readdirSync ( path || "." ) . sort ( ) ;
496496 const directories : string [ ] = [ ] ;
497497 for ( const current of files ) {
498+ // This is necessary because on some file system node fails to exclude
499+ // "." and "..". See https://github.com/nodejs/node/issues/4002
500+ if ( current === "." || current === ".." ) {
501+ continue ;
502+ }
498503 const name = combinePaths ( path , current ) ;
499504 if ( ! contains ( exclude , getCanonicalPath ( name ) ) ) {
500505 // fs.statSync would throw an exception if the file is a symlink
@@ -553,18 +558,18 @@ namespace ts {
553558 } ,
554559 readFile,
555560 writeFile,
556- watchFile : ( filePath , callback ) => {
561+ watchFile : ( fileName , callback ) => {
557562 // Node 4.0 stabilized the `fs.watch` function on Windows which avoids polling
558563 // and is more efficient than `fs.watchFile` (ref: https://github.com/nodejs/node/pull/2649
559564 // and https://github.com/Microsoft/TypeScript/issues/4643), therefore
560565 // if the current node.js version is newer than 4, use `fs.watch` instead.
561566 const watchSet = isNode4OrLater ( ) ? watchedFileSet : pollingWatchedFileSet ;
562- const watchedFile = watchSet . addFile ( filePath , callback ) ;
567+ const watchedFile = watchSet . addFile ( fileName , callback ) ;
563568 return {
564569 close : ( ) => watchSet . removeFile ( watchedFile )
565570 } ;
566571 } ,
567- watchDirectory : ( path , callback , recursive ) => {
572+ watchDirectory : ( directoryName , callback , recursive ) => {
568573 // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
569574 // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
570575 let options : any ;
@@ -576,15 +581,15 @@ namespace ts {
576581 }
577582
578583 return _fs . watch (
579- path ,
584+ directoryName ,
580585 options ,
581586 ( eventName : string , relativeFileName : string ) => {
582587 // In watchDirectory we only care about adding and removing files (when event name is
583588 // "rename"); changes made within files are handled by corresponding fileWatchers (when
584589 // event name is "change")
585590 if ( eventName === "rename" ) {
586591 // When deleting a file, the passed baseFileName is null
587- callback ( ! relativeFileName ? relativeFileName : normalizePath ( combinePaths ( path , relativeFileName ) ) ) ;
592+ callback ( ! relativeFileName ? relativeFileName : normalizePath ( combinePaths ( directoryName , relativeFileName ) ) ) ;
588593 } ;
589594 }
590595 ) ;
0 commit comments