@@ -17,7 +17,7 @@ import (
17
17
"github.com/microsoft/typescript-go/internal/vfs/iovfs"
18
18
)
19
19
20
- type mapFS struct {
20
+ type MapFS struct {
21
21
// mu protects m.
22
22
// A single mutex is sufficient as we only use fstest.Map's Open method.
23
23
mu sync.RWMutex
@@ -53,8 +53,8 @@ func (t *Time) SinceStart() time.Duration {
53
53
}
54
54
55
55
var (
56
- _ iovfs.RealpathFS = (* mapFS )(nil )
57
- _ iovfs.WritableFS = (* mapFS )(nil )
56
+ _ iovfs.RealpathFS = (* MapFS )(nil )
57
+ _ iovfs.WritableFS = (* MapFS )(nil )
58
58
)
59
59
60
60
type sys struct {
@@ -79,7 +79,7 @@ func FromMap[File any](m map[string]File, useCaseSensitiveFileNames bool) vfs.FS
79
79
// The paths must be normalized absolute paths according to the tspath package,
80
80
// without trailing directory separators.
81
81
// The paths must be all POSIX-style or all Windows-style, but not both.
82
- func FromMapWithTime [File any ](m map [string ]File , useCaseSensitiveFileNames bool ) (vfs. FS , * Time ) {
82
+ func FromMapWithTime [File any ](m map [string ]File , useCaseSensitiveFileNames bool ) (iovfs. FsWithSys , * Time ) {
83
83
posix := false
84
84
windows := false
85
85
timeImpl := & Time {start : time .Now ()}
@@ -142,8 +142,8 @@ func FromMapWithTime[File any](m map[string]File, useCaseSensitiveFileNames bool
142
142
return iovfs .From (convertMapFS (mfs , useCaseSensitiveFileNames , timeImpl ), useCaseSensitiveFileNames ), timeImpl
143
143
}
144
144
145
- func convertMapFS (input fstest.MapFS , useCaseSensitiveFileNames bool , timeImpl * Time ) * mapFS {
146
- m := & mapFS {
145
+ func convertMapFS (input fstest.MapFS , useCaseSensitiveFileNames bool , timeImpl * Time ) * MapFS {
146
+ m := & MapFS {
147
147
m : make (fstest.MapFS , len (input )),
148
148
useCaseSensitiveFileNames : useCaseSensitiveFileNames ,
149
149
timeImpl : timeImpl ,
@@ -202,15 +202,15 @@ func comparePathsByParts(a, b string) int {
202
202
203
203
type canonicalPath string
204
204
205
- func (m * mapFS ) getCanonicalPath (p string ) canonicalPath {
205
+ func (m * MapFS ) getCanonicalPath (p string ) canonicalPath {
206
206
return canonicalPath (tspath .GetCanonicalFileName (p , m .useCaseSensitiveFileNames ))
207
207
}
208
208
209
- func (m * mapFS ) open (p canonicalPath ) (fs.File , error ) {
209
+ func (m * MapFS ) open (p canonicalPath ) (fs.File , error ) {
210
210
return m .m .Open (string (p ))
211
211
}
212
212
213
- func (m * mapFS ) remove (path string ) error {
213
+ func (m * MapFS ) remove (path string ) error {
214
214
canonical := m .getCanonicalPath (path )
215
215
canonicalString := string (canonical )
216
216
fileInfo := m .m [canonicalString ]
@@ -240,7 +240,7 @@ func Symlink(target string) *fstest.MapFile {
240
240
}
241
241
}
242
242
243
- func (m * mapFS ) getFollowingSymlinks (p canonicalPath ) (* fstest.MapFile , canonicalPath , error ) {
243
+ func (m * MapFS ) getFollowingSymlinks (p canonicalPath ) (* fstest.MapFile , canonicalPath , error ) {
244
244
return m .getFollowingSymlinksWorker (p , "" , "" )
245
245
}
246
246
@@ -252,7 +252,7 @@ func (e *brokenSymlinkError) Error() string {
252
252
return fmt .Sprintf ("broken symlink %q -> %q" , e .from , e .to )
253
253
}
254
254
255
- func (m * mapFS ) getFollowingSymlinksWorker (p canonicalPath , symlinkFrom , symlinkTo canonicalPath ) (* fstest.MapFile , canonicalPath , error ) {
255
+ func (m * MapFS ) getFollowingSymlinksWorker (p canonicalPath , symlinkFrom , symlinkTo canonicalPath ) (* fstest.MapFile , canonicalPath , error ) {
256
256
if file , ok := m .m [string (p )]; ok && file .Mode & fs .ModeSymlink == 0 {
257
257
return file , p , nil
258
258
}
@@ -275,11 +275,11 @@ func (m *mapFS) getFollowingSymlinksWorker(p canonicalPath, symlinkFrom, symlink
275
275
return nil , p , err
276
276
}
277
277
278
- func (m * mapFS ) set (p canonicalPath , file * fstest.MapFile ) {
278
+ func (m * MapFS ) set (p canonicalPath , file * fstest.MapFile ) {
279
279
m .m [string (p )] = file
280
280
}
281
281
282
- func (m * mapFS ) setEntry (realpath string , canonical canonicalPath , file fstest.MapFile ) {
282
+ func (m * MapFS ) setEntry (realpath string , canonical canonicalPath , file fstest.MapFile ) {
283
283
if realpath == "" || canonical == "" {
284
284
panic ("empty path" )
285
285
}
@@ -316,7 +316,7 @@ func baseName(p string) string {
316
316
return file
317
317
}
318
318
319
- func (m * mapFS ) mkdirAll (p string , perm fs.FileMode ) error {
319
+ func (m * MapFS ) mkdirAll (p string , perm fs.FileMode ) error {
320
320
if p == "" {
321
321
panic ("empty path" )
322
322
}
@@ -419,7 +419,7 @@ func (f *readDirFile) ReadDir(n int) ([]fs.DirEntry, error) {
419
419
return entries , nil
420
420
}
421
421
422
- func (m * mapFS ) Open (name string ) (fs.File , error ) {
422
+ func (m * MapFS ) Open (name string ) (fs.File , error ) {
423
423
m .mu .RLock ()
424
424
defer m .mu .RUnlock ()
425
425
@@ -461,7 +461,7 @@ func (m *mapFS) Open(name string) (fs.File, error) {
461
461
}, nil
462
462
}
463
463
464
- func (m * mapFS ) Realpath (name string ) (string , error ) {
464
+ func (m * MapFS ) Realpath (name string ) (string , error ) {
465
465
m .mu .RLock ()
466
466
defer m .mu .RUnlock ()
467
467
@@ -486,14 +486,14 @@ func convertInfo(info fs.FileInfo) (*fileInfo, bool) {
486
486
487
487
const umask = 0o022
488
488
489
- func (m * mapFS ) MkdirAll (path string , perm fs.FileMode ) error {
489
+ func (m * MapFS ) MkdirAll (path string , perm fs.FileMode ) error {
490
490
m .mu .Lock ()
491
491
defer m .mu .Unlock ()
492
492
493
493
return m .mkdirAll (path , perm )
494
494
}
495
495
496
- func (m * mapFS ) WriteFile (path string , data []byte , perm fs.FileMode ) error {
496
+ func (m * MapFS ) WriteFile (path string , data []byte , perm fs.FileMode ) error {
497
497
m .mu .Lock ()
498
498
defer m .mu .Unlock ()
499
499
@@ -530,14 +530,14 @@ func (m *mapFS) WriteFile(path string, data []byte, perm fs.FileMode) error {
530
530
return nil
531
531
}
532
532
533
- func (m * mapFS ) Remove (path string ) error {
533
+ func (m * MapFS ) Remove (path string ) error {
534
534
m .mu .Lock ()
535
535
defer m .mu .Unlock ()
536
536
537
537
return m .remove (path )
538
538
}
539
539
540
- func (m * mapFS ) Chtimes (path string , aTime time.Time , mTime time.Time ) error {
540
+ func (m * MapFS ) Chtimes (path string , aTime time.Time , mTime time.Time ) error {
541
541
m .mu .Lock ()
542
542
defer m .mu .Unlock ()
543
543
canonical := m .getCanonicalPath (path )
@@ -551,6 +551,20 @@ func (m *mapFS) Chtimes(path string, aTime time.Time, mTime time.Time) error {
551
551
return nil
552
552
}
553
553
554
+ func (m * MapFS ) GetTargetOfSymlink (path string ) (string , bool ) {
555
+ path , _ = strings .CutPrefix (path , "/" )
556
+ m .mu .RLock ()
557
+ defer m .mu .RUnlock ()
558
+ canonical := m .getCanonicalPath (path )
559
+ canonicalString := string (canonical )
560
+ if fileInfo , ok := m .m [canonicalString ]; ok {
561
+ if fileInfo .Mode & fs .ModeSymlink != 0 {
562
+ return "/" + string (fileInfo .Data ), true
563
+ }
564
+ }
565
+ return "" , false
566
+ }
567
+
554
568
func must [T any ](v T , err error ) T {
555
569
if err != nil {
556
570
panic (err )
0 commit comments