aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-02-11 09:53:10 +0000
committerAleksey Kladov <[email protected]>2019-02-11 09:53:10 +0000
commitdced2f4ed42b7013c761f2ed53c6c2482fa76169 (patch)
tree4eaf3d862a920b7e0f18733ee520cbb6719551c3 /crates/ra_hir
parent81852f6dd2c1bf86da440d9216959baa9a0a5ed2 (diff)
Handle SourceRoots automatically in fixtures
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/mock.rs82
-rw-r--r--crates/ra_hir/src/nameres/tests.rs48
2 files changed, 75 insertions, 55 deletions
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 950f89948..29b696afa 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -6,6 +6,7 @@ use ra_db::{
6}; 6};
7use relative_path::RelativePathBuf; 7use relative_path::RelativePathBuf;
8use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; 8use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset};
9use rustc_hash::FxHashMap;
9 10
10use crate::{db, HirInterner}; 11use crate::{db, HirInterner};
11 12
@@ -21,82 +22,107 @@ pub struct MockDatabase {
21 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, 22 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>,
22 runtime: salsa::Runtime<MockDatabase>, 23 runtime: salsa::Runtime<MockDatabase>,
23 interner: Arc<HirInterner>, 24 interner: Arc<HirInterner>,
24 file_counter: u32, 25 files: FxHashMap<String, FileId>,
25} 26}
26 27
27impl panic::RefUnwindSafe for MockDatabase {} 28impl panic::RefUnwindSafe for MockDatabase {}
28 29
29impl MockDatabase { 30impl MockDatabase {
30 pub fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) { 31 pub fn with_files(fixture: &str) -> MockDatabase {
31 let (db, source_root, position) = MockDatabase::from_fixture(fixture); 32 let (db, position) = MockDatabase::from_fixture(fixture);
32 assert!(position.is_none()); 33 assert!(position.is_none());
33 (db, source_root) 34 db
34 } 35 }
35 36
36 pub fn with_single_file(text: &str) -> (MockDatabase, SourceRoot, FileId) { 37 pub fn with_single_file(text: &str) -> (MockDatabase, SourceRoot, FileId) {
37 let mut db = MockDatabase::default(); 38 let mut db = MockDatabase::default();
38 let mut source_root = SourceRoot::default(); 39 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);
40 db.set_source_root(WORKSPACE, Arc::new(source_root.clone())); 41 db.set_source_root(WORKSPACE, Arc::new(source_root.clone()));
41 (db, source_root, file_id) 42 (db, source_root, file_id)
42 } 43 }
43 44
44 pub fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { 45 pub fn with_position(fixture: &str) -> (MockDatabase, FilePosition) {
45 let (db, _, position) = MockDatabase::from_fixture(fixture); 46 let (db, position) = MockDatabase::from_fixture(fixture);
46 let position = position.expect("expected a marker ( <|> )"); 47 let position = position.expect("expected a marker ( <|> )");
47 (db, position) 48 (db, position)
48 } 49 }
49 50
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>) {
51 let mut db = MockDatabase::default(); 59 let mut db = MockDatabase::default();
52 60
53 let (source_root, pos) = db.add_fixture(WORKSPACE, fixture); 61 let pos = db.add_fixture(fixture);
54 62
55 (db, source_root, pos) 63 (db, pos)
56 } 64 }
57 65
58 pub fn add_fixture( 66 fn add_fixture(&mut self, fixture: &str) -> Option<FilePosition> {
59 &mut self,
60 source_root_id: SourceRootId,
61 fixture: &str,
62 ) -> (SourceRoot, Option<FilePosition>) {
63 let mut position = None; 67 let mut position = None;
64 let mut source_root = SourceRoot::default(); 68 let mut source_root = SourceRoot::default();
69 let mut source_root_id = WORKSPACE;
70 let mut source_root_prefix = "/".to_string();
65 for entry in parse_fixture(fixture) { 71 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 }
66 if entry.text.contains(CURSOR_MARKER) { 80 if entry.text.contains(CURSOR_MARKER) {
67 assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); 81 assert!(position.is_none(), "only one marker (<|>) per fixture is allowed");
68 position = Some(self.add_file_with_position( 82 position = Some(self.add_file_with_position(
69 source_root_id, 83 source_root_id,
84 &source_root_prefix,
70 &mut source_root, 85 &mut source_root,
71 &entry.meta, 86 &entry.meta,
72 &entry.text, 87 &entry.text,
73 )); 88 ));
74 } else { 89 } 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 );
76 } 97 }
77 } 98 }
78 self.set_source_root(source_root_id, Arc::new(source_root.clone())); 99 self.set_source_root(source_root_id, Arc::new(source_root));
79 (source_root, position) 100 position
80 } 101 }
81 102
82 fn add_file( 103 fn add_file(
83 &mut self, 104 &mut self,
84 source_root_id: SourceRootId, 105 source_root_id: SourceRootId,
106 source_root_prefix: &str,
85 source_root: &mut SourceRoot, 107 source_root: &mut SourceRoot,
86 path: &str, 108 path: &str,
87 text: &str, 109 text: &str,
88 ) -> FileId { 110 ) -> FileId {
89 assert!(path.starts_with('/')); 111 assert!(source_root_prefix.starts_with('/'));
90 let is_crate_root = path == "/lib.rs" || path == "/main.rs"; 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";
91 117
92 let path = RelativePathBuf::from_path(&path[1..]).unwrap(); 118 let file_id = FileId(self.files.len() as u32);
93 let file_id = FileId(self.file_counter); 119 let prev = self.files.insert(path.to_string(), file_id);
94 self.file_counter += 1; 120 assert!(prev.is_none(), "duplicate files in the text fixture");
95 let text = Arc::new(text.to_string()); 121 let text = Arc::new(text.to_string());
96 self.set_file_text(file_id, text); 122 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());
98 self.set_file_source_root(file_id, source_root_id); 124 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);
100 126
101 if is_crate_root { 127 if is_crate_root {
102 let mut crate_graph = CrateGraph::default(); 128 let mut crate_graph = CrateGraph::default();
@@ -109,12 +135,13 @@ impl MockDatabase {
109 fn add_file_with_position( 135 fn add_file_with_position(
110 &mut self, 136 &mut self,
111 source_root_id: SourceRootId, 137 source_root_id: SourceRootId,
138 source_root_prefix: &str,
112 source_root: &mut SourceRoot, 139 source_root: &mut SourceRoot,
113 path: &str, 140 path: &str,
114 text: &str, 141 text: &str,
115 ) -> FilePosition { 142 ) -> FilePosition {
116 let (offset, text) = extract_offset(text); 143 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);
118 FilePosition { file_id, offset } 145 FilePosition { file_id, offset }
119 } 146 }
120} 147}
@@ -138,7 +165,7 @@ impl Default for MockDatabase {
138 events: Default::default(), 165 events: Default::default(),
139 runtime: salsa::Runtime::default(), 166 runtime: salsa::Runtime::default(),
140 interner: Default::default(), 167 interner: Default::default(),
141 file_counter: 0, 168 files: FxHashMap::default(),
142 }; 169 };
143 db.set_crate_graph(Default::default()); 170 db.set_crate_graph(Default::default());
144 db 171 db
@@ -151,7 +178,8 @@ impl salsa::ParallelDatabase for MockDatabase {
151 events: Default::default(), 178 events: Default::default(),
152 runtime: self.runtime.snapshot(self), 179 runtime: self.runtime.snapshot(self),
153 interner: Arc::clone(&self.interner), 180 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(),
155 }) 183 })
156 } 184 }
157} 185}
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 9c0e4ef29..905c3accf 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -1,7 +1,6 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::{CrateGraph, SourceRootId, SourceDatabase}; 3use ra_db::{CrateGraph, SourceDatabase};
4use relative_path::RelativePath;
5use test_utils::{assert_eq_text, covers}; 4use test_utils::{assert_eq_text, covers};
6 5
7use crate::{ 6use crate::{
@@ -252,7 +251,7 @@ fn glob_enum() {
252#[test] 251#[test]
253fn glob_across_crates() { 252fn glob_across_crates() {
254 covers!(glob_across_crates); 253 covers!(glob_across_crates);
255 let (mut db, sr) = MockDatabase::with_files( 254 let mut db = MockDatabase::with_files(
256 " 255 "
257 //- /main.rs 256 //- /main.rs
258 use test_crate::*; 257 use test_crate::*;
@@ -261,8 +260,8 @@ fn glob_across_crates() {
261 pub struct Baz; 260 pub struct Baz;
262 ", 261 ",
263 ); 262 );
264 let main_id = sr.files[RelativePath::new("/main.rs")]; 263 let main_id = db.file_id_of("/main.rs");
265 let lib_id = sr.files[RelativePath::new("/lib.rs")]; 264 let lib_id = db.file_id_of("/lib.rs");
266 265
267 let mut crate_graph = CrateGraph::default(); 266 let mut crate_graph = CrateGraph::default();
268 let main_crate = crate_graph.add_crate_root(main_id); 267 let main_crate = crate_graph.add_crate_root(main_id);
@@ -411,7 +410,7 @@ fn item_map_enum_importing() {
411 410
412#[test] 411#[test]
413fn item_map_across_crates() { 412fn item_map_across_crates() {
414 let (mut db, sr) = MockDatabase::with_files( 413 let mut db = MockDatabase::with_files(
415 " 414 "
416 //- /main.rs 415 //- /main.rs
417 use test_crate::Baz; 416 use test_crate::Baz;
@@ -420,8 +419,8 @@ fn item_map_across_crates() {
420 pub struct Baz; 419 pub struct Baz;
421 ", 420 ",
422 ); 421 );
423 let main_id = sr.files[RelativePath::new("/main.rs")]; 422 let main_id = db.file_id_of("/main.rs");
424 let lib_id = sr.files[RelativePath::new("/lib.rs")]; 423 let lib_id = db.file_id_of("/lib.rs");
425 424
426 let mut crate_graph = CrateGraph::default(); 425 let mut crate_graph = CrateGraph::default();
427 let main_crate = crate_graph.add_crate_root(main_id); 426 let main_crate = crate_graph.add_crate_root(main_id);
@@ -445,7 +444,7 @@ fn item_map_across_crates() {
445 444
446#[test] 445#[test]
447fn extern_crate_rename() { 446fn extern_crate_rename() {
448 let (mut db, sr) = MockDatabase::with_files( 447 let mut db = MockDatabase::with_files(
449 " 448 "
450 //- /main.rs 449 //- /main.rs
451 extern crate alloc as alloc_crate; 450 extern crate alloc as alloc_crate;
@@ -460,9 +459,9 @@ fn extern_crate_rename() {
460 struct Arc; 459 struct Arc;
461 ", 460 ",
462 ); 461 );
463 let main_id = sr.files[RelativePath::new("/main.rs")]; 462 let main_id = db.file_id_of("/main.rs");
464 let sync_id = sr.files[RelativePath::new("/sync.rs")]; 463 let sync_id = db.file_id_of("/sync.rs");
465 let lib_id = sr.files[RelativePath::new("/lib.rs")]; 464 let lib_id = db.file_id_of("/lib.rs");
466 465
467 let mut crate_graph = CrateGraph::default(); 466 let mut crate_graph = CrateGraph::default();
468 let main_crate = crate_graph.add_crate_root(main_id); 467 let main_crate = crate_graph.add_crate_root(main_id);
@@ -486,7 +485,7 @@ fn extern_crate_rename() {
486 485
487#[test] 486#[test]
488fn import_across_source_roots() { 487fn import_across_source_roots() {
489 let (mut db, sr) = MockDatabase::with_files( 488 let mut db = MockDatabase::with_files(
490 " 489 "
491 //- /lib.rs 490 //- /lib.rs
492 pub mod a { 491 pub mod a {
@@ -494,22 +493,15 @@ fn import_across_source_roots() {
494 pub struct C; 493 pub struct C;
495 } 494 }
496 } 495 }
497 ",
498 );
499 let lib_id = sr.files[RelativePath::new("/lib.rs")];
500 496
501 let source_root = SourceRootId(1); 497 //- root /test_crate/
502 498
503 let (sr2, pos) = db.add_fixture( 499 //- /test_crate/main.rs
504 source_root,
505 "
506 //- /main.rs
507 use test_crate::a::b::C; 500 use test_crate::a::b::C;
508 ", 501 ",
509 ); 502 );
510 assert!(pos.is_none()); 503 let lib_id = db.file_id_of("/lib.rs");
511 504 let main_id = db.file_id_of("/test_crate/main.rs");
512 let main_id = sr2.files[RelativePath::new("/main.rs")];
513 505
514 let mut crate_graph = CrateGraph::default(); 506 let mut crate_graph = CrateGraph::default();
515 let main_crate = crate_graph.add_crate_root(main_id); 507 let main_crate = crate_graph.add_crate_root(main_id);
@@ -533,7 +525,7 @@ fn import_across_source_roots() {
533 525
534#[test] 526#[test]
535fn reexport_across_crates() { 527fn reexport_across_crates() {
536 let (mut db, sr) = MockDatabase::with_files( 528 let mut db = MockDatabase::with_files(
537 " 529 "
538 //- /main.rs 530 //- /main.rs
539 use test_crate::Baz; 531 use test_crate::Baz;
@@ -547,8 +539,8 @@ fn reexport_across_crates() {
547 pub struct Baz; 539 pub struct Baz;
548 ", 540 ",
549 ); 541 );
550 let main_id = sr.files[RelativePath::new("/main.rs")]; 542 let main_id = db.file_id_of("/main.rs");
551 let lib_id = sr.files[RelativePath::new("/lib.rs")]; 543 let lib_id = db.file_id_of("/lib.rs");
552 544
553 let mut crate_graph = CrateGraph::default(); 545 let mut crate_graph = CrateGraph::default();
554 let main_crate = crate_graph.add_crate_root(main_id); 546 let main_crate = crate_graph.add_crate_root(main_id);