Skip to content

Commit dced2f4

Browse files
committed
Handle SourceRoots automatically in fixtures
1 parent 81852f6 commit dced2f4

File tree

2 files changed

+75
-55
lines changed

2 files changed

+75
-55
lines changed

crates/ra_hir/src/mock.rs

Lines changed: 55 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,107 @@ 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+
fn from_fixture(fixture: &str) -> (MockDatabase, Option<FilePosition>) {
5159
let mut db = MockDatabase::default();
5260

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

55-
(db, source_root, pos)
63+
(db, pos)
5664
}
5765

58-
pub fn add_fixture(
59-
&mut self,
60-
source_root_id: SourceRootId,
61-
fixture: &str,
62-
) -> (SourceRoot, Option<FilePosition>) {
66+
fn add_fixture(&mut self, fixture: &str) -> Option<FilePosition> {
6367
let mut position = None;
6468
let mut source_root = SourceRoot::default();
69+
let mut source_root_id = WORKSPACE;
70+
let mut source_root_prefix = "/".to_string();
6571
for entry in parse_fixture(fixture) {
72+
if entry.meta.starts_with("root") {
73+
self.set_source_root(source_root_id, Arc::new(source_root));
74+
source_root = SourceRoot::default();
75+
76+
source_root_id = SourceRootId(source_root_id.0 + 1);
77+
source_root_prefix = entry.meta["root".len()..].trim().to_string();
78+
continue;
79+
}
6680
if entry.text.contains(CURSOR_MARKER) {
6781
assert!(position.is_none(), "only one marker (<|>) per fixture is allowed");
6882
position = Some(self.add_file_with_position(
6983
source_root_id,
84+
&source_root_prefix,
7085
&mut source_root,
7186
&entry.meta,
7287
&entry.text,
7388
));
7489
} else {
75-
self.add_file(source_root_id, &mut source_root, &entry.meta, &entry.text);
90+
self.add_file(
91+
source_root_id,
92+
&source_root_prefix,
93+
&mut source_root,
94+
&entry.meta,
95+
&entry.text,
96+
);
7697
}
7798
}
78-
self.set_source_root(source_root_id, Arc::new(source_root.clone()));
79-
(source_root, position)
99+
self.set_source_root(source_root_id, Arc::new(source_root));
100+
position
80101
}
81102

82103
fn add_file(
83104
&mut self,
84105
source_root_id: SourceRootId,
106+
source_root_prefix: &str,
85107
source_root: &mut SourceRoot,
86108
path: &str,
87109
text: &str,
88110
) -> FileId {
89-
assert!(path.starts_with('/'));
90-
let is_crate_root = path == "/lib.rs" || path == "/main.rs";
111+
assert!(source_root_prefix.starts_with('/'));
112+
assert!(source_root_prefix.ends_with('/'));
113+
assert!(path.starts_with(source_root_prefix));
114+
let rel_path = RelativePathBuf::from_path(&path[source_root_prefix.len()..]).unwrap();
115+
116+
let is_crate_root = rel_path == "lib.rs" || rel_path == "/main.rs";
91117

92-
let path = RelativePathBuf::from_path(&path[1..]).unwrap();
93-
let file_id = FileId(self.file_counter);
94-
self.file_counter += 1;
118+
let file_id = FileId(self.files.len() as u32);
119+
let prev = self.files.insert(path.to_string(), file_id);
120+
assert!(prev.is_none(), "duplicate files in the text fixture");
95121
let text = Arc::new(text.to_string());
96122
self.set_file_text(file_id, text);
97-
self.set_file_relative_path(file_id, path.clone());
123+
self.set_file_relative_path(file_id, rel_path.clone());
98124
self.set_file_source_root(file_id, source_root_id);
99-
source_root.files.insert(path, file_id);
125+
source_root.files.insert(rel_path, file_id);
100126

101127
if is_crate_root {
102128
let mut crate_graph = CrateGraph::default();
@@ -109,12 +135,13 @@ impl MockDatabase {
109135
fn add_file_with_position(
110136
&mut self,
111137
source_root_id: SourceRootId,
138+
source_root_prefix: &str,
112139
source_root: &mut SourceRoot,
113140
path: &str,
114141
text: &str,
115142
) -> FilePosition {
116143
let (offset, text) = extract_offset(text);
117-
let file_id = self.add_file(source_root_id, source_root, path, &text);
144+
let file_id = self.add_file(source_root_id, source_root_prefix, source_root, path, &text);
118145
FilePosition { file_id, offset }
119146
}
120147
}
@@ -138,7 +165,7 @@ impl Default for MockDatabase {
138165
events: Default::default(),
139166
runtime: salsa::Runtime::default(),
140167
interner: Default::default(),
141-
file_counter: 0,
168+
files: FxHashMap::default(),
142169
};
143170
db.set_crate_graph(Default::default());
144171
db
@@ -151,7 +178,8 @@ impl salsa::ParallelDatabase for MockDatabase {
151178
events: Default::default(),
152179
runtime: self.runtime.snapshot(self),
153180
interner: Arc::clone(&self.interner),
154-
file_counter: self.file_counter,
181+
// only the root database can be used to get file_id by path.
182+
files: FxHashMap::default(),
155183
})
156184
}
157185
}

crates/ra_hir/src/nameres/tests.rs

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::sync::Arc;
22

3-
use ra_db::{CrateGraph, SourceRootId, SourceDatabase};
4-
use relative_path::RelativePath;
3+
use ra_db::{CrateGraph, SourceDatabase};
54
use test_utils::{assert_eq_text, covers};
65

76
use crate::{
@@ -252,7 +251,7 @@ fn glob_enum() {
252251
#[test]
253252
fn glob_across_crates() {
254253
covers!(glob_across_crates);
255-
let (mut db, sr) = MockDatabase::with_files(
254+
let mut db = MockDatabase::with_files(
256255
"
257256
//- /main.rs
258257
use test_crate::*;
@@ -261,8 +260,8 @@ fn glob_across_crates() {
261260
pub struct Baz;
262261
",
263262
);
264-
let main_id = sr.files[RelativePath::new("/main.rs")];
265-
let lib_id = sr.files[RelativePath::new("/lib.rs")];
263+
let main_id = db.file_id_of("/main.rs");
264+
let lib_id = db.file_id_of("/lib.rs");
266265

267266
let mut crate_graph = CrateGraph::default();
268267
let main_crate = crate_graph.add_crate_root(main_id);
@@ -411,7 +410,7 @@ fn item_map_enum_importing() {
411410

412411
#[test]
413412
fn item_map_across_crates() {
414-
let (mut db, sr) = MockDatabase::with_files(
413+
let mut db = MockDatabase::with_files(
415414
"
416415
//- /main.rs
417416
use test_crate::Baz;
@@ -420,8 +419,8 @@ fn item_map_across_crates() {
420419
pub struct Baz;
421420
",
422421
);
423-
let main_id = sr.files[RelativePath::new("/main.rs")];
424-
let lib_id = sr.files[RelativePath::new("/lib.rs")];
422+
let main_id = db.file_id_of("/main.rs");
423+
let lib_id = db.file_id_of("/lib.rs");
425424

426425
let mut crate_graph = CrateGraph::default();
427426
let main_crate = crate_graph.add_crate_root(main_id);
@@ -445,7 +444,7 @@ fn item_map_across_crates() {
445444

446445
#[test]
447446
fn extern_crate_rename() {
448-
let (mut db, sr) = MockDatabase::with_files(
447+
let mut db = MockDatabase::with_files(
449448
"
450449
//- /main.rs
451450
extern crate alloc as alloc_crate;
@@ -460,9 +459,9 @@ fn extern_crate_rename() {
460459
struct Arc;
461460
",
462461
);
463-
let main_id = sr.files[RelativePath::new("/main.rs")];
464-
let sync_id = sr.files[RelativePath::new("/sync.rs")];
465-
let lib_id = sr.files[RelativePath::new("/lib.rs")];
462+
let main_id = db.file_id_of("/main.rs");
463+
let sync_id = db.file_id_of("/sync.rs");
464+
let lib_id = db.file_id_of("/lib.rs");
466465

467466
let mut crate_graph = CrateGraph::default();
468467
let main_crate = crate_graph.add_crate_root(main_id);
@@ -486,30 +485,23 @@ fn extern_crate_rename() {
486485

487486
#[test]
488487
fn import_across_source_roots() {
489-
let (mut db, sr) = MockDatabase::with_files(
488+
let mut db = MockDatabase::with_files(
490489
"
491490
//- /lib.rs
492491
pub mod a {
493492
pub mod b {
494493
pub struct C;
495494
}
496495
}
497-
",
498-
);
499-
let lib_id = sr.files[RelativePath::new("/lib.rs")];
500496
501-
let source_root = SourceRootId(1);
497+
//- root /test_crate/
502498
503-
let (sr2, pos) = db.add_fixture(
504-
source_root,
505-
"
506-
//- /main.rs
499+
//- /test_crate/main.rs
507500
use test_crate::a::b::C;
508-
",
501+
",
509502
);
510-
assert!(pos.is_none());
511-
512-
let main_id = sr2.files[RelativePath::new("/main.rs")];
503+
let lib_id = db.file_id_of("/lib.rs");
504+
let main_id = db.file_id_of("/test_crate/main.rs");
513505

514506
let mut crate_graph = CrateGraph::default();
515507
let main_crate = crate_graph.add_crate_root(main_id);
@@ -533,7 +525,7 @@ fn import_across_source_roots() {
533525

534526
#[test]
535527
fn reexport_across_crates() {
536-
let (mut db, sr) = MockDatabase::with_files(
528+
let mut db = MockDatabase::with_files(
537529
"
538530
//- /main.rs
539531
use test_crate::Baz;
@@ -547,8 +539,8 @@ fn reexport_across_crates() {
547539
pub struct Baz;
548540
",
549541
);
550-
let main_id = sr.files[RelativePath::new("/main.rs")];
551-
let lib_id = sr.files[RelativePath::new("/lib.rs")];
542+
let main_id = db.file_id_of("/main.rs");
543+
let lib_id = db.file_id_of("/lib.rs");
552544

553545
let mut crate_graph = CrateGraph::default();
554546
let main_crate = crate_graph.add_crate_root(main_id);

0 commit comments

Comments
 (0)