diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-11 10:51:07 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-11 10:51:07 +0000 |
commit | c48dcf74118b6e0df747f036a9b66701037f3fc7 (patch) | |
tree | bc047c31d43d2e16428c56bf7cdf305f4a30fa66 /crates/ra_db/src/input.rs | |
parent | 7b323b45a15809a20052f13d5a8f073aaa274a86 (diff) | |
parent | 6ea7c319154f9ec10721f4041afc9d07d6b2476b (diff) |
Merge #3549
3549: Implement env! macro r=matklad a=edwin0cheng
This PR implements `env!` macro by adding following things:
1. Added `additional_outdirs` settings in vscode. (naming to be bikeshed)
2. Added `ExternSourceId` which is a wrapping for SourceRootId but only used in extern sources. It is because `OUT_DIR` is not belonged to any crate and we have to access it behind an `AstDatabase`.
3. This PR does not implement the `OUT_DIR` parsing from `cargo check`. I don't have general design about this, @kiljacken could we reuse some cargo watch code for that ?
~~Block on [#3536]~~
PS: After this PR , we (kind of) completed the `include!(concat!(env!('OUT_DIR'), "foo.rs")` macro call combo. [Exodia Obliterate!](https://www.youtube.com/watch?v=RfqNH3FoGi0)
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_db/src/input.rs')
-rw-r--r-- | crates/ra_db/src/input.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 1a1c64202..06d40db96 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -113,6 +113,7 @@ pub struct CrateData { | |||
113 | pub display_name: Option<String>, | 113 | pub display_name: Option<String>, |
114 | pub cfg_options: CfgOptions, | 114 | pub cfg_options: CfgOptions, |
115 | pub env: Env, | 115 | pub env: Env, |
116 | pub extern_source: ExternSource, | ||
116 | pub dependencies: Vec<Dependency>, | 117 | pub dependencies: Vec<Dependency>, |
117 | } | 118 | } |
118 | 119 | ||
@@ -122,11 +123,22 @@ pub enum Edition { | |||
122 | Edition2015, | 123 | Edition2015, |
123 | } | 124 | } |
124 | 125 | ||
126 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
127 | pub struct ExternSourceId(pub u32); | ||
128 | |||
125 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 129 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
126 | pub struct Env { | 130 | pub struct Env { |
127 | entries: FxHashMap<String, String>, | 131 | entries: FxHashMap<String, String>, |
128 | } | 132 | } |
129 | 133 | ||
134 | // FIXME: Redesign vfs for solve the following limitation ? | ||
135 | // Note: Some env variables (e.g. OUT_DIR) are located outside of the | ||
136 | // crate. We store a map to allow remap it to ExternSourceId | ||
137 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | ||
138 | pub struct ExternSource { | ||
139 | extern_paths: FxHashMap<String, ExternSourceId>, | ||
140 | } | ||
141 | |||
130 | #[derive(Debug, Clone, PartialEq, Eq)] | 142 | #[derive(Debug, Clone, PartialEq, Eq)] |
131 | pub struct Dependency { | 143 | pub struct Dependency { |
132 | pub crate_id: CrateId, | 144 | pub crate_id: CrateId, |
@@ -141,6 +153,7 @@ impl CrateGraph { | |||
141 | display_name: Option<String>, | 153 | display_name: Option<String>, |
142 | cfg_options: CfgOptions, | 154 | cfg_options: CfgOptions, |
143 | env: Env, | 155 | env: Env, |
156 | extern_source: ExternSource, | ||
144 | ) -> CrateId { | 157 | ) -> CrateId { |
145 | let data = CrateData { | 158 | let data = CrateData { |
146 | root_file_id: file_id, | 159 | root_file_id: file_id, |
@@ -148,6 +161,7 @@ impl CrateGraph { | |||
148 | display_name, | 161 | display_name, |
149 | cfg_options, | 162 | cfg_options, |
150 | env, | 163 | env, |
164 | extern_source, | ||
151 | dependencies: Vec::new(), | 165 | dependencies: Vec::new(), |
152 | }; | 166 | }; |
153 | let crate_id = CrateId(self.arena.len() as u32); | 167 | let crate_id = CrateId(self.arena.len() as u32); |
@@ -271,6 +285,27 @@ impl Env { | |||
271 | } | 285 | } |
272 | } | 286 | } |
273 | 287 | ||
288 | impl ExternSource { | ||
289 | pub fn extern_path(&self, path: &str) -> Option<(ExternSourceId, RelativePathBuf)> { | ||
290 | self.extern_paths.iter().find_map(|(root_path, id)| { | ||
291 | if path.starts_with(root_path) { | ||
292 | let mut rel_path = &path[root_path.len()..]; | ||
293 | if rel_path.starts_with("/") { | ||
294 | rel_path = &rel_path[1..]; | ||
295 | } | ||
296 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
297 | Some((id.clone(), rel_path)) | ||
298 | } else { | ||
299 | None | ||
300 | } | ||
301 | }) | ||
302 | } | ||
303 | |||
304 | pub fn set_extern_path(&mut self, root_path: &str, root: ExternSourceId) { | ||
305 | self.extern_paths.insert(root_path.to_owned(), root); | ||
306 | } | ||
307 | } | ||
308 | |||
274 | #[derive(Debug)] | 309 | #[derive(Debug)] |
275 | pub struct ParseEditionError { | 310 | pub struct ParseEditionError { |
276 | invalid_input: String, | 311 | invalid_input: String, |
@@ -300,6 +335,7 @@ mod tests { | |||
300 | None, | 335 | None, |
301 | CfgOptions::default(), | 336 | CfgOptions::default(), |
302 | Env::default(), | 337 | Env::default(), |
338 | Default::default(), | ||
303 | ); | 339 | ); |
304 | let crate2 = graph.add_crate_root( | 340 | let crate2 = graph.add_crate_root( |
305 | FileId(2u32), | 341 | FileId(2u32), |
@@ -307,6 +343,7 @@ mod tests { | |||
307 | None, | 343 | None, |
308 | CfgOptions::default(), | 344 | CfgOptions::default(), |
309 | Env::default(), | 345 | Env::default(), |
346 | Default::default(), | ||
310 | ); | 347 | ); |
311 | let crate3 = graph.add_crate_root( | 348 | let crate3 = graph.add_crate_root( |
312 | FileId(3u32), | 349 | FileId(3u32), |
@@ -314,6 +351,7 @@ mod tests { | |||
314 | None, | 351 | None, |
315 | CfgOptions::default(), | 352 | CfgOptions::default(), |
316 | Env::default(), | 353 | Env::default(), |
354 | Default::default(), | ||
317 | ); | 355 | ); |
318 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 356 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
319 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); | 357 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
@@ -329,6 +367,7 @@ mod tests { | |||
329 | None, | 367 | None, |
330 | CfgOptions::default(), | 368 | CfgOptions::default(), |
331 | Env::default(), | 369 | Env::default(), |
370 | Default::default(), | ||
332 | ); | 371 | ); |
333 | let crate2 = graph.add_crate_root( | 372 | let crate2 = graph.add_crate_root( |
334 | FileId(2u32), | 373 | FileId(2u32), |
@@ -336,6 +375,7 @@ mod tests { | |||
336 | None, | 375 | None, |
337 | CfgOptions::default(), | 376 | CfgOptions::default(), |
338 | Env::default(), | 377 | Env::default(), |
378 | Default::default(), | ||
339 | ); | 379 | ); |
340 | let crate3 = graph.add_crate_root( | 380 | let crate3 = graph.add_crate_root( |
341 | FileId(3u32), | 381 | FileId(3u32), |
@@ -343,6 +383,7 @@ mod tests { | |||
343 | None, | 383 | None, |
344 | CfgOptions::default(), | 384 | CfgOptions::default(), |
345 | Env::default(), | 385 | Env::default(), |
386 | Default::default(), | ||
346 | ); | 387 | ); |
347 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 388 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
348 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); | 389 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
@@ -357,6 +398,7 @@ mod tests { | |||
357 | None, | 398 | None, |
358 | CfgOptions::default(), | 399 | CfgOptions::default(), |
359 | Env::default(), | 400 | Env::default(), |
401 | Default::default(), | ||
360 | ); | 402 | ); |
361 | let crate2 = graph.add_crate_root( | 403 | let crate2 = graph.add_crate_root( |
362 | FileId(2u32), | 404 | FileId(2u32), |
@@ -364,6 +406,7 @@ mod tests { | |||
364 | None, | 406 | None, |
365 | CfgOptions::default(), | 407 | CfgOptions::default(), |
366 | Env::default(), | 408 | Env::default(), |
409 | Default::default(), | ||
367 | ); | 410 | ); |
368 | assert!(graph | 411 | assert!(graph |
369 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) | 412 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) |