aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_db/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-11 10:51:07 +0000
committerGitHub <[email protected]>2020-03-11 10:51:07 +0000
commitc48dcf74118b6e0df747f036a9b66701037f3fc7 (patch)
treebc047c31d43d2e16428c56bf7cdf305f4a30fa66 /crates/ra_db/src
parent7b323b45a15809a20052f13d5a8f073aaa274a86 (diff)
parent6ea7c319154f9ec10721f4041afc9d07d6b2476b (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')
-rw-r--r--crates/ra_db/src/fixture.rs12
-rw-r--r--crates/ra_db/src/input.rs43
-rw-r--r--crates/ra_db/src/lib.rs18
3 files changed, 71 insertions, 2 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 7f43c2971..3dc86ca2d 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -61,7 +61,14 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
61 }; 61 };
62 62
63 let mut crate_graph = CrateGraph::default(); 63 let mut crate_graph = CrateGraph::default();
64 crate_graph.add_crate_root(file_id, meta.edition, meta.krate, meta.cfg, meta.env); 64 crate_graph.add_crate_root(
65 file_id,
66 meta.edition,
67 meta.krate,
68 meta.cfg,
69 meta.env,
70 Default::default(),
71 );
65 crate_graph 72 crate_graph
66 } else { 73 } else {
67 let mut crate_graph = CrateGraph::default(); 74 let mut crate_graph = CrateGraph::default();
@@ -71,6 +78,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
71 None, 78 None,
72 CfgOptions::default(), 79 CfgOptions::default(),
73 Env::default(), 80 Env::default(),
81 Default::default(),
74 ); 82 );
75 crate_graph 83 crate_graph
76 }; 84 };
@@ -119,6 +127,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
119 Some(krate.clone()), 127 Some(krate.clone()),
120 meta.cfg, 128 meta.cfg,
121 meta.env, 129 meta.env,
130 Default::default(),
122 ); 131 );
123 let prev = crates.insert(krate.clone(), crate_id); 132 let prev = crates.insert(krate.clone(), crate_id);
124 assert!(prev.is_none()); 133 assert!(prev.is_none());
@@ -155,6 +164,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
155 None, 164 None,
156 CfgOptions::default(), 165 CfgOptions::default(),
157 Env::default(), 166 Env::default(),
167 Default::default(),
158 ); 168 );
159 } else { 169 } else {
160 for (from, to) in crate_deps { 170 for (from, to) in crate_deps {
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)]
127pub struct ExternSourceId(pub u32);
128
125#[derive(Default, Debug, Clone, PartialEq, Eq)] 129#[derive(Default, Debug, Clone, PartialEq, Eq)]
126pub struct Env { 130pub 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)]
138pub struct ExternSource {
139 extern_paths: FxHashMap<String, ExternSourceId>,
140}
141
130#[derive(Debug, Clone, PartialEq, Eq)] 142#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct Dependency { 143pub 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
288impl 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)]
275pub struct ParseEditionError { 310pub 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)
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
index fb002d717..d500d5e85 100644
--- a/crates/ra_db/src/lib.rs
+++ b/crates/ra_db/src/lib.rs
@@ -11,7 +11,8 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
11pub use crate::{ 11pub use crate::{
12 cancellation::Canceled, 12 cancellation::Canceled,
13 input::{ 13 input::{
14 CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId, 14 CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId,
15 FileId, SourceRoot, SourceRootId,
15 }, 16 },
16}; 17};
17pub use relative_path::{RelativePath, RelativePathBuf}; 18pub use relative_path::{RelativePath, RelativePathBuf};
@@ -87,6 +88,12 @@ pub trait FileLoader {
87 fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath) 88 fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath)
88 -> Option<FileId>; 89 -> Option<FileId>;
89 fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>; 90 fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>;
91
92 fn resolve_extern_path(
93 &self,
94 extern_id: ExternSourceId,
95 relative_path: &RelativePath,
96 ) -> Option<FileId>;
90} 97}
91 98
92/// Database which stores all significant input facts: source code and project 99/// Database which stores all significant input facts: source code and project
@@ -164,4 +171,13 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
164 let source_root = self.0.file_source_root(file_id); 171 let source_root = self.0.file_source_root(file_id);
165 self.0.source_root_crates(source_root) 172 self.0.source_root_crates(source_root)
166 } 173 }
174
175 fn resolve_extern_path(
176 &self,
177 extern_id: ExternSourceId,
178 relative_path: &RelativePath,
179 ) -> Option<FileId> {
180 let source_root = self.0.source_root(SourceRootId(extern_id.0));
181 source_root.file_by_relative_path(&relative_path)
182 }
167} 183}