Skip to content

Commit b6c26de

Browse files
committed
Rust: create single Semantics object for each workspace
1 parent 57cdda3 commit b6c26de

File tree

3 files changed

+65
-42
lines changed

3 files changed

+65
-42
lines changed

rust/extractor/src/main.rs

Lines changed: 13 additions & 7 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};
@@ -29,7 +30,6 @@ 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();
@@ -41,7 +41,7 @@ fn extract(
4141
label,
4242
line_index,
4343
file_id,
44-
semantics,
44+
rust_analyzer.semantics(),
4545
);
4646

4747
for err in errors {
@@ -112,14 +112,20 @@ fn main() -> anyhow::Result<()> {
112112
if files.is_empty() {
113113
break;
114114
}
115-
let mut rust_analyzer = RustAnalyzer::new(manifest, &cfg.scratch_dir);
116-
for file in files {
117-
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(db, 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::WithoutDatabase(), &archiver, &traps, file);
124+
}
118125
}
119126
}
120-
let mut rust_analyzer = RustAnalyzer::WithoutDatabase();
121127
for file in other_files {
122-
extract(&mut rust_analyzer, &archiver, &traps, file);
128+
extract(&RustAnalyzer::WithoutDatabase(), &archiver, &traps, file);
123129
}
124130

125131
Ok(())

rust/extractor/src/rust_analyzer.rs

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,25 @@ use ra_ap_vfs::VfsPath;
2020
use std::borrow::Cow;
2121
use std::path::{Path, PathBuf};
2222
use triomphe::Arc;
23-
pub enum RustAnalyzer {
24-
WithDatabase { db: RootDatabase, vfs: Vfs },
23+
pub enum RustAnalyzer<'a> {
24+
WithDatabase {
25+
db: &'a RootDatabase,
26+
vfs: &'a Vfs,
27+
semantics: Semantics<'a, RootDatabase>,
28+
},
2529
WithoutDatabase(),
2630
}
27-
pub struct ParseResult<'a> {
31+
pub struct ParseResult {
2832
pub ast: SourceFile,
2933
pub text: Arc<str>,
3034
pub errors: Vec<SyntaxError>,
3135
pub file_id: Option<EditionedFileId>,
32-
pub semantics: Option<Semantics<'a, RootDatabase>>,
3336
}
34-
impl RustAnalyzer {
35-
pub fn new(project: &ProjectManifest, scratch_dir: &Path) -> Self {
37+
impl<'a> RustAnalyzer<'a> {
38+
pub fn load_workspace(
39+
project: &ProjectManifest,
40+
scratch_dir: &Path,
41+
) -> Option<(RootDatabase, Vfs)> {
3642
let config = CargoConfig {
3743
sysroot: Some(RustLibSource::Discover),
3844
target_dir: ra_ap_paths::Utf8PathBuf::from_path_buf(scratch_dir.to_path_buf())
@@ -49,52 +55,64 @@ impl RustAnalyzer {
4955
let manifest = project.manifest_path();
5056

5157
match load_workspace_at(manifest.as_ref(), &config, &load_config, &progress) {
52-
Ok((db, vfs, _macro_server)) => RustAnalyzer::WithDatabase { db, vfs },
58+
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
5359
Err(err) => {
5460
log::error!("failed to load workspace for {}: {}", manifest, err);
55-
RustAnalyzer::WithoutDatabase()
61+
None
5662
}
5763
}
5864
}
59-
pub fn parse(&self, path: &Path) -> ParseResult<'_> {
60-
let mut errors = Vec::new();
61-
let input = match std::fs::read(path) {
62-
Ok(data) => data,
63-
Err(e) => {
64-
errors.push(SyntaxError::new(
65-
format!("Could not read {}: {}", path.to_string_lossy(), e),
66-
TextRange::empty(TextSize::default()),
67-
));
68-
vec![]
69-
}
70-
};
71-
let (input, err) = from_utf8_lossy(&input);
72-
73-
if let RustAnalyzer::WithDatabase { vfs, db } = self {
65+
pub fn new(db: &'a RootDatabase, vfs: &'a Vfs, semantics: Semantics<'a, RootDatabase>) -> Self {
66+
RustAnalyzer::WithDatabase { db, vfs, semantics }
67+
}
68+
pub fn semantics(&'a self) -> Option<&'a Semantics<'a, RootDatabase>> {
69+
match self {
70+
RustAnalyzer::WithDatabase {
71+
db: _,
72+
vfs: _,
73+
semantics,
74+
} => Some(semantics),
75+
RustAnalyzer::WithoutDatabase() => None,
76+
}
77+
}
78+
pub fn parse(&self, path: &Path) -> ParseResult {
79+
if let RustAnalyzer::WithDatabase { vfs, db, semantics } = self {
7480
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
7581
.ok()
7682
.and_then(|x| AbsPathBuf::try_from(x).ok())
7783
.map(VfsPath::from)
7884
.and_then(|x| vfs.file_id(&x))
7985
{
80-
let semantics = Semantics::new(db);
81-
86+
let input: Arc<str> = db.file_text(file_id);
8287
let file_id = EditionedFileId::current_edition(file_id);
8388
let source_file = semantics.parse(file_id);
84-
errors.extend(
85-
db.parse_errors(file_id)
86-
.into_iter()
87-
.flat_map(|x| x.to_vec()),
88-
);
89+
let errors = db
90+
.parse_errors(file_id)
91+
.into_iter()
92+
.flat_map(|x| x.to_vec())
93+
.collect();
94+
8995
return ParseResult {
9096
ast: source_file,
91-
text: input.as_ref().into(),
97+
text: input,
9298
errors,
9399
file_id: Some(file_id),
94-
semantics: Some(semantics),
95100
};
96101
}
97102
}
103+
let mut errors = Vec::new();
104+
let input = match std::fs::read(path) {
105+
Ok(data) => data,
106+
Err(e) => {
107+
errors.push(SyntaxError::new(
108+
format!("Could not read {}: {}", path.to_string_lossy(), e),
109+
TextRange::empty(TextSize::default()),
110+
));
111+
vec![]
112+
}
113+
};
114+
let (input, err) = from_utf8_lossy(&input);
115+
98116
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
99117
errors.extend(parse.errors());
100118
errors.extend(err);
@@ -103,7 +121,6 @@ impl RustAnalyzer {
103121
text: input.as_ref().into(),
104122
errors,
105123
file_id: None,
106-
semantics: None,
107124
}
108125
}
109126
}

rust/extractor/src/translate/base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub struct Translator<'a> {
8282
label: trap::Label,
8383
line_index: LineIndex,
8484
file_id: Option<EditionedFileId>,
85-
pub semantics: Option<Semantics<'a, RootDatabase>>,
85+
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
8686
}
8787

8888
impl<'a> Translator<'a> {
@@ -92,7 +92,7 @@ impl<'a> Translator<'a> {
9292
label: trap::Label,
9393
line_index: LineIndex,
9494
file_id: Option<EditionedFileId>,
95-
semantics: Option<Semantics<'a, RootDatabase>>,
95+
semantics: Option<&'a Semantics<'a, RootDatabase>>,
9696
) -> Translator<'a> {
9797
Translator {
9898
trap,

0 commit comments

Comments
 (0)