11use itertools:: Itertools ;
2- use ra_ap_base_db:: { EditionedFileId , RootQueryDb , SourceDatabase } ;
2+ use ra_ap_base_db:: { EditionedFileId , FileText , RootQueryDb , SourceDatabase } ;
33use ra_ap_hir:: Semantics ;
44use ra_ap_ide_db:: RootDatabase ;
55use ra_ap_load_cargo:: { LoadCargoConfig , load_workspace_at} ;
66use ra_ap_paths:: { AbsPath , Utf8PathBuf } ;
77use ra_ap_project_model:: ProjectManifest ;
88use ra_ap_project_model:: { CargoConfig , ManifestPath } ;
99use ra_ap_span:: Edition ;
10- use ra_ap_span:: EditionedFileId as SpanEditionedFileId ;
1110use ra_ap_span:: TextRange ;
1211use ra_ap_span:: TextSize ;
1312use ra_ap_syntax:: SourceFile ;
@@ -54,7 +53,6 @@ impl<'a> RustAnalyzer<'a> {
5453 ) -> Option < ( RootDatabase , Vfs ) > {
5554 let progress = |t| ( trace ! ( "progress: {}" , t) ) ;
5655 let manifest = project. manifest_path ( ) ;
57-
5856 match load_workspace_at ( manifest. as_ref ( ) , config, load_config, & progress) {
5957 Ok ( ( db, vfs, _macro_server) ) => Some ( ( db, vfs) ) ,
6058 Err ( err) => {
@@ -66,67 +64,70 @@ impl<'a> RustAnalyzer<'a> {
6664 pub fn new ( vfs : & ' a Vfs , semantics : & ' a Semantics < ' a , RootDatabase > ) -> Self {
6765 RustAnalyzer :: WithSemantics { vfs, semantics }
6866 }
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 > {
7171 match self {
72+ RustAnalyzer :: WithoutSemantics { reason } => Err ( reason) ,
7273 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+ ) )
10785 }
10886 }
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+ }
118106 }
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) ;
121120
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+ }
130131 }
131132 }
132133}
0 commit comments