Skip to content

Commit f1e45de

Browse files
committed
Rust: extract source files of depdendencies
1 parent e4b7b91 commit f1e45de

File tree

3 files changed

+93
-13
lines changed

3 files changed

+93
-13
lines changed

rust/extractor/src/main.rs

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::diagnostics::{ExtractionStep, emit_extraction_diagnostics};
22
use crate::rust_analyzer::path_to_file_id;
3-
use crate::translate::ResolvePaths;
3+
use crate::translate::{ResolvePaths, SourceKind};
44
use crate::trap::TrapId;
55
use anyhow::Context;
66
use archive::Archiver;
@@ -12,6 +12,7 @@ use ra_ap_paths::{AbsPathBuf, Utf8PathBuf};
1212
use ra_ap_project_model::{CargoConfig, ProjectManifest};
1313
use ra_ap_vfs::Vfs;
1414
use rust_analyzer::{ParseResult, RustAnalyzer};
15+
use std::collections::HashSet;
1516
use std::time::Instant;
1617
use std::{
1718
collections::HashMap,
@@ -47,9 +48,14 @@ impl<'a> Extractor<'a> {
4748
}
4849
}
4950

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+
) {
5158
self.archiver.archive(file);
52-
5359
let before_parse = Instant::now();
5460
let ParseResult {
5561
ast,
@@ -71,6 +77,7 @@ impl<'a> Extractor<'a> {
7177
line_index,
7278
semantics_info.as_ref().ok(),
7379
resolve_paths,
80+
source_kind,
7481
);
7582

7683
for err in errors {
@@ -110,15 +117,27 @@ impl<'a> Extractor<'a> {
110117
semantics: &Semantics<'_, RootDatabase>,
111118
vfs: &Vfs,
112119
resolve_paths: ResolvePaths,
120+
source_kind: SourceKind,
113121
) {
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+
);
115128
}
116129

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+
) {
118136
self.extract(
119137
&RustAnalyzer::WithoutSemantics { reason },
120138
file,
121139
ResolvePaths::No,
140+
source_kind,
122141
);
123142
}
124143

@@ -246,7 +265,7 @@ fn main() -> anyhow::Result<()> {
246265
continue 'outer;
247266
}
248267
}
249-
extractor.extract_without_semantics(file, "no manifest found");
268+
extractor.extract_without_semantics(file, SourceKind::Source, "no manifest found");
250269
}
251270
let cwd = cwd()?;
252271
let (cargo_config, load_cargo_config) = cfg.to_cargo_config(&cwd);
@@ -255,6 +274,7 @@ fn main() -> anyhow::Result<()> {
255274
} else {
256275
ResolvePaths::Yes
257276
};
277+
let mut processed_files = HashSet::new();
258278
for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) {
259279
if let Some((ref db, ref vfs)) =
260280
extractor.load_manifest(manifest, &cargo_config, &load_cargo_config)
@@ -266,16 +286,43 @@ fn main() -> anyhow::Result<()> {
266286
.push(ExtractionStep::crate_graph(before_crate_graph));
267287
let semantics = Semantics::new(db);
268288
for file in files {
289+
processed_files.insert((*file).to_owned());
269290
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)
272300
}
273-
Err(reason) => extractor.extract_without_semantics(file, &reason),
274301
};
275302
}
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+
}
276319
} else {
277320
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+
);
279326
}
280327
}
281328
}
@@ -286,7 +333,7 @@ fn main() -> anyhow::Result<()> {
286333
let entry = entry.context("failed to read builtins directory")?;
287334
let path = entry.path();
288335
if path.extension().is_some_and(|ext| ext == "rs") {
289-
extractor.extract_without_semantics(&path, "");
336+
extractor.extract_without_semantics(&path, SourceKind::Library, "");
290337
}
291338
}
292339

rust/extractor/src/translate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ mod base;
22
mod generated;
33
mod mappings;
44

5-
pub use base::{ResolvePaths, Translator};
5+
pub use base::{ResolvePaths, SourceKind, Translator};

rust/extractor/src/translate/base.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use ra_ap_ide_db::RootDatabase;
1616
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
1717
use ra_ap_parser::SyntaxKind;
1818
use ra_ap_span::TextSize;
19-
use ra_ap_syntax::ast::HasName;
19+
use ra_ap_syntax::ast::{Const, Fn, HasName, Static};
2020
use ra_ap_syntax::{
2121
AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxNode, SyntaxToken, TextRange,
2222
ast,
@@ -93,6 +93,11 @@ pub enum ResolvePaths {
9393
Yes,
9494
No,
9595
}
96+
#[derive(PartialEq, Eq)]
97+
pub enum SourceKind {
98+
Source,
99+
Library,
100+
}
96101

97102
pub struct Translator<'a> {
98103
pub trap: TrapFile,
@@ -102,6 +107,7 @@ pub struct Translator<'a> {
102107
file_id: Option<EditionedFileId>,
103108
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
104109
resolve_paths: ResolvePaths,
110+
source_kind: SourceKind,
105111
}
106112

107113
const UNKNOWN_LOCATION: (LineCol, LineCol) =
@@ -115,6 +121,7 @@ impl<'a> Translator<'a> {
115121
line_index: LineIndex,
116122
semantic_info: Option<&FileSemanticInformation<'a>>,
117123
resolve_paths: ResolvePaths,
124+
source_kind: SourceKind,
118125
) -> Translator<'a> {
119126
Translator {
120127
trap,
@@ -124,6 +131,7 @@ impl<'a> Translator<'a> {
124131
file_id: semantic_info.map(|i| i.file_id),
125132
semantics: semantic_info.map(|i| i.semantics),
126133
resolve_paths,
134+
source_kind,
127135
}
128136
}
129137
fn location(&self, range: TextRange) -> Option<(LineCol, LineCol)> {
@@ -612,6 +620,31 @@ impl<'a> Translator<'a> {
612620
}
613621

614622
pub(crate) fn should_be_excluded(&self, item: &impl ast::HasAttrs) -> bool {
623+
if self.source_kind == SourceKind::Library {
624+
let syntax = item.syntax();
625+
if let Some(body) = syntax.parent().and_then(Fn::cast).and_then(|x| x.body()) {
626+
if body.syntax() == syntax {
627+
tracing::debug!("Skipping Fn body");
628+
return true;
629+
}
630+
}
631+
if let Some(body) = syntax.parent().and_then(Const::cast).and_then(|x| x.body()) {
632+
if body.syntax() == syntax {
633+
tracing::debug!("Skipping Const body");
634+
return true;
635+
}
636+
}
637+
if let Some(body) = syntax
638+
.parent()
639+
.and_then(Static::cast)
640+
.and_then(|x| x.body())
641+
{
642+
if body.syntax() == syntax {
643+
tracing::debug!("Skipping Static body");
644+
return true;
645+
}
646+
}
647+
}
615648
self.semantics.is_some_and(|sema| {
616649
item.attrs().any(|attr| {
617650
attr.as_simple_call().is_some_and(|(name, tokens)| {

0 commit comments

Comments
 (0)