1
1
use std:: sync:: Arc ;
2
+ use std:: path:: Path ;
3
+ use std:: collections:: HashSet ;
4
+
5
+ use rustc_hash:: FxHashMap ;
2
6
3
7
use ra_db:: {
4
- FilePosition , FileId , CrateGraph , SourceRoot , SourceRootId , SourceDatabase , salsa,
8
+ CrateGraph , FileId , SourceRoot , SourceRootId , SourceDatabase , salsa,
5
9
} ;
6
10
use ra_hir:: { db, HirInterner } ;
11
+ use ra_project_model:: ProjectWorkspace ;
12
+ use ra_vfs:: { Vfs , VfsChange } ;
13
+
14
+ type Result < T > = std:: result:: Result < T , failure:: Error > ;
7
15
8
16
#[ salsa:: database(
9
17
ra_db:: SourceDatabaseStorage ,
10
18
db:: HirDatabaseStorage ,
11
19
db:: PersistentHirDatabaseStorage
12
20
) ]
13
21
#[ derive( Debug ) ]
14
- pub ( crate ) struct BatchDatabase {
22
+ pub struct BatchDatabase {
15
23
runtime : salsa:: Runtime < BatchDatabase > ,
16
24
interner : Arc < HirInterner > ,
17
- file_counter : u32 ,
25
+ // file_counter: u32,
18
26
}
19
27
20
28
impl salsa:: Database for BatchDatabase {
@@ -28,3 +36,88 @@ impl AsRef<HirInterner> for BatchDatabase {
28
36
& self . interner
29
37
}
30
38
}
39
+
40
+ fn vfs_file_to_id ( f : ra_vfs:: VfsFile ) -> FileId {
41
+ FileId ( f. 0 . into ( ) )
42
+ }
43
+ fn vfs_root_to_id ( r : ra_vfs:: VfsRoot ) -> SourceRootId {
44
+ SourceRootId ( r. 0 . into ( ) )
45
+ }
46
+
47
+ impl BatchDatabase {
48
+ pub fn load ( crate_graph : CrateGraph , vfs : & mut Vfs ) -> BatchDatabase {
49
+ let mut db =
50
+ BatchDatabase { runtime : salsa:: Runtime :: default ( ) , interner : Default :: default ( ) } ;
51
+ db. set_crate_graph ( Arc :: new ( crate_graph) ) ;
52
+
53
+ // wait until Vfs has loaded all roots
54
+ let receiver = vfs. task_receiver ( ) . clone ( ) ;
55
+ let mut roots_loaded = HashSet :: new ( ) ;
56
+ for task in receiver {
57
+ vfs. handle_task ( task) ;
58
+ let mut done = false ;
59
+ for change in vfs. commit_changes ( ) {
60
+ match change {
61
+ VfsChange :: AddRoot { root, files } => {
62
+ let source_root_id = vfs_root_to_id ( root) ;
63
+ log:: debug!( "loaded source root {:?} with path {:?}" , source_root_id, vfs. root2path( root) ) ;
64
+ let mut file_map = FxHashMap :: default ( ) ;
65
+ for ( vfs_file, path, text) in files {
66
+ let file_id = vfs_file_to_id ( vfs_file) ;
67
+ db. set_file_text ( file_id, text) ;
68
+ db. set_file_relative_path ( file_id, path. clone ( ) ) ;
69
+ db. set_file_source_root ( file_id, source_root_id) ;
70
+ file_map. insert ( path, file_id) ;
71
+ }
72
+ let source_root = SourceRoot { files : file_map } ;
73
+ db. set_source_root ( source_root_id, Arc :: new ( source_root) ) ;
74
+ roots_loaded. insert ( source_root_id) ;
75
+ if roots_loaded. len ( ) == vfs. num_roots ( ) {
76
+ done = true ;
77
+ }
78
+ }
79
+ VfsChange :: AddFile { .. }
80
+ | VfsChange :: RemoveFile { .. }
81
+ | VfsChange :: ChangeFile { .. } => {
82
+ // log::warn!("VFS changed while loading");
83
+ }
84
+ }
85
+ }
86
+ if done {
87
+ break ;
88
+ }
89
+ }
90
+
91
+ db
92
+ }
93
+
94
+ pub fn load_cargo ( root : impl AsRef < Path > ) -> Result < ( BatchDatabase , Vec < SourceRootId > ) > {
95
+ let root = root. as_ref ( ) . canonicalize ( ) ?;
96
+ let ws = ProjectWorkspace :: discover ( root. as_ref ( ) ) ?;
97
+ let mut roots = Vec :: new ( ) ;
98
+ roots. push ( root. clone ( ) ) ;
99
+ for pkg in ws. cargo . packages ( ) {
100
+ roots. push ( pkg. root ( & ws. cargo ) . to_path_buf ( ) ) ;
101
+ }
102
+ for krate in ws. sysroot . crates ( ) {
103
+ roots. push ( krate. root_dir ( & ws. sysroot ) . to_path_buf ( ) )
104
+ }
105
+ let ( mut vfs, roots) = Vfs :: new ( roots) ;
106
+ let mut load = |path : & Path | {
107
+ let vfs_file = vfs. load ( path) ;
108
+ log:: debug!( "vfs file {:?} -> {:?}" , path, vfs_file) ;
109
+ vfs_file. map ( vfs_file_to_id)
110
+ } ;
111
+ let crate_graph = ws. to_crate_graph ( & mut load) ;
112
+ log:: debug!( "crate graph: {:?}" , crate_graph) ;
113
+
114
+ let local_roots = roots. into_iter ( )
115
+ . filter ( |r| vfs. root2path ( * r) . starts_with ( & root) )
116
+ . map ( vfs_root_to_id)
117
+ . collect ( ) ;
118
+
119
+ let db = BatchDatabase :: load ( crate_graph, & mut vfs) ;
120
+ let _ = vfs. shutdown ( ) ;
121
+ Ok ( ( db, local_roots) )
122
+ }
123
+ }
0 commit comments