1
- use crate :: config:: Config ;
2
- use anyhow:: Context ;
3
1
use itertools:: Itertools ;
4
2
use log:: info;
5
3
use ra_ap_base_db:: SourceDatabase ;
@@ -9,6 +7,7 @@ use ra_ap_ide_db::RootDatabase;
9
7
use ra_ap_load_cargo:: { load_workspace_at, LoadCargoConfig , ProcMacroServerChoice } ;
10
8
use ra_ap_paths:: Utf8PathBuf ;
11
9
use ra_ap_project_model:: CargoConfig ;
10
+ use ra_ap_project_model:: ProjectManifest ;
12
11
use ra_ap_project_model:: RustLibSource ;
13
12
use ra_ap_span:: Edition ;
14
13
use ra_ap_span:: EditionedFileId ;
@@ -20,19 +19,18 @@ use ra_ap_vfs::AbsPathBuf;
20
19
use ra_ap_vfs:: Vfs ;
21
20
use ra_ap_vfs:: VfsPath ;
22
21
use std:: borrow:: Cow ;
23
- use std:: collections:: HashMap ;
24
22
use std:: path:: { Path , PathBuf } ;
25
23
use triomphe:: Arc ;
26
- pub struct RustAnalyzer {
27
- workspace : HashMap < PathBuf , ( Vfs , RootDatabase ) > ,
24
+ pub enum RustAnalyzer {
25
+ WithDatabase { db : RootDatabase , vfs : Vfs } ,
26
+ WithoutDatabase ( ) ,
28
27
}
29
28
30
29
impl RustAnalyzer {
31
- pub fn new ( cfg : & Config ) -> anyhow:: Result < RustAnalyzer > {
32
- let mut workspace = HashMap :: new ( ) ;
30
+ pub fn new ( project : & ProjectManifest , scratch_dir : & Path ) -> Self {
33
31
let config = CargoConfig {
34
32
sysroot : Some ( RustLibSource :: Discover ) ,
35
- target_dir : ra_ap_paths:: Utf8PathBuf :: from_path_buf ( cfg . scratch_dir . to_path_buf ( ) )
33
+ target_dir : ra_ap_paths:: Utf8PathBuf :: from_path_buf ( scratch_dir. to_path_buf ( ) )
36
34
. map ( |x| x. join ( "target" ) )
37
35
. ok ( ) ,
38
36
..Default :: default ( )
@@ -43,25 +41,19 @@ impl RustAnalyzer {
43
41
with_proc_macro_server : ProcMacroServerChoice :: Sysroot ,
44
42
prefill_caches : false ,
45
43
} ;
46
- let projects = find_project_manifests ( & cfg. inputs ) . context ( "loading inputs" ) ?;
47
- for project in projects {
48
- let manifest = project. manifest_path ( ) ;
44
+ let manifest = project. manifest_path ( ) ;
49
45
50
- match load_workspace_at ( manifest. as_ref ( ) , & config, & load_config, & progress) {
51
- Ok ( ( db, vfs, _macro_server) ) => {
52
- let path: & Path = manifest. parent ( ) . as_ref ( ) ;
53
- workspace. insert ( path. to_path_buf ( ) , ( vfs, db) ) ;
54
- }
55
- Err ( err) => {
56
- log:: error!( "failed to load workspace for {}: {}" , manifest, err) ;
57
- }
46
+ match load_workspace_at ( manifest. as_ref ( ) , & config, & load_config, & progress) {
47
+ Ok ( ( db, vfs, _macro_server) ) => RustAnalyzer :: WithDatabase { db, vfs } ,
48
+ Err ( err) => {
49
+ log:: error!( "failed to load workspace for {}: {}" , manifest, err) ;
50
+ RustAnalyzer :: WithoutDatabase ( )
58
51
}
59
52
}
60
- Ok ( RustAnalyzer { workspace } )
61
53
}
62
54
pub fn parse (
63
55
& mut self ,
64
- path : & PathBuf ,
56
+ path : & Path ,
65
57
) -> (
66
58
SourceFile ,
67
59
Arc < str > ,
@@ -82,37 +74,30 @@ impl RustAnalyzer {
82
74
} ;
83
75
let ( input, err) = from_utf8_lossy ( & input) ;
84
76
85
- let mut p = path. as_path ( ) ;
86
- while let Some ( parent) = p. parent ( ) {
87
- p = parent;
88
- if self . workspace . contains_key ( parent) {
89
- let ( vfs, db) = self . workspace . get_mut ( parent) . unwrap ( ) ;
90
- if let Some ( file_id) = Utf8PathBuf :: from_path_buf ( path. to_path_buf ( ) )
91
- . ok ( )
92
- . and_then ( |x| AbsPathBuf :: try_from ( x) . ok ( ) )
93
- . map ( VfsPath :: from)
94
- . and_then ( |x| vfs. file_id ( & x) )
95
- {
96
- db. set_file_text ( file_id, & input) ;
97
- let semi = Semantics :: new ( db) ;
77
+ if let RustAnalyzer :: WithDatabase { vfs, db } = self {
78
+ if let Some ( file_id) = Utf8PathBuf :: from_path_buf ( path. to_path_buf ( ) )
79
+ . ok ( )
80
+ . and_then ( |x| AbsPathBuf :: try_from ( x) . ok ( ) )
81
+ . map ( VfsPath :: from)
82
+ . and_then ( |x| vfs. file_id ( & x) )
83
+ {
84
+ db. set_file_text ( file_id, & input) ;
85
+ let semi = Semantics :: new ( db) ;
98
86
99
- let file_id = EditionedFileId :: current_edition ( file_id) ;
100
- let source_file = semi. parse ( file_id) ;
101
- errors. extend (
102
- db. parse_errors ( file_id)
103
- . into_iter ( )
104
- . flat_map ( |x| x. to_vec ( ) ) ,
105
- ) ;
106
- return (
107
- source_file,
108
- input. as_ref ( ) . into ( ) ,
109
- errors,
110
- Some ( file_id) ,
111
- Some ( semi) ,
112
- ) ;
113
- } else {
114
- break ;
115
- }
87
+ let file_id = EditionedFileId :: current_edition ( file_id) ;
88
+ let source_file = semi. parse ( file_id) ;
89
+ errors. extend (
90
+ db. parse_errors ( file_id)
91
+ . into_iter ( )
92
+ . flat_map ( |x| x. to_vec ( ) ) ,
93
+ ) ;
94
+ return (
95
+ source_file,
96
+ input. as_ref ( ) . into ( ) ,
97
+ errors,
98
+ Some ( file_id) ,
99
+ Some ( semi) ,
100
+ ) ;
116
101
}
117
102
}
118
103
let parse = ra_ap_syntax:: ast:: SourceFile :: parse ( & input, Edition :: CURRENT ) ;
@@ -122,7 +107,7 @@ impl RustAnalyzer {
122
107
}
123
108
}
124
109
125
- fn find_project_manifests (
110
+ pub fn find_project_manifests (
126
111
files : & [ PathBuf ] ,
127
112
) -> anyhow:: Result < Vec < ra_ap_project_model:: ProjectManifest > > {
128
113
let current = std:: env:: current_dir ( ) ?;
0 commit comments