Skip to content

Commit 714e2fc

Browse files
authored
Merge branch 'main' into rust-data-flow-consistency-query
2 parents 7f344fa + 2ae721b commit 714e2fc

File tree

3 files changed

+72
-52
lines changed

3 files changed

+72
-52
lines changed

rust/extractor/src/main.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use anyhow::Context;
22
use archive::Archiver;
33
use log::info;
4+
use ra_ap_hir::Semantics;
45
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
56
use ra_ap_project_model::ProjectManifest;
67
use rust_analyzer::{ParseResult, RustAnalyzer};
@@ -17,7 +18,7 @@ mod translate;
1718
pub mod trap;
1819

1920
fn extract(
20-
rust_analyzer: &mut rust_analyzer::RustAnalyzer,
21+
rust_analyzer: &rust_analyzer::RustAnalyzer,
2122
archiver: &Archiver,
2223
traps: &trap::TrapFileProvider,
2324
file: &std::path::Path,
@@ -29,23 +30,18 @@ fn extract(
2930
text,
3031
errors,
3132
file_id,
32-
semantics,
3333
} = rust_analyzer.parse(file);
3434
let line_index = LineIndex::new(text.as_ref());
3535
let display_path = file.to_string_lossy();
3636
let mut trap = traps.create("source", file);
37-
trap.writer.comment(format!(
38-
"semantics: {}",
39-
if semantics.is_some() { "yes" } else { "no" }
40-
));
4137
let label = trap.emit_file(file);
4238
let mut translator = translate::Translator::new(
4339
trap,
4440
display_path.as_ref(),
4541
label,
4642
line_index,
4743
file_id,
48-
semantics,
44+
file_id.and(rust_analyzer.semantics()),
4945
);
5046

5147
for err in errors {
@@ -116,14 +112,20 @@ fn main() -> anyhow::Result<()> {
116112
if files.is_empty() {
117113
break;
118114
}
119-
let mut rust_analyzer = RustAnalyzer::new(manifest, &cfg.scratch_dir);
120-
for file in files {
121-
extract(&mut rust_analyzer, &archiver, &traps, file);
115+
if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cfg.scratch_dir) {
116+
let semantics = Semantics::new(db);
117+
let rust_analyzer = RustAnalyzer::new(vfs, semantics);
118+
for file in files {
119+
extract(&rust_analyzer, &archiver, &traps, file);
120+
}
121+
} else {
122+
for file in files {
123+
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
124+
}
122125
}
123126
}
124-
let mut rust_analyzer = RustAnalyzer::WithoutDatabase();
125127
for file in other_files {
126-
extract(&mut rust_analyzer, &archiver, &traps, file);
128+
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
127129
}
128130

129131
Ok(())

rust/extractor/src/rust_analyzer.rs

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use itertools::Itertools;
22
use log::{debug, info};
33
use ra_ap_base_db::SourceDatabase;
4-
use ra_ap_base_db::SourceDatabaseFileInputExt;
54
use ra_ap_hir::Semantics;
65
use ra_ap_ide_db::RootDatabase;
76
use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
@@ -21,19 +20,24 @@ use ra_ap_vfs::VfsPath;
2120
use std::borrow::Cow;
2221
use std::path::{Path, PathBuf};
2322
use triomphe::Arc;
24-
pub enum RustAnalyzer {
25-
WithDatabase { db: RootDatabase, vfs: Vfs },
26-
WithoutDatabase(),
23+
pub enum RustAnalyzer<'a> {
24+
WithSemantics {
25+
vfs: &'a Vfs,
26+
semantics: Semantics<'a, RootDatabase>,
27+
},
28+
WithoutSemantics,
2729
}
28-
pub struct ParseResult<'a> {
30+
pub struct ParseResult {
2931
pub ast: SourceFile,
3032
pub text: Arc<str>,
3133
pub errors: Vec<SyntaxError>,
3234
pub file_id: Option<EditionedFileId>,
33-
pub semantics: Option<Semantics<'a, RootDatabase>>,
3435
}
35-
impl RustAnalyzer {
36-
pub fn new(project: &ProjectManifest, scratch_dir: &Path) -> Self {
36+
impl<'a> RustAnalyzer<'a> {
37+
pub fn load_workspace(
38+
project: &ProjectManifest,
39+
scratch_dir: &Path,
40+
) -> Option<(RootDatabase, Vfs)> {
3741
let config = CargoConfig {
3842
sysroot: Some(RustLibSource::Discover),
3943
target_dir: ra_ap_paths::Utf8PathBuf::from_path_buf(scratch_dir.to_path_buf())
@@ -50,14 +54,55 @@ impl RustAnalyzer {
5054
let manifest = project.manifest_path();
5155

5256
match load_workspace_at(manifest.as_ref(), &config, &load_config, &progress) {
53-
Ok((db, vfs, _macro_server)) => RustAnalyzer::WithDatabase { db, vfs },
57+
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
5458
Err(err) => {
5559
log::error!("failed to load workspace for {}: {}", manifest, err);
56-
RustAnalyzer::WithoutDatabase()
60+
None
5761
}
5862
}
5963
}
60-
pub fn parse(&mut self, path: &Path) -> ParseResult<'_> {
64+
pub fn new(vfs: &'a Vfs, semantics: Semantics<'a, RootDatabase>) -> Self {
65+
RustAnalyzer::WithSemantics { vfs, semantics }
66+
}
67+
pub fn semantics(&'a self) -> Option<&'a Semantics<'a, RootDatabase>> {
68+
match self {
69+
RustAnalyzer::WithSemantics { vfs: _, semantics } => Some(semantics),
70+
RustAnalyzer::WithoutSemantics => None,
71+
}
72+
}
73+
pub fn parse(&self, path: &Path) -> ParseResult {
74+
if let RustAnalyzer::WithSemantics { vfs, semantics } = self {
75+
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
76+
.ok()
77+
.and_then(|x| AbsPathBuf::try_from(x).ok())
78+
.map(VfsPath::from)
79+
.and_then(|x| vfs.file_id(&x))
80+
{
81+
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id)) {
82+
let file_id = EditionedFileId::current_edition(file_id);
83+
let source_file = semantics.parse(file_id);
84+
let errors = semantics
85+
.db
86+
.parse_errors(file_id)
87+
.into_iter()
88+
.flat_map(|x| x.to_vec())
89+
.collect();
90+
91+
return ParseResult {
92+
ast: source_file,
93+
text: input,
94+
errors,
95+
file_id: Some(file_id),
96+
};
97+
} else {
98+
log::debug!(
99+
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
100+
file_id,
101+
path.to_string_lossy()
102+
)
103+
}
104+
}
105+
}
61106
let mut errors = Vec::new();
62107
let input = match std::fs::read(path) {
63108
Ok(data) => data,
@@ -71,32 +116,6 @@ impl RustAnalyzer {
71116
};
72117
let (input, err) = from_utf8_lossy(&input);
73118

74-
if let RustAnalyzer::WithDatabase { vfs, db } = self {
75-
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
76-
.ok()
77-
.and_then(|x| AbsPathBuf::try_from(x).ok())
78-
.map(VfsPath::from)
79-
.and_then(|x| vfs.file_id(&x))
80-
{
81-
db.set_file_text(file_id, &input);
82-
let semantics = Semantics::new(db);
83-
84-
let file_id = EditionedFileId::current_edition(file_id);
85-
let source_file = semantics.parse(file_id);
86-
errors.extend(
87-
db.parse_errors(file_id)
88-
.into_iter()
89-
.flat_map(|x| x.to_vec()),
90-
);
91-
return ParseResult {
92-
ast: source_file,
93-
text: input.as_ref().into(),
94-
errors,
95-
file_id: Some(file_id),
96-
semantics: Some(semantics),
97-
};
98-
}
99-
}
100119
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
101120
errors.extend(parse.errors());
102121
errors.extend(err);
@@ -105,7 +124,6 @@ impl RustAnalyzer {
105124
text: input.as_ref().into(),
106125
errors,
107126
file_id: None,
108-
semantics: None,
109127
}
110128
}
111129
}

rust/extractor/src/translate/base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub struct Translator<'a> {
5555
label: trap::Label,
5656
line_index: LineIndex,
5757
file_id: Option<EditionedFileId>,
58-
pub semantics: Option<Semantics<'a, RootDatabase>>,
58+
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
5959
}
6060

6161
impl<'a> Translator<'a> {
@@ -65,7 +65,7 @@ impl<'a> Translator<'a> {
6565
label: trap::Label,
6666
line_index: LineIndex,
6767
file_id: Option<EditionedFileId>,
68-
semantics: Option<Semantics<'a, RootDatabase>>,
68+
semantics: Option<&'a Semantics<'a, RootDatabase>>,
6969
) -> Translator<'a> {
7070
Translator {
7171
trap,

0 commit comments

Comments
 (0)