1
1
mod vfs_filter;
2
2
3
- use std:: { sync :: Arc , path:: Path , collections:: HashSet , error:: Error } ;
3
+ use std:: { path:: Path , collections:: HashSet , error:: Error } ;
4
4
5
5
use rustc_hash:: FxHashMap ;
6
6
7
7
use ra_db:: {
8
- CrateGraph , FileId , SourceRoot , SourceRootId , SourceDatabase , salsa :: { self , Database } ,
8
+ CrateGraph , FileId , SourceRootId ,
9
9
} ;
10
- use ra_hir :: db ;
10
+ use ra_ide_api :: { AnalysisHost , AnalysisChange } ;
11
11
use ra_project_model:: ProjectWorkspace ;
12
12
use ra_vfs:: { Vfs , VfsChange } ;
13
13
use vfs_filter:: IncludeRustFiles ;
14
14
15
15
type Result < T > = std:: result:: Result < T , Box < dyn Error + Send + Sync > > ;
16
16
17
- #[ salsa:: database(
18
- ra_db:: SourceDatabaseStorage ,
19
- db:: AstDatabaseStorage ,
20
- db:: DefDatabaseStorage ,
21
- db:: HirDatabaseStorage
22
- ) ]
23
- #[ derive( Debug ) ]
24
- pub struct BatchDatabase {
25
- runtime : salsa:: Runtime < BatchDatabase > ,
26
- }
27
-
28
- impl salsa:: Database for BatchDatabase {
29
- fn salsa_runtime ( & self ) -> & salsa:: Runtime < BatchDatabase > {
30
- & self . runtime
31
- }
32
- }
33
-
34
17
fn vfs_file_to_id ( f : ra_vfs:: VfsFile ) -> FileId {
35
18
FileId ( f. 0 )
36
19
}
37
20
fn vfs_root_to_id ( r : ra_vfs:: VfsRoot ) -> SourceRootId {
38
21
SourceRootId ( r. 0 )
39
22
}
40
23
41
- impl BatchDatabase {
42
- pub fn load ( crate_graph : CrateGraph , vfs : & mut Vfs ) -> BatchDatabase {
43
- let mut db = BatchDatabase { runtime : salsa:: Runtime :: default ( ) } ;
44
- let lru_cap = std:: env:: var ( "RA_LRU_CAP" )
45
- . ok ( )
46
- . and_then ( |it| it. parse :: < usize > ( ) . ok ( ) )
47
- . unwrap_or ( ra_db:: DEFAULT_LRU_CAP ) ;
48
- db. query_mut ( ra_db:: ParseQuery ) . set_lru_capacity ( lru_cap) ;
49
- db. query_mut ( ra_hir:: db:: ParseMacroQuery ) . set_lru_capacity ( lru_cap) ;
50
- db. set_crate_graph ( Arc :: new ( crate_graph) ) ;
24
+ pub fn load_cargo ( root : & Path ) -> Result < ( AnalysisHost , Vec < SourceRootId > ) > {
25
+ let root = std:: env:: current_dir ( ) ?. join ( root) ;
26
+ let ws = ProjectWorkspace :: discover ( root. as_ref ( ) ) ?;
27
+ let mut roots = Vec :: new ( ) ;
28
+ roots. push ( IncludeRustFiles :: member ( root. clone ( ) ) ) ;
29
+ roots. extend ( IncludeRustFiles :: from_roots ( ws. to_roots ( ) ) ) ;
30
+ let ( mut vfs, roots) = Vfs :: new ( roots) ;
31
+ let crate_graph = ws. to_crate_graph ( & mut |path : & Path | {
32
+ let vfs_file = vfs. load ( path) ;
33
+ log:: debug!( "vfs file {:?} -> {:?}" , path, vfs_file) ;
34
+ vfs_file. map ( vfs_file_to_id)
35
+ } ) ;
36
+ log:: debug!( "crate graph: {:?}" , crate_graph) ;
37
+
38
+ let local_roots = roots
39
+ . into_iter ( )
40
+ . filter ( |r| vfs. root2path ( * r) . starts_with ( & root) )
41
+ . map ( vfs_root_to_id)
42
+ . collect ( ) ;
43
+
44
+ let host = load ( root. as_path ( ) , crate_graph, & mut vfs) ;
45
+ Ok ( ( host, local_roots) )
46
+ }
51
47
52
- // wait until Vfs has loaded all roots
53
- let receiver = vfs . task_receiver ( ) . clone ( ) ;
54
- let mut roots_loaded = HashSet :: new ( ) ;
55
- for task in receiver {
56
- vfs . handle_task ( task ) ;
57
- let mut done = false ;
58
- for change in vfs . commit_changes ( ) {
59
- match change {
60
- VfsChange :: AddRoot { root , files } => {
61
- let source_root_id = vfs_root_to_id ( root ) ;
62
- log :: debug! (
63
- "loaded source root {:?} with path {:?}" ,
64
- source_root_id ,
65
- vfs . root2path ( root )
66
- ) ;
67
- let mut file_map = FxHashMap :: default ( ) ;
68
- for ( vfs_file , path , text ) in files {
69
- let file_id = vfs_file_to_id ( vfs_file ) ;
70
- db . set_file_text ( file_id , text ) ;
71
- db . set_file_relative_path ( file_id , path . clone ( ) ) ;
72
- db . set_file_source_root ( file_id , source_root_id ) ;
73
- file_map . insert ( path , file_id ) ;
74
- }
75
- let source_root = SourceRoot { files : file_map } ;
76
- db . set_source_root ( source_root_id , Arc :: new ( source_root ) ) ;
77
- roots_loaded . insert ( source_root_id ) ;
78
- if roots_loaded . len ( ) == vfs . n_roots ( ) {
79
- done = true ;
80
- }
48
+ pub fn load ( project_root : & Path , crate_graph : CrateGraph , vfs : & mut Vfs ) -> AnalysisHost {
49
+ let lru_cap = std :: env :: var ( "RA_LRU_CAP" ) . ok ( ) . and_then ( |it| it . parse :: < usize > ( ) . ok ( ) ) ;
50
+ let mut host = AnalysisHost :: new ( lru_cap ) ;
51
+ let mut analysis_change = AnalysisChange :: new ( ) ;
52
+ analysis_change . set_crate_graph ( crate_graph ) ;
53
+
54
+ // wait until Vfs has loaded all roots
55
+ let receiver = vfs . task_receiver ( ) . clone ( ) ;
56
+ let mut roots_loaded = HashSet :: new ( ) ;
57
+ for task in receiver {
58
+ vfs . handle_task ( task ) ;
59
+ let mut done = false ;
60
+ for change in vfs . commit_changes ( ) {
61
+ match change {
62
+ VfsChange :: AddRoot { root , files } => {
63
+ let is_local = vfs . root2path ( root ) . starts_with ( & project_root ) ;
64
+ let source_root_id = vfs_root_to_id ( root ) ;
65
+ log :: debug! (
66
+ "loaded source root {:?} with path {:?}" ,
67
+ source_root_id ,
68
+ vfs . root2path ( root )
69
+ ) ;
70
+ analysis_change . add_root ( source_root_id , is_local ) ;
71
+
72
+ let mut file_map = FxHashMap :: default ( ) ;
73
+ for ( vfs_file , path , text ) in files {
74
+ let file_id = vfs_file_to_id ( vfs_file ) ;
75
+ analysis_change . add_file ( source_root_id , file_id , path . clone ( ) , text ) ;
76
+ file_map . insert ( path , file_id ) ;
81
77
}
82
- VfsChange :: AddFile { .. }
83
- | VfsChange :: RemoveFile { .. }
84
- | VfsChange :: ChangeFile { .. } => {
85
- // We just need the first scan, so just ignore these
78
+ roots_loaded. insert ( source_root_id) ;
79
+ if roots_loaded. len ( ) == vfs. n_roots ( ) {
80
+ done = true ;
86
81
}
87
82
}
88
- }
89
- if done {
90
- break ;
83
+ VfsChange :: AddFile { .. }
84
+ | VfsChange :: RemoveFile { .. }
85
+ | VfsChange :: ChangeFile { .. } => {
86
+ // We just need the first scan, so just ignore these
87
+ }
91
88
}
92
89
}
93
-
94
- db
90
+ if done {
91
+ break ;
92
+ }
95
93
}
96
94
97
- pub fn load_cargo ( root : impl AsRef < Path > ) -> Result < ( BatchDatabase , Vec < SourceRootId > ) > {
98
- let root = std:: env:: current_dir ( ) ?. join ( root) ;
99
- let ws = ProjectWorkspace :: discover ( root. as_ref ( ) ) ?;
100
- let mut roots = Vec :: new ( ) ;
101
- roots. push ( IncludeRustFiles :: member ( root. clone ( ) ) ) ;
102
- roots. extend ( IncludeRustFiles :: from_roots ( ws. to_roots ( ) ) ) ;
103
- let ( mut vfs, roots) = Vfs :: new ( roots) ;
104
- let mut load = |path : & Path | {
105
- let vfs_file = vfs. load ( path) ;
106
- log:: debug!( "vfs file {:?} -> {:?}" , path, vfs_file) ;
107
- vfs_file. map ( vfs_file_to_id)
108
- } ;
109
- let crate_graph = ws. to_crate_graph ( & mut load) ;
110
- log:: debug!( "crate graph: {:?}" , crate_graph) ;
111
-
112
- let local_roots = roots
113
- . into_iter ( )
114
- . filter ( |r| vfs. root2path ( * r) . starts_with ( & root) )
115
- . map ( vfs_root_to_id)
116
- . collect ( ) ;
117
-
118
- let db = BatchDatabase :: load ( crate_graph, & mut vfs) ;
119
- Ok ( ( db, local_roots) )
120
- }
95
+ host. apply_change ( analysis_change) ;
96
+ host
121
97
}
122
98
123
99
#[ cfg( test) ]
@@ -128,10 +104,10 @@ mod tests {
128
104
#[ test]
129
105
fn test_loading_rust_analyzer ( ) {
130
106
let path = Path :: new ( env ! ( "CARGO_MANIFEST_DIR" ) ) . parent ( ) . unwrap ( ) . parent ( ) . unwrap ( ) ;
131
- let ( db , roots) = BatchDatabase :: load_cargo ( path) . unwrap ( ) ;
107
+ let ( host , roots) = load_cargo ( path) . unwrap ( ) ;
132
108
let mut n_crates = 0 ;
133
109
for root in roots {
134
- for _krate in Crate :: source_root_crates ( & db , root) {
110
+ for _krate in Crate :: source_root_crates ( host . raw_database ( ) , root) {
135
111
n_crates += 1 ;
136
112
}
137
113
}
0 commit comments