aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_db/src/fixture.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_db/src/fixture.rs')
-rw-r--r--crates/ra_db/src/fixture.rs180
1 files changed, 62 insertions, 118 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 482a2f3e6..4f4fb4494 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -57,17 +57,16 @@
57//! fn insert_source_code_here() {} 57//! fn insert_source_code_here() {}
58//! " 58//! "
59//! ``` 59//! ```
60 60use std::{str::FromStr, sync::Arc};
61use std::str::FromStr;
62use std::sync::Arc;
63 61
64use ra_cfg::CfgOptions; 62use ra_cfg::CfgOptions;
65use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
66use test_utils::{extract_offset, parse_fixture, parse_single_fixture, FixtureMeta, CURSOR_MARKER}; 64use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER};
65use vfs::{file_set::FileSet, VfsPath};
67 66
68use crate::{ 67use crate::{
69 input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, 68 input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, SourceDatabaseExt,
70 SourceDatabaseExt, SourceRoot, SourceRootId, 69 SourceRoot, SourceRootId,
71}; 70};
72 71
73pub const WORKSPACE: SourceRootId = SourceRootId(0); 72pub const WORKSPACE: SourceRootId = SourceRootId(0);
@@ -75,21 +74,32 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0);
75pub trait WithFixture: Default + SourceDatabaseExt + 'static { 74pub trait WithFixture: Default + SourceDatabaseExt + 'static {
76 fn with_single_file(text: &str) -> (Self, FileId) { 75 fn with_single_file(text: &str) -> (Self, FileId) {
77 let mut db = Self::default(); 76 let mut db = Self::default();
78 let file_id = with_single_file(&mut db, text); 77 let (_, files) = with_files(&mut db, text);
79 (db, file_id) 78 assert_eq!(files.len(), 1);
79 (db, files[0])
80 } 80 }
81 81
82 fn with_files(ra_fixture: &str) -> Self { 82 fn with_files(ra_fixture: &str) -> Self {
83 let mut db = Self::default(); 83 let mut db = Self::default();
84 let pos = with_files(&mut db, ra_fixture); 84 let (pos, _) = with_files(&mut db, ra_fixture);
85 assert!(pos.is_none()); 85 assert!(pos.is_none());
86 db 86 db
87 } 87 }
88 88
89 fn with_position(ra_fixture: &str) -> (Self, FilePosition) { 89 fn with_position(ra_fixture: &str) -> (Self, FilePosition) {
90 let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture);
91 let offset = match range_or_offset {
92 RangeOrOffset::Range(_) => panic!(),
93 RangeOrOffset::Offset(it) => it,
94 };
95 (db, FilePosition { file_id, offset })
96 }
97
98 fn with_range_or_offset(ra_fixture: &str) -> (Self, FileId, RangeOrOffset) {
90 let mut db = Self::default(); 99 let mut db = Self::default();
91 let pos = with_files(&mut db, ra_fixture); 100 let (pos, _) = with_files(&mut db, ra_fixture);
92 (db, pos.unwrap()) 101 let (file_id, range_or_offset) = pos.unwrap();
102 (db, file_id, range_or_offset)
93 } 103 }
94 104
95 fn test_crate(&self) -> CrateId { 105 fn test_crate(&self) -> CrateId {
@@ -103,83 +113,36 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
103 113
104impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {} 114impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {}
105 115
106fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId { 116fn with_files(
107 let file_id = FileId(0); 117 db: &mut dyn SourceDatabaseExt,
108 let rel_path: RelativePathBuf = "/main.rs".into(); 118 fixture: &str,
109 119) -> (Option<(FileId, RangeOrOffset)>, Vec<FileId>) {
110 let mut source_root = SourceRoot::new_local(); 120 let fixture = Fixture::parse(fixture);
111 source_root.insert_file(rel_path.clone(), file_id);
112
113 let fixture = parse_single_fixture(ra_fixture);
114
115 let crate_graph = if let Some(entry) = fixture {
116 let meta = match ParsedMeta::from(&entry.meta) {
117 ParsedMeta::File(it) => it,
118 _ => panic!("with_single_file only support file meta"),
119 };
120
121 let mut crate_graph = CrateGraph::default();
122 crate_graph.add_crate_root(
123 file_id,
124 meta.edition,
125 meta.krate.map(|name| {
126 CrateName::new(&name).expect("Fixture crate name should not contain dashes")
127 }),
128 meta.cfg,
129 meta.env,
130 Default::default(),
131 Default::default(),
132 );
133 crate_graph
134 } else {
135 let mut crate_graph = CrateGraph::default();
136 crate_graph.add_crate_root(
137 file_id,
138 Edition::Edition2018,
139 None,
140 CfgOptions::default(),
141 Env::default(),
142 Default::default(),
143 Default::default(),
144 );
145 crate_graph
146 };
147
148 db.set_file_text(file_id, Arc::new(ra_fixture.to_string()));
149 db.set_file_relative_path(file_id, rel_path);
150 db.set_file_source_root(file_id, WORKSPACE);
151 db.set_source_root(WORKSPACE, Arc::new(source_root));
152 db.set_crate_graph(Arc::new(crate_graph));
153
154 file_id
155}
156
157fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosition> {
158 let fixture = parse_fixture(fixture);
159 121
122 let mut files = Vec::new();
160 let mut crate_graph = CrateGraph::default(); 123 let mut crate_graph = CrateGraph::default();
161 let mut crates = FxHashMap::default(); 124 let mut crates = FxHashMap::default();
162 let mut crate_deps = Vec::new(); 125 let mut crate_deps = Vec::new();
163 let mut default_crate_root: Option<FileId> = None; 126 let mut default_crate_root: Option<FileId> = None;
164 127
165 let mut source_root = SourceRoot::new_local(); 128 let mut file_set = FileSet::default();
166 let mut source_root_id = WORKSPACE; 129 let source_root_id = WORKSPACE;
167 let mut source_root_prefix: RelativePathBuf = "/".into(); 130 let source_root_prefix = "/".to_string();
168 let mut file_id = FileId(0); 131 let mut file_id = FileId(0);
169 132
170 let mut file_position = None; 133 let mut file_position = None;
171 134
172 for entry in fixture.iter() { 135 for entry in fixture {
173 let meta = match ParsedMeta::from(&entry.meta) { 136 let text = if entry.text.contains(CURSOR_MARKER) {
174 ParsedMeta::Root { path } => { 137 let (range_or_offset, text) = extract_range_or_offset(&entry.text);
175 let source_root = std::mem::replace(&mut source_root, SourceRoot::new_local()); 138 assert!(file_position.is_none());
176 db.set_source_root(source_root_id, Arc::new(source_root)); 139 file_position = Some((file_id, range_or_offset));
177 source_root_id.0 += 1; 140 text.to_string()
178 source_root_prefix = path; 141 } else {
179 continue; 142 entry.text.clone()
180 }
181 ParsedMeta::File(it) => it,
182 }; 143 };
144
145 let meta = FileMeta::from(entry);
183 assert!(meta.path.starts_with(&source_root_prefix)); 146 assert!(meta.path.starts_with(&source_root_prefix));
184 147
185 if let Some(krate) = meta.krate { 148 if let Some(krate) = meta.krate {
@@ -190,7 +153,6 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
190 meta.cfg, 153 meta.cfg,
191 meta.env, 154 meta.env,
192 Default::default(), 155 Default::default(),
193 Default::default(),
194 ); 156 );
195 let prev = crates.insert(krate.clone(), crate_id); 157 let prev = crates.insert(krate.clone(), crate_id);
196 assert!(prev.is_none()); 158 assert!(prev.is_none());
@@ -202,20 +164,11 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
202 default_crate_root = Some(file_id); 164 default_crate_root = Some(file_id);
203 } 165 }
204 166
205 let text = if entry.text.contains(CURSOR_MARKER) {
206 let (offset, text) = extract_offset(&entry.text);
207 assert!(file_position.is_none());
208 file_position = Some(FilePosition { file_id, offset });
209 text.to_string()
210 } else {
211 entry.text.to_string()
212 };
213
214 db.set_file_text(file_id, Arc::new(text)); 167 db.set_file_text(file_id, Arc::new(text));
215 db.set_file_relative_path(file_id, meta.path.clone());
216 db.set_file_source_root(file_id, source_root_id); 168 db.set_file_source_root(file_id, source_root_id);
217 source_root.insert_file(meta.path, file_id); 169 let path = VfsPath::new_virtual_path(meta.path);
218 170 file_set.insert(file_id, path.into());
171 files.push(file_id);
219 file_id.0 += 1; 172 file_id.0 += 1;
220 } 173 }
221 174
@@ -228,7 +181,6 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
228 CfgOptions::default(), 181 CfgOptions::default(),
229 Env::default(), 182 Env::default(),
230 Default::default(), 183 Default::default(),
231 Default::default(),
232 ); 184 );
233 } else { 185 } else {
234 for (from, to) in crate_deps { 186 for (from, to) in crate_deps {
@@ -238,19 +190,14 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
238 } 190 }
239 } 191 }
240 192
241 db.set_source_root(source_root_id, Arc::new(source_root)); 193 db.set_source_root(source_root_id, Arc::new(SourceRoot::new_local(file_set)));
242 db.set_crate_graph(Arc::new(crate_graph)); 194 db.set_crate_graph(Arc::new(crate_graph));
243 195
244 file_position 196 (file_position, files)
245}
246
247enum ParsedMeta {
248 Root { path: RelativePathBuf },
249 File(FileMeta),
250} 197}
251 198
252struct FileMeta { 199struct FileMeta {
253 path: RelativePathBuf, 200 path: String,
254 krate: Option<String>, 201 krate: Option<String>,
255 deps: Vec<String>, 202 deps: Vec<String>,
256 cfg: CfgOptions, 203 cfg: CfgOptions,
@@ -258,25 +205,22 @@ struct FileMeta {
258 env: Env, 205 env: Env,
259} 206}
260 207
261impl From<&FixtureMeta> for ParsedMeta { 208impl From<Fixture> for FileMeta {
262 fn from(meta: &FixtureMeta) -> Self { 209 fn from(f: Fixture) -> FileMeta {
263 match meta { 210 let mut cfg = CfgOptions::default();
264 FixtureMeta::Root { path } => { 211 f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
265 // `Self::Root` causes a false warning: 'variant is never constructed: `Root` ' 212 f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
266 // see https://github.com/rust-lang/rust/issues/69018 213
267 ParsedMeta::Root { path: path.to_owned() } 214 FileMeta {
268 } 215 path: f.path,
269 FixtureMeta::File(f) => Self::File(FileMeta { 216 krate: f.krate,
270 path: f.path.to_owned(), 217 deps: f.deps,
271 krate: f.crate_name.to_owned(), 218 cfg,
272 deps: f.deps.to_owned(), 219 edition: f
273 cfg: f.cfg.to_owned(), 220 .edition
274 edition: f 221 .as_ref()
275 .edition 222 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()),
276 .as_ref() 223 env: Env::from(f.env.iter()),
277 .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()),
278 env: Env::from(f.env.iter()),
279 }),
280 } 224 }
281 } 225 }
282} 226}