diff options
-rw-r--r-- | crates/ra_db/src/fixture.rs | 53 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 10 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 8 |
3 files changed, 56 insertions, 15 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 947d6ad56..7f43c2971 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -5,7 +5,7 @@ use std::sync::Arc; | |||
5 | 5 | ||
6 | use ra_cfg::CfgOptions; | 6 | use ra_cfg::CfgOptions; |
7 | use rustc_hash::FxHashMap; | 7 | use rustc_hash::FxHashMap; |
8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 8 | use test_utils::{extract_offset, parse_fixture, parse_single_fixture, CURSOR_MARKER}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, | 11 | input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, |
@@ -45,23 +45,37 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static { | |||
45 | 45 | ||
46 | impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {} | 46 | impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {} |
47 | 47 | ||
48 | fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId { | 48 | fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId { |
49 | let file_id = FileId(0); | 49 | let file_id = FileId(0); |
50 | let rel_path: RelativePathBuf = "/main.rs".into(); | 50 | let rel_path: RelativePathBuf = "/main.rs".into(); |
51 | 51 | ||
52 | let mut source_root = SourceRoot::new_local(); | 52 | let mut source_root = SourceRoot::new_local(); |
53 | source_root.insert_file(rel_path.clone(), file_id); | 53 | source_root.insert_file(rel_path.clone(), file_id); |
54 | 54 | ||
55 | let mut crate_graph = CrateGraph::default(); | 55 | let fixture = parse_single_fixture(ra_fixture); |
56 | crate_graph.add_crate_root( | 56 | |
57 | file_id, | 57 | let crate_graph = if let Some(entry) = fixture { |
58 | Edition::Edition2018, | 58 | let meta = match parse_meta(&entry.meta) { |
59 | None, | 59 | ParsedMeta::File(it) => it, |
60 | CfgOptions::default(), | 60 | _ => panic!("with_single_file only support file meta"), |
61 | Env::default(), | 61 | }; |
62 | ); | 62 | |
63 | 63 | let mut crate_graph = CrateGraph::default(); | |
64 | db.set_file_text(file_id, Arc::new(text.to_string())); | 64 | crate_graph.add_crate_root(file_id, meta.edition, meta.krate, meta.cfg, meta.env); |
65 | crate_graph | ||
66 | } else { | ||
67 | let mut crate_graph = CrateGraph::default(); | ||
68 | crate_graph.add_crate_root( | ||
69 | file_id, | ||
70 | Edition::Edition2018, | ||
71 | None, | ||
72 | CfgOptions::default(), | ||
73 | Env::default(), | ||
74 | ); | ||
75 | crate_graph | ||
76 | }; | ||
77 | |||
78 | db.set_file_text(file_id, Arc::new(ra_fixture.to_string())); | ||
65 | db.set_file_relative_path(file_id, rel_path); | 79 | db.set_file_relative_path(file_id, rel_path); |
66 | db.set_file_source_root(file_id, WORKSPACE); | 80 | db.set_file_source_root(file_id, WORKSPACE); |
67 | db.set_source_root(WORKSPACE, Arc::new(source_root)); | 81 | db.set_source_root(WORKSPACE, Arc::new(source_root)); |
@@ -104,7 +118,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
104 | meta.edition, | 118 | meta.edition, |
105 | Some(krate.clone()), | 119 | Some(krate.clone()), |
106 | meta.cfg, | 120 | meta.cfg, |
107 | Env::default(), | 121 | meta.env, |
108 | ); | 122 | ); |
109 | let prev = crates.insert(krate.clone(), crate_id); | 123 | let prev = crates.insert(krate.clone(), crate_id); |
110 | assert!(prev.is_none()); | 124 | assert!(prev.is_none()); |
@@ -167,9 +181,10 @@ struct FileMeta { | |||
167 | deps: Vec<String>, | 181 | deps: Vec<String>, |
168 | cfg: CfgOptions, | 182 | cfg: CfgOptions, |
169 | edition: Edition, | 183 | edition: Edition, |
184 | env: Env, | ||
170 | } | 185 | } |
171 | 186 | ||
172 | //- /lib.rs crate:foo deps:bar,baz | 187 | //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo) |
173 | fn parse_meta(meta: &str) -> ParsedMeta { | 188 | fn parse_meta(meta: &str) -> ParsedMeta { |
174 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); | 189 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); |
175 | 190 | ||
@@ -186,6 +201,7 @@ fn parse_meta(meta: &str) -> ParsedMeta { | |||
186 | let mut deps = Vec::new(); | 201 | let mut deps = Vec::new(); |
187 | let mut edition = Edition::Edition2018; | 202 | let mut edition = Edition::Edition2018; |
188 | let mut cfg = CfgOptions::default(); | 203 | let mut cfg = CfgOptions::default(); |
204 | let mut env = Env::default(); | ||
189 | for component in components[1..].iter() { | 205 | for component in components[1..].iter() { |
190 | let (key, value) = split1(component, ':').unwrap(); | 206 | let (key, value) = split1(component, ':').unwrap(); |
191 | match key { | 207 | match key { |
@@ -200,11 +216,18 @@ fn parse_meta(meta: &str) -> ParsedMeta { | |||
200 | } | 216 | } |
201 | } | 217 | } |
202 | } | 218 | } |
219 | "env" => { | ||
220 | for key in value.split(',') { | ||
221 | if let Some((k, v)) = split1(key, '=') { | ||
222 | env.set(k.into(), v.into()); | ||
223 | } | ||
224 | } | ||
225 | } | ||
203 | _ => panic!("bad component: {:?}", component), | 226 | _ => panic!("bad component: {:?}", component), |
204 | } | 227 | } |
205 | } | 228 | } |
206 | 229 | ||
207 | ParsedMeta::File(FileMeta { path, krate, deps, edition, cfg }) | 230 | ParsedMeta::File(FileMeta { path, krate, deps, edition, cfg, env }) |
208 | } | 231 | } |
209 | 232 | ||
210 | fn split1(haystack: &str, delim: char) -> Option<(&str, &str)> { | 233 | fn split1(haystack: &str, delim: char) -> Option<(&str, &str)> { |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index b77640b2b..1a1c64202 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -261,6 +261,16 @@ impl fmt::Display for Edition { | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | impl Env { | ||
265 | pub fn set(&mut self, env: &str, value: String) { | ||
266 | self.entries.insert(env.to_owned(), value); | ||
267 | } | ||
268 | |||
269 | pub fn get(&self, env: &str) -> Option<String> { | ||
270 | self.entries.get(env).cloned() | ||
271 | } | ||
272 | } | ||
273 | |||
264 | #[derive(Debug)] | 274 | #[derive(Debug)] |
265 | pub struct ParseEditionError { | 275 | pub struct ParseEditionError { |
266 | invalid_input: String, | 276 | invalid_input: String, |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 69deddcb5..2432177b4 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -202,6 +202,14 @@ pub fn parse_fixture(fixture: &str) -> Vec<FixtureEntry> { | |||
202 | res | 202 | res |
203 | } | 203 | } |
204 | 204 | ||
205 | /// Same as `parse_fixture`, except it allow empty fixture | ||
206 | pub fn parse_single_fixture(fixture: &str) -> Option<FixtureEntry> { | ||
207 | if !fixture.lines().any(|it| it.trim_start().starts_with("//-")) { | ||
208 | return None; | ||
209 | } | ||
210 | parse_fixture(fixture).into_iter().nth(0) | ||
211 | } | ||
212 | |||
205 | // Comparison functionality borrowed from cargo: | 213 | // Comparison functionality borrowed from cargo: |
206 | 214 | ||
207 | /// Compare a line with an expected pattern. | 215 | /// Compare a line with an expected pattern. |