@@ -3,7 +3,7 @@ use rayon::prelude::*;
3
3
use solar_ast:: { self as ast, Span } ;
4
4
use solar_data_structures:: {
5
5
index:: { Idx , IndexVec } ,
6
- map:: FxHashSet ,
6
+ map:: { FxHashMap , FxHashSet } ,
7
7
sync:: Mutex ,
8
8
} ;
9
9
use solar_interface:: {
@@ -413,7 +413,8 @@ fn path_from_bytes(bytes: &[u8]) -> Option<&Path> {
413
413
/// Sources.
414
414
#[ derive( Default ) ]
415
415
pub struct Sources < ' ast > {
416
- pub sources : IndexVec < SourceId , Source < ' ast > > ,
416
+ sources : IndexVec < SourceId , Source < ' ast > > ,
417
+ file_to_id : FxHashMap < Arc < SourceFile > , SourceId > ,
417
418
}
418
419
419
420
impl fmt:: Debug for Sources < ' _ > {
@@ -426,7 +427,60 @@ impl fmt::Debug for Sources<'_> {
426
427
impl < ' ast > Sources < ' ast > {
427
428
/// Creates a new empty list of parsed sources.
428
429
pub fn new ( ) -> Self {
429
- Self { sources : IndexVec :: new ( ) }
430
+ Self :: default ( )
431
+ }
432
+
433
+ /// Returns a reference to the source, if it exists.
434
+ #[ inline]
435
+ pub fn get ( & self , id : SourceId ) -> Option < & Source < ' ast > > {
436
+ self . sources . get ( id)
437
+ }
438
+
439
+ /// Returns a mutable reference to the source, if it exists.
440
+ #[ inline]
441
+ pub fn get_mut ( & mut self , id : SourceId ) -> Option < & mut Source < ' ast > > {
442
+ self . sources . get_mut ( id)
443
+ }
444
+
445
+ /// Returns the ID of the source file, if it exists.
446
+ pub fn get_file ( & self , file : & Arc < SourceFile > ) -> Option < ( SourceId , & Source < ' ast > ) > {
447
+ self . file_to_id . get ( file) . map ( |& id| ( id, & self . sources [ id] ) )
448
+ }
449
+
450
+ /// Returns the ID of the source file, if it exists.
451
+ pub fn get_file_mut (
452
+ & mut self ,
453
+ file : & Arc < SourceFile > ,
454
+ ) -> Option < ( SourceId , & mut Source < ' ast > ) > {
455
+ self . file_to_id . get ( file) . map ( |& id| ( id, & mut self . sources [ id] ) )
456
+ }
457
+
458
+ /// Returns the ID of the given file, or inserts it if it doesn't exist.
459
+ ///
460
+ /// Returns `true` if the file was newly inserted.
461
+ #[ instrument( level = "debug" , skip_all) ]
462
+ pub fn get_or_insert_file ( & mut self , file : Arc < SourceFile > ) -> ( SourceId , bool ) {
463
+ let mut new = false ;
464
+ let id = * self . file_to_id . entry ( file) . or_insert_with_key ( |file| {
465
+ new = true ;
466
+ self . sources . push ( Source :: new ( file. clone ( ) ) )
467
+ } ) ;
468
+ ( id, new)
469
+ }
470
+
471
+ /// Removes the given file from the sources.
472
+ pub fn remove_file ( & mut self , file : & Arc < SourceFile > ) -> Option < Source < ' ast > > {
473
+ self . file_to_id . remove ( file) . map ( |id| self . sources . remove ( id) )
474
+ }
475
+
476
+ /// Returns an iterator over all the ASTs.
477
+ pub fn asts ( & self ) -> impl DoubleEndedIterator < Item = & ast:: SourceUnit < ' ast > > {
478
+ self . sources . iter ( ) . filter_map ( |source| source. ast . as_ref ( ) )
479
+ }
480
+
481
+ /// Returns a parallel iterator over all the ASTs.
482
+ pub fn par_asts ( & self ) -> impl ParallelIterator < Item = & ast:: SourceUnit < ' ast > > {
483
+ self . sources . as_raw_slice ( ) . par_iter ( ) . filter_map ( |source| source. ast . as_ref ( ) )
430
484
}
431
485
432
486
fn count_parsed ( & self ) -> usize {
@@ -455,28 +509,6 @@ impl<'ast> Sources<'ast> {
455
509
ret
456
510
}
457
511
458
- #[ instrument( level = "debug" , skip_all) ]
459
- fn get_or_insert_file ( & mut self , file : Arc < SourceFile > ) -> ( SourceId , bool ) {
460
- if let Some ( ( id, _) ) = self . get_file ( & file) {
461
- return ( id, false ) ;
462
- }
463
- ( self . sources . push ( Source :: new ( file) ) , true )
464
- }
465
-
466
- /// Returns the ID of the source file, if it exists.
467
- pub fn get_file ( & self , file : & Arc < SourceFile > ) -> Option < ( SourceId , & Source < ' ast > ) > {
468
- self . sources . iter_enumerated ( ) . find ( |( _, source) | Arc :: ptr_eq ( & source. file , file) )
469
- }
470
-
471
- /// Returns the ID of the source file, if it exists.
472
- pub fn get_file_mut (
473
- & mut self ,
474
- file : & Arc < SourceFile > ,
475
- ) -> Option < ( SourceId , & mut Source < ' ast > ) > {
476
- let ( id, _) = self . get_file ( file) ?;
477
- Some ( ( id, & mut self . sources [ id] ) )
478
- }
479
-
480
512
/// Asserts that all sources are unique.
481
513
fn assert_unique ( & self ) {
482
514
if self . sources . len ( ) <= 1 {
@@ -490,16 +522,6 @@ impl<'ast> Sources<'ast> {
490
522
) ;
491
523
}
492
524
493
- /// Returns an iterator over all the ASTs.
494
- pub fn asts ( & self ) -> impl DoubleEndedIterator < Item = & ast:: SourceUnit < ' ast > > {
495
- self . sources . iter ( ) . filter_map ( |source| source. ast . as_ref ( ) )
496
- }
497
-
498
- /// Returns a parallel iterator over all the ASTs.
499
- pub fn par_asts ( & self ) -> impl ParallelIterator < Item = & ast:: SourceUnit < ' ast > > {
500
- self . sources . as_raw_slice ( ) . par_iter ( ) . filter_map ( |source| source. ast . as_ref ( ) )
501
- }
502
-
503
525
/// Sorts the sources topologically in-place. Invalidates all source IDs.
504
526
#[ instrument( level = "debug" , skip_all) ]
505
527
pub fn topo_sort ( & mut self ) {
0 commit comments