1
1
use crate :: diagnostics:: { ExtractionStep , emit_extraction_diagnostics} ;
2
2
use crate :: rust_analyzer:: path_to_file_id;
3
- use crate :: translate:: ResolvePaths ;
3
+ use crate :: translate:: { ResolvePaths , SourceKind } ;
4
4
use crate :: trap:: TrapId ;
5
5
use anyhow:: Context ;
6
6
use archive:: Archiver ;
@@ -12,6 +12,7 @@ use ra_ap_paths::{AbsPathBuf, Utf8PathBuf};
12
12
use ra_ap_project_model:: { CargoConfig , ProjectManifest } ;
13
13
use ra_ap_vfs:: Vfs ;
14
14
use rust_analyzer:: { ParseResult , RustAnalyzer } ;
15
+ use std:: collections:: HashSet ;
15
16
use std:: time:: Instant ;
16
17
use std:: {
17
18
collections:: HashMap ,
@@ -47,9 +48,14 @@ impl<'a> Extractor<'a> {
47
48
}
48
49
}
49
50
50
- fn extract ( & mut self , rust_analyzer : & RustAnalyzer , file : & Path , resolve_paths : ResolvePaths ) {
51
+ fn extract (
52
+ & mut self ,
53
+ rust_analyzer : & RustAnalyzer ,
54
+ file : & Path ,
55
+ resolve_paths : ResolvePaths ,
56
+ source_kind : SourceKind ,
57
+ ) {
51
58
self . archiver . archive ( file) ;
52
-
53
59
let before_parse = Instant :: now ( ) ;
54
60
let ParseResult {
55
61
ast,
@@ -71,6 +77,7 @@ impl<'a> Extractor<'a> {
71
77
line_index,
72
78
semantics_info. as_ref ( ) . ok ( ) ,
73
79
resolve_paths,
80
+ source_kind,
74
81
) ;
75
82
76
83
for err in errors {
@@ -110,15 +117,27 @@ impl<'a> Extractor<'a> {
110
117
semantics : & Semantics < ' _ , RootDatabase > ,
111
118
vfs : & Vfs ,
112
119
resolve_paths : ResolvePaths ,
120
+ source_kind : SourceKind ,
113
121
) {
114
- self . extract ( & RustAnalyzer :: new ( vfs, semantics) , file, resolve_paths) ;
122
+ self . extract (
123
+ & RustAnalyzer :: new ( vfs, semantics) ,
124
+ file,
125
+ resolve_paths,
126
+ source_kind,
127
+ ) ;
115
128
}
116
129
117
- pub fn extract_without_semantics ( & mut self , file : & Path , reason : & str ) {
130
+ pub fn extract_without_semantics (
131
+ & mut self ,
132
+ file : & Path ,
133
+ source_kind : SourceKind ,
134
+ reason : & str ,
135
+ ) {
118
136
self . extract (
119
137
& RustAnalyzer :: WithoutSemantics { reason } ,
120
138
file,
121
139
ResolvePaths :: No ,
140
+ source_kind,
122
141
) ;
123
142
}
124
143
@@ -246,7 +265,7 @@ fn main() -> anyhow::Result<()> {
246
265
continue ' outer;
247
266
}
248
267
}
249
- extractor. extract_without_semantics ( file, "no manifest found" ) ;
268
+ extractor. extract_without_semantics ( file, SourceKind :: Source , "no manifest found" ) ;
250
269
}
251
270
let cwd = cwd ( ) ?;
252
271
let ( cargo_config, load_cargo_config) = cfg. to_cargo_config ( & cwd) ;
@@ -255,6 +274,7 @@ fn main() -> anyhow::Result<()> {
255
274
} else {
256
275
ResolvePaths :: Yes
257
276
} ;
277
+ let mut processed_files = HashSet :: new ( ) ;
258
278
for ( manifest, files) in map. values ( ) . filter ( |( _, files) | !files. is_empty ( ) ) {
259
279
if let Some ( ( ref db, ref vfs) ) =
260
280
extractor. load_manifest ( manifest, & cargo_config, & load_cargo_config)
@@ -266,16 +286,43 @@ fn main() -> anyhow::Result<()> {
266
286
. push ( ExtractionStep :: crate_graph ( before_crate_graph) ) ;
267
287
let semantics = Semantics :: new ( db) ;
268
288
for file in files {
289
+ processed_files. insert ( ( * file) . to_owned ( ) ) ;
269
290
match extractor. load_source ( file, & semantics, vfs) {
270
- Ok ( ( ) ) => {
271
- extractor. extract_with_semantics ( file, & semantics, vfs, resolve_paths)
291
+ Ok ( ( ) ) => extractor. extract_with_semantics (
292
+ file,
293
+ & semantics,
294
+ vfs,
295
+ resolve_paths,
296
+ SourceKind :: Source ,
297
+ ) ,
298
+ Err ( reason) => {
299
+ extractor. extract_without_semantics ( file, SourceKind :: Source , & reason)
272
300
}
273
- Err ( reason) => extractor. extract_without_semantics ( file, & reason) ,
274
301
} ;
275
302
}
303
+ for ( _, file) in vfs. iter ( ) {
304
+ if let Some ( file) = file. as_path ( ) . map ( <_ as AsRef < Path > >:: as_ref) {
305
+ if file. extension ( ) . is_some_and ( |ext| ext == "rs" )
306
+ && processed_files. insert ( file. to_owned ( ) )
307
+ {
308
+ extractor. extract_with_semantics (
309
+ file,
310
+ & semantics,
311
+ vfs,
312
+ resolve_paths,
313
+ SourceKind :: Library ,
314
+ ) ;
315
+ extractor. archiver . archive ( file) ;
316
+ }
317
+ }
318
+ }
276
319
} else {
277
320
for file in files {
278
- extractor. extract_without_semantics ( file, "unable to load manifest" ) ;
321
+ extractor. extract_without_semantics (
322
+ file,
323
+ SourceKind :: Source ,
324
+ "unable to load manifest" ,
325
+ ) ;
279
326
}
280
327
}
281
328
}
@@ -286,7 +333,7 @@ fn main() -> anyhow::Result<()> {
286
333
let entry = entry. context ( "failed to read builtins directory" ) ?;
287
334
let path = entry. path ( ) ;
288
335
if path. extension ( ) . is_some_and ( |ext| ext == "rs" ) {
289
- extractor. extract_without_semantics ( & path, "" ) ;
336
+ extractor. extract_without_semantics ( & path, SourceKind :: Library , "" ) ;
290
337
}
291
338
}
292
339
0 commit comments