Skip to content

Commit 2babbbb

Browse files
bors[bot]matklad
andcommitted
Merge #784
784: WIP: improve multi-crate fixtures r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents b60ccac + 9923383 commit 2babbbb

File tree

3 files changed

+146
-116
lines changed

3 files changed

+146
-116
lines changed

crates/ra_hir/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ macro_rules! impl_froms {
1818
}
1919

2020
pub mod db;
21+
#[macro_use]
2122
pub mod mock;
2223
mod query_definitions;
2324
mod path;

crates/ra_hir/src/mock.rs

Lines changed: 90 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ra_db::{
66
};
77
use relative_path::RelativePathBuf;
88
use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset};
9+
use rustc_hash::FxHashMap;
910

1011
use crate::{db, HirInterner};
1112

@@ -21,82 +22,125 @@ pub struct MockDatabase {
2122
events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>,
2223
runtime: salsa::Runtime<MockDatabase>,
2324
interner: Arc<HirInterner>,
24-
file_counter: u32,
25+
files: FxHashMap<String, FileId>,
2526
}
2627

2728
impl panic::RefUnwindSafe for MockDatabase {}
2829

2930
impl MockDatabase {
30-
pub fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) {
31-
let (db, source_root, position) = MockDatabase::from_fixture(fixture);
31+
pub fn with_files(fixture: &str) -> MockDatabase {
32+
let (db, position) = MockDatabase::from_fixture(fixture);
3233
assert!(position.is_none());
33-
(db, source_root)
34+
db
3435
}
3536

3637
pub fn with_single_file(text: &str) -> (MockDatabase, SourceRoot, FileId) {
3738
let mut db = MockDatabase::default();
3839
let mut source_root = SourceRoot::default();
39-
let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text);
40+
let file_id = db.add_file(WORKSPACE, "/", &mut source_root, "/main.rs", text);
4041
db.set_source_root(WORKSPACE, Arc::new(source_root.clone()));
4142
(db, source_root, file_id)
4243
}
4344

4445
pub fn with_position(fixture: &str) -> (MockDatabase, FilePosition) {
45-
let (db, _, position) = MockDatabase::from_fixture(fixture);
46+
let (db, position) = MockDatabase::from_fixture(fixture);
4647
let position = position.expect("expected a marker ( <|> )");
4748
(db, position)
4849
}
4950

50-
fn from_fixture(fixture: &str) -> (MockDatabase, SourceRoot, Option<FilePosition>) {
51+
pub fn file_id_of(&self, path: &str) -> FileId {
52+
match self.files.get(path) {
53+
Some(it) => *it,
54+
None => panic!("unknown file: {:?}\nexisting files:\n{:#?}", path, self.files),
55+
}
56+
}
57+
58+
pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) {
59+
let mut ids = FxHashMap::default();
60+
let mut crate_graph = CrateGraph::default();
61+
for (crate_name, (crate_root, _)) in graph.0.iter() {
62+
let crate_root = self.file_id_of(&crate_root);
63+
let crate_id = crate_graph.add_crate_root(crate_root);
64+
ids.insert(crate_name, crate_id);
65+
}
66+
for (crate_name, (_, deps)) in graph.0.iter() {
67+
let from = ids[crate_name];
68+
for dep in deps {
69+
let to = ids[dep];
70+
crate_graph.add_dep(from, dep.as_str().into(), to).unwrap();
71+
}
72+
}
73+
self.set_crate_graph(Arc::new(crate_graph))
74+
}
75+
76+
fn from_fixture(fixture: &str) -> (MockDatabase, Option<FilePosition>) {
5177
let mut db = MockDatabase::default();
5278

53-
let (source_root, pos) = db.add_fixture(WORKSPACE, fixture);
79+
let pos = db.add_fixture(fixture);
5480

55-
(db, source_root, pos)
81+
(db, pos)
5682
}
5783

58-
pub fn add_fixture(
59-
&mut self,
60-
source_root_id: SourceRootId,
61-
fixture: &str,
62-
) -> (SourceRoot, Option<FilePosition>) {
84+
fn add_fixture(&mut self, fixture: &str) -> Option<FilePosition> {
6385
let mut position = None;
6486
let mut source_root = SourceRoot::default();
87+
let mut source_root_id = WORKSPACE;
88+
let mut source_root_prefix = "/".to_string();
6589
for entry in parse_fixture(fixture) {
90+
if entry.meta.starts_with("root") {
91+
self.set_source_root(source_root_id, Arc::new(source_root));
92+
source_root = SourceRoot::default();
93+
94+
source_root_id = SourceRootId(source_root_id.0 + 1);
95+
source_root_prefix = entry.meta["root".len()..].trim().to_string();
96+
continue;
97+
}
6698
if entry.text.contains(CURSOR_MARKER) {
6799
assert!(position.is_none(), "only one marker (<|>) per fixture is allowed");
68100
position = Some(self.add_file_with_position(
69101
source_root_id,
102+
&source_root_prefix,
70103
&mut source_root,
71104
&entry.meta,
72105
&entry.text,
73106
));
74107
} else {
75-
self.add_file(source_root_id, &mut source_root, &entry.meta, &entry.text);
108+
self.add_file(
109+
source_root_id,
110+
&source_root_prefix,
111+
&mut source_root,
112+
&entry.meta,
113+
&entry.text,
114+
);
76115
}
77116
}
78-
self.set_source_root(source_root_id, Arc::new(source_root.clone()));
79-
(source_root, position)
117+
self.set_source_root(source_root_id, Arc::new(source_root));
118+
position
80119
}
81120

82121
fn add_file(
83122
&mut self,
84123
source_root_id: SourceRootId,
124+
source_root_prefix: &str,
85125
source_root: &mut SourceRoot,
86126
path: &str,
87127
text: &str,
88128
) -> FileId {
89-
assert!(path.starts_with('/'));
90-
let is_crate_root = path == "/lib.rs" || path == "/main.rs";
129+
assert!(source_root_prefix.starts_with('/'));
130+
assert!(source_root_prefix.ends_with('/'));
131+
assert!(path.starts_with(source_root_prefix));
132+
let rel_path = RelativePathBuf::from_path(&path[source_root_prefix.len()..]).unwrap();
133+
134+
let is_crate_root = rel_path == "lib.rs" || rel_path == "/main.rs";
91135

92-
let path = RelativePathBuf::from_path(&path[1..]).unwrap();
93-
let file_id = FileId(self.file_counter);
94-
self.file_counter += 1;
136+
let file_id = FileId(self.files.len() as u32);
137+
let prev = self.files.insert(path.to_string(), file_id);
138+
assert!(prev.is_none(), "duplicate files in the text fixture");
95139
let text = Arc::new(text.to_string());
96140
self.set_file_text(file_id, text);
97-
self.set_file_relative_path(file_id, path.clone());
141+
self.set_file_relative_path(file_id, rel_path.clone());
98142
self.set_file_source_root(file_id, source_root_id);
99-
source_root.files.insert(path, file_id);
143+
source_root.files.insert(rel_path, file_id);
100144

101145
if is_crate_root {
102146
let mut crate_graph = CrateGraph::default();
@@ -109,12 +153,13 @@ impl MockDatabase {
109153
fn add_file_with_position(
110154
&mut self,
111155
source_root_id: SourceRootId,
156+
source_root_prefix: &str,
112157
source_root: &mut SourceRoot,
113158
path: &str,
114159
text: &str,
115160
) -> FilePosition {
116161
let (offset, text) = extract_offset(text);
117-
let file_id = self.add_file(source_root_id, source_root, path, &text);
162+
let file_id = self.add_file(source_root_id, source_root_prefix, source_root, path, &text);
118163
FilePosition { file_id, offset }
119164
}
120165
}
@@ -138,7 +183,7 @@ impl Default for MockDatabase {
138183
events: Default::default(),
139184
runtime: salsa::Runtime::default(),
140185
interner: Default::default(),
141-
file_counter: 0,
186+
files: FxHashMap::default(),
142187
};
143188
db.set_crate_graph(Default::default());
144189
db
@@ -151,7 +196,8 @@ impl salsa::ParallelDatabase for MockDatabase {
151196
events: Default::default(),
152197
runtime: self.runtime.snapshot(self),
153198
interner: Arc::clone(&self.interner),
154-
file_counter: self.file_counter,
199+
// only the root database can be used to get file_id by path.
200+
files: FxHashMap::default(),
155201
})
156202
}
157203
}
@@ -184,3 +230,20 @@ impl MockDatabase {
184230
.collect()
185231
}
186232
}
233+
234+
#[derive(Default)]
235+
pub struct CrateGraphFixture(pub FxHashMap<String, (String, Vec<String>)>);
236+
237+
#[macro_export]
238+
macro_rules! crate_graph {
239+
($($crate_name:literal: ($crate_path:literal, [$($dep:literal),*]),)*) => {{
240+
let mut res = $crate::mock::CrateGraphFixture::default();
241+
$(
242+
res.0.insert(
243+
$crate_name.to_string(),
244+
($crate_path.to_string(), vec![$($dep.to_string()),*])
245+
);
246+
)*
247+
res
248+
}}
249+
}

0 commit comments

Comments
 (0)