@@ -20,19 +20,25 @@ use ra_ap_vfs::VfsPath;
20
20
use std:: borrow:: Cow ;
21
21
use std:: path:: { Path , PathBuf } ;
22
22
use triomphe:: Arc ;
23
- pub enum RustAnalyzer {
24
- WithDatabase { db : RootDatabase , vfs : Vfs } ,
23
+ pub enum RustAnalyzer < ' a > {
24
+ WithDatabase {
25
+ db : & ' a RootDatabase ,
26
+ vfs : & ' a Vfs ,
27
+ semantics : Semantics < ' a , RootDatabase > ,
28
+ } ,
25
29
WithoutDatabase ( ) ,
26
30
}
27
- pub struct ParseResult < ' a > {
31
+ pub struct ParseResult {
28
32
pub ast : SourceFile ,
29
33
pub text : Arc < str > ,
30
34
pub errors : Vec < SyntaxError > ,
31
35
pub file_id : Option < EditionedFileId > ,
32
- pub semantics : Option < Semantics < ' a , RootDatabase > > ,
33
36
}
34
- impl RustAnalyzer {
35
- pub fn new ( project : & ProjectManifest , scratch_dir : & Path ) -> Self {
37
+ impl < ' a > RustAnalyzer < ' a > {
38
+ pub fn load_workspace (
39
+ project : & ProjectManifest ,
40
+ scratch_dir : & Path ,
41
+ ) -> Option < ( RootDatabase , Vfs ) > {
36
42
let config = CargoConfig {
37
43
sysroot : Some ( RustLibSource :: Discover ) ,
38
44
target_dir : ra_ap_paths:: Utf8PathBuf :: from_path_buf ( scratch_dir. to_path_buf ( ) )
@@ -49,52 +55,64 @@ impl RustAnalyzer {
49
55
let manifest = project. manifest_path ( ) ;
50
56
51
57
match load_workspace_at ( manifest. as_ref ( ) , & config, & load_config, & progress) {
52
- Ok ( ( db, vfs, _macro_server) ) => RustAnalyzer :: WithDatabase { db, vfs } ,
58
+ Ok ( ( db, vfs, _macro_server) ) => Some ( ( db, vfs) ) ,
53
59
Err ( err) => {
54
60
log:: error!( "failed to load workspace for {}: {}" , manifest, err) ;
55
- RustAnalyzer :: WithoutDatabase ( )
61
+ None
56
62
}
57
63
}
58
64
}
59
- pub fn parse ( & self , path : & Path ) -> ParseResult < ' _ > {
60
- let mut errors = Vec :: new ( ) ;
61
- let input = match std :: fs :: read ( path ) {
62
- Ok ( data ) => data ,
63
- Err ( e ) => {
64
- errors . push ( SyntaxError :: new (
65
- format ! ( "Could not read {}: {}" , path . to_string_lossy ( ) , e ) ,
66
- TextRange :: empty ( TextSize :: default ( ) ) ,
67
- ) ) ;
68
- vec ! [ ]
69
- }
70
- } ;
71
- let ( input , err ) = from_utf8_lossy ( & input ) ;
72
-
73
- if let RustAnalyzer :: WithDatabase { vfs, db } = self {
65
+ pub fn new ( db : & ' a RootDatabase , vfs : & ' a Vfs , semantics : Semantics < ' a , RootDatabase > ) -> Self {
66
+ RustAnalyzer :: WithDatabase { db , vfs , semantics }
67
+ }
68
+ pub fn semantics ( & ' a self ) -> Option < & ' a Semantics < ' a , RootDatabase > > {
69
+ match self {
70
+ RustAnalyzer :: WithDatabase {
71
+ db : _ ,
72
+ vfs : _ ,
73
+ semantics ,
74
+ } => Some ( semantics ) ,
75
+ RustAnalyzer :: WithoutDatabase ( ) => None ,
76
+ }
77
+ }
78
+ pub fn parse ( & self , path : & Path ) -> ParseResult {
79
+ if let RustAnalyzer :: WithDatabase { vfs, db, semantics } = self {
74
80
if let Some ( file_id) = Utf8PathBuf :: from_path_buf ( path. to_path_buf ( ) )
75
81
. ok ( )
76
82
. and_then ( |x| AbsPathBuf :: try_from ( x) . ok ( ) )
77
83
. map ( VfsPath :: from)
78
84
. and_then ( |x| vfs. file_id ( & x) )
79
85
{
80
- let semantics = Semantics :: new ( db) ;
81
-
86
+ let input: Arc < str > = db. file_text ( file_id) ;
82
87
let file_id = EditionedFileId :: current_edition ( file_id) ;
83
88
let source_file = semantics. parse ( file_id) ;
84
- errors. extend (
85
- db. parse_errors ( file_id)
86
- . into_iter ( )
87
- . flat_map ( |x| x. to_vec ( ) ) ,
88
- ) ;
89
+ let errors = db
90
+ . parse_errors ( file_id)
91
+ . into_iter ( )
92
+ . flat_map ( |x| x. to_vec ( ) )
93
+ . collect ( ) ;
94
+
89
95
return ParseResult {
90
96
ast : source_file,
91
- text : input. as_ref ( ) . into ( ) ,
97
+ text : input,
92
98
errors,
93
99
file_id : Some ( file_id) ,
94
- semantics : Some ( semantics) ,
95
100
} ;
96
101
}
97
102
}
103
+ let mut errors = Vec :: new ( ) ;
104
+ let input = match std:: fs:: read ( path) {
105
+ Ok ( data) => data,
106
+ Err ( e) => {
107
+ errors. push ( SyntaxError :: new (
108
+ format ! ( "Could not read {}: {}" , path. to_string_lossy( ) , e) ,
109
+ TextRange :: empty ( TextSize :: default ( ) ) ,
110
+ ) ) ;
111
+ vec ! [ ]
112
+ }
113
+ } ;
114
+ let ( input, err) = from_utf8_lossy ( & input) ;
115
+
98
116
let parse = ra_ap_syntax:: ast:: SourceFile :: parse ( & input, Edition :: CURRENT ) ;
99
117
errors. extend ( parse. errors ( ) ) ;
100
118
errors. extend ( err) ;
@@ -103,7 +121,6 @@ impl RustAnalyzer {
103
121
text : input. as_ref ( ) . into ( ) ,
104
122
errors,
105
123
file_id : None ,
106
- semantics : None ,
107
124
}
108
125
}
109
126
}
0 commit comments