diff options
Diffstat (limited to 'crates/ra_db/src/fixture.rs')
-rw-r--r-- | crates/ra_db/src/fixture.rs | 180 |
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 | 60 | use std::{str::FromStr, sync::Arc}; | |
61 | use std::str::FromStr; | ||
62 | use std::sync::Arc; | ||
63 | 61 | ||
64 | use ra_cfg::CfgOptions; | 62 | use ra_cfg::CfgOptions; |
65 | use rustc_hash::FxHashMap; | 63 | use rustc_hash::FxHashMap; |
66 | use test_utils::{extract_offset, parse_fixture, parse_single_fixture, FixtureMeta, CURSOR_MARKER}; | 64 | use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER}; |
65 | use vfs::{file_set::FileSet, VfsPath}; | ||
67 | 66 | ||
68 | use crate::{ | 67 | use 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 | ||
73 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 72 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
@@ -75,21 +74,32 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); | |||
75 | pub trait WithFixture: Default + SourceDatabaseExt + 'static { | 74 | pub 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 | ||
104 | impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {} | 114 | impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {} |
105 | 115 | ||
106 | fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId { | 116 | fn 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 | |||
157 | fn 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 | |||
247 | enum ParsedMeta { | ||
248 | Root { path: RelativePathBuf }, | ||
249 | File(FileMeta), | ||
250 | } | 197 | } |
251 | 198 | ||
252 | struct FileMeta { | 199 | struct 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 | ||
261 | impl From<&FixtureMeta> for ParsedMeta { | 208 | impl 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 | } |