1
1
use itertools:: Itertools ;
2
- use ra_ap_base_db:: { EditionedFileId , RootQueryDb , SourceDatabase } ;
2
+ use ra_ap_base_db:: { EditionedFileId , FileText , RootQueryDb , SourceDatabase } ;
3
3
use ra_ap_hir:: Semantics ;
4
4
use ra_ap_ide_db:: RootDatabase ;
5
5
use ra_ap_load_cargo:: { LoadCargoConfig , load_workspace_at} ;
6
6
use ra_ap_paths:: { AbsPath , Utf8PathBuf } ;
7
7
use ra_ap_project_model:: ProjectManifest ;
8
8
use ra_ap_project_model:: { CargoConfig , ManifestPath } ;
9
9
use ra_ap_span:: Edition ;
10
- use ra_ap_span:: EditionedFileId as SpanEditionedFileId ;
11
10
use ra_ap_span:: TextRange ;
12
11
use ra_ap_span:: TextSize ;
13
12
use ra_ap_syntax:: SourceFile ;
@@ -54,7 +53,6 @@ impl<'a> RustAnalyzer<'a> {
54
53
) -> Option < ( RootDatabase , Vfs ) > {
55
54
let progress = |t| ( trace ! ( "progress: {}" , t) ) ;
56
55
let manifest = project. manifest_path ( ) ;
57
-
58
56
match load_workspace_at ( manifest. as_ref ( ) , config, load_config, & progress) {
59
57
Ok ( ( db, vfs, _macro_server) ) => Some ( ( db, vfs) ) ,
60
58
Err ( err) => {
@@ -66,67 +64,70 @@ impl<'a> RustAnalyzer<'a> {
66
64
pub fn new ( vfs : & ' a Vfs , semantics : & ' a Semantics < ' a , RootDatabase > ) -> Self {
67
65
RustAnalyzer :: WithSemantics { vfs, semantics }
68
66
}
69
- pub fn parse ( & self , path : & Path ) -> ParseResult {
70
- let no_semantics_reason;
67
+ fn get_file_data (
68
+ & self ,
69
+ path : & Path ,
70
+ ) -> Result < ( & Semantics < RootDatabase > , EditionedFileId , FileText ) , & str > {
71
71
match self {
72
+ RustAnalyzer :: WithoutSemantics { reason } => Err ( reason) ,
72
73
RustAnalyzer :: WithSemantics { vfs, semantics } => {
73
- if let Some ( file_id) = path_to_file_id ( path, vfs) {
74
- if let Ok ( input) = std:: panic:: catch_unwind ( || semantics. db . file_text ( file_id) )
75
- {
76
- let file_id = EditionedFileId :: new (
77
- semantics. db ,
78
- SpanEditionedFileId :: current_edition ( file_id) ,
79
- ) ;
80
- let source_file = semantics. parse ( file_id) ;
81
- let errors = semantics
82
- . db
83
- . parse_errors ( file_id)
84
- . into_iter ( )
85
- . flat_map ( |x| x. to_vec ( ) )
86
- . collect ( ) ;
87
-
88
- return ParseResult {
89
- ast : source_file,
90
- text : input. text ( semantics. db ) ,
91
- errors,
92
- semantics_info : Ok ( FileSemanticInformation { file_id, semantics } ) ,
93
- } ;
94
- }
95
- debug ! (
96
- "No text available for file_id '{:?}', falling back to loading file '{}' from disk." ,
97
- file_id,
98
- path. to_string_lossy( )
99
- ) ;
100
- no_semantics_reason = "no text available for the file in the project" ;
101
- } else {
102
- no_semantics_reason = "file not found in project" ;
103
- }
104
- }
105
- RustAnalyzer :: WithoutSemantics { reason } => {
106
- no_semantics_reason = reason;
74
+ let file_id = path_to_file_id ( path, vfs) . ok_or ( "file not found in project" ) ?;
75
+ let input = std:: panic:: catch_unwind ( || semantics. db . file_text ( file_id) )
76
+ . or ( Err ( "no text available for the file in the project" ) ) ?;
77
+ let editioned_file_id = semantics
78
+ . attach_first_edition ( file_id)
79
+ . ok_or ( "failed to determine rust edition" ) ?;
80
+ Ok ( (
81
+ semantics,
82
+ EditionedFileId :: new ( semantics. db , editioned_file_id) ,
83
+ input,
84
+ ) )
107
85
}
108
86
}
109
- let mut errors = Vec :: new ( ) ;
110
- let input = match std:: fs:: read ( path) {
111
- Ok ( data) => data,
112
- Err ( e) => {
113
- errors. push ( SyntaxError :: new (
114
- format ! ( "Could not read {}: {}" , path. to_string_lossy( ) , e) ,
115
- TextRange :: empty ( TextSize :: default ( ) ) ,
116
- ) ) ;
117
- vec ! [ ]
87
+ }
88
+
89
+ pub fn parse ( & self , path : & Path ) -> ParseResult {
90
+ match self . get_file_data ( path) {
91
+ Ok ( ( semantics, file_id, input) ) => {
92
+ let source_file = semantics. parse ( file_id) ;
93
+ let errors = semantics
94
+ . db
95
+ . parse_errors ( file_id)
96
+ . into_iter ( )
97
+ . flat_map ( |x| x. to_vec ( ) )
98
+ . collect ( ) ;
99
+
100
+ ParseResult {
101
+ ast : source_file,
102
+ text : input. text ( semantics. db ) ,
103
+ errors,
104
+ semantics_info : Ok ( FileSemanticInformation { file_id, semantics } ) ,
105
+ }
118
106
}
119
- } ;
120
- let ( input, err) = from_utf8_lossy ( & input) ;
107
+ Err ( reason) => {
108
+ let mut errors = Vec :: new ( ) ;
109
+ let input = match std:: fs:: read ( path) {
110
+ Ok ( data) => data,
111
+ Err ( e) => {
112
+ errors. push ( SyntaxError :: new (
113
+ format ! ( "Could not read {}: {}" , path. to_string_lossy( ) , e) ,
114
+ TextRange :: empty ( TextSize :: default ( ) ) ,
115
+ ) ) ;
116
+ vec ! [ ]
117
+ }
118
+ } ;
119
+ let ( input, err) = from_utf8_lossy ( & input) ;
121
120
122
- let parse = ra_ap_syntax:: ast:: SourceFile :: parse ( & input, Edition :: CURRENT ) ;
123
- errors. extend ( parse. errors ( ) ) ;
124
- errors. extend ( err) ;
125
- ParseResult {
126
- ast : parse. tree ( ) ,
127
- text : input. as_ref ( ) . into ( ) ,
128
- errors,
129
- semantics_info : Err ( no_semantics_reason) ,
121
+ let parse = ra_ap_syntax:: ast:: SourceFile :: parse ( & input, Edition :: CURRENT ) ;
122
+ errors. extend ( parse. errors ( ) ) ;
123
+ errors. extend ( err) ;
124
+ ParseResult {
125
+ ast : parse. tree ( ) ,
126
+ text : input. as_ref ( ) . into ( ) ,
127
+ errors,
128
+ semantics_info : Err ( reason) ,
129
+ }
130
+ }
130
131
}
131
132
}
132
133
}
0 commit comments