diff options
Diffstat (limited to 'crates/ra_db')
-rw-r--r-- | crates/ra_db/src/fixture.rs | 70 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 195 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 18 |
3 files changed, 213 insertions, 70 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index da7af110c..3dc86ca2d 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,22 +45,45 @@ 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 | CfgOptions::default(), | 59 | ParsedMeta::File(it) => it, |
60 | Env::default(), | 60 | _ => panic!("with_single_file only support file meta"), |
61 | ); | 61 | }; |
62 | 62 | ||
63 | db.set_file_text(file_id, Arc::new(text.to_string())); | 63 | let mut crate_graph = CrateGraph::default(); |
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 | ); | ||
72 | crate_graph | ||
73 | } else { | ||
74 | let mut crate_graph = CrateGraph::default(); | ||
75 | crate_graph.add_crate_root( | ||
76 | file_id, | ||
77 | Edition::Edition2018, | ||
78 | None, | ||
79 | CfgOptions::default(), | ||
80 | Env::default(), | ||
81 | Default::default(), | ||
82 | ); | ||
83 | crate_graph | ||
84 | }; | ||
85 | |||
86 | db.set_file_text(file_id, Arc::new(ra_fixture.to_string())); | ||
64 | db.set_file_relative_path(file_id, rel_path); | 87 | db.set_file_relative_path(file_id, rel_path); |
65 | db.set_file_source_root(file_id, WORKSPACE); | 88 | db.set_file_source_root(file_id, WORKSPACE); |
66 | db.set_source_root(WORKSPACE, Arc::new(source_root)); | 89 | db.set_source_root(WORKSPACE, Arc::new(source_root)); |
@@ -98,8 +121,14 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
98 | assert!(meta.path.starts_with(&source_root_prefix)); | 121 | assert!(meta.path.starts_with(&source_root_prefix)); |
99 | 122 | ||
100 | if let Some(krate) = meta.krate { | 123 | if let Some(krate) = meta.krate { |
101 | let crate_id = | 124 | let crate_id = crate_graph.add_crate_root( |
102 | crate_graph.add_crate_root(file_id, meta.edition, meta.cfg, Env::default()); | 125 | file_id, |
126 | meta.edition, | ||
127 | Some(krate.clone()), | ||
128 | meta.cfg, | ||
129 | meta.env, | ||
130 | Default::default(), | ||
131 | ); | ||
103 | let prev = crates.insert(krate.clone(), crate_id); | 132 | let prev = crates.insert(krate.clone(), crate_id); |
104 | assert!(prev.is_none()); | 133 | assert!(prev.is_none()); |
105 | for dep in meta.deps { | 134 | for dep in meta.deps { |
@@ -132,8 +161,10 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
132 | crate_graph.add_crate_root( | 161 | crate_graph.add_crate_root( |
133 | crate_root, | 162 | crate_root, |
134 | Edition::Edition2018, | 163 | Edition::Edition2018, |
164 | None, | ||
135 | CfgOptions::default(), | 165 | CfgOptions::default(), |
136 | Env::default(), | 166 | Env::default(), |
167 | Default::default(), | ||
137 | ); | 168 | ); |
138 | } else { | 169 | } else { |
139 | for (from, to) in crate_deps { | 170 | for (from, to) in crate_deps { |
@@ -160,9 +191,10 @@ struct FileMeta { | |||
160 | deps: Vec<String>, | 191 | deps: Vec<String>, |
161 | cfg: CfgOptions, | 192 | cfg: CfgOptions, |
162 | edition: Edition, | 193 | edition: Edition, |
194 | env: Env, | ||
163 | } | 195 | } |
164 | 196 | ||
165 | //- /lib.rs crate:foo deps:bar,baz | 197 | //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo) |
166 | fn parse_meta(meta: &str) -> ParsedMeta { | 198 | fn parse_meta(meta: &str) -> ParsedMeta { |
167 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); | 199 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); |
168 | 200 | ||
@@ -179,6 +211,7 @@ fn parse_meta(meta: &str) -> ParsedMeta { | |||
179 | let mut deps = Vec::new(); | 211 | let mut deps = Vec::new(); |
180 | let mut edition = Edition::Edition2018; | 212 | let mut edition = Edition::Edition2018; |
181 | let mut cfg = CfgOptions::default(); | 213 | let mut cfg = CfgOptions::default(); |
214 | let mut env = Env::default(); | ||
182 | for component in components[1..].iter() { | 215 | for component in components[1..].iter() { |
183 | let (key, value) = split1(component, ':').unwrap(); | 216 | let (key, value) = split1(component, ':').unwrap(); |
184 | match key { | 217 | match key { |
@@ -193,11 +226,18 @@ fn parse_meta(meta: &str) -> ParsedMeta { | |||
193 | } | 226 | } |
194 | } | 227 | } |
195 | } | 228 | } |
229 | "env" => { | ||
230 | for key in value.split(',') { | ||
231 | if let Some((k, v)) = split1(key, '=') { | ||
232 | env.set(k.into(), v.into()); | ||
233 | } | ||
234 | } | ||
235 | } | ||
196 | _ => panic!("bad component: {:?}", component), | 236 | _ => panic!("bad component: {:?}", component), |
197 | } | 237 | } |
198 | } | 238 | } |
199 | 239 | ||
200 | ParsedMeta::File(FileMeta { path, krate, deps, edition, cfg }) | 240 | ParsedMeta::File(FileMeta { path, krate, deps, edition, cfg, env }) |
201 | } | 241 | } |
202 | 242 | ||
203 | fn split1(haystack: &str, delim: char) -> Option<(&str, &str)> { | 243 | 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 eaff99fd3..06d40db96 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -6,7 +6,7 @@ | |||
6 | //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how | 6 | //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how |
7 | //! actual IO is done and lowered to input. | 7 | //! actual IO is done and lowered to input. |
8 | 8 | ||
9 | use std::{fmt, str::FromStr}; | 9 | use std::{fmt, ops, str::FromStr}; |
10 | 10 | ||
11 | use ra_cfg::CfgOptions; | 11 | use ra_cfg::CfgOptions; |
12 | use ra_syntax::SmolStr; | 12 | use ra_syntax::SmolStr; |
@@ -86,7 +86,7 @@ pub struct CrateId(pub u32); | |||
86 | pub struct CrateName(SmolStr); | 86 | pub struct CrateName(SmolStr); |
87 | 87 | ||
88 | impl CrateName { | 88 | impl CrateName { |
89 | /// Crates a crate name, checking for dashes in the string provided. | 89 | /// Creates a crate name, checking for dashes in the string provided. |
90 | /// Dashes are not allowed in the crate names, | 90 | /// Dashes are not allowed in the crate names, |
91 | /// hence the input string is returned as `Err` for those cases. | 91 | /// hence the input string is returned as `Err` for those cases. |
92 | pub fn new(name: &str) -> Result<CrateName, &str> { | 92 | pub fn new(name: &str) -> Result<CrateName, &str> { |
@@ -97,19 +97,24 @@ impl CrateName { | |||
97 | } | 97 | } |
98 | } | 98 | } |
99 | 99 | ||
100 | /// Crates a crate name, unconditionally replacing the dashes with underscores. | 100 | /// Creates a crate name, unconditionally replacing the dashes with underscores. |
101 | pub fn normalize_dashes(name: &str) -> CrateName { | 101 | pub fn normalize_dashes(name: &str) -> CrateName { |
102 | Self(SmolStr::new(name.replace('-', "_"))) | 102 | Self(SmolStr::new(name.replace('-', "_"))) |
103 | } | 103 | } |
104 | } | 104 | } |
105 | 105 | ||
106 | #[derive(Debug, Clone, PartialEq, Eq)] | 106 | #[derive(Debug, Clone, PartialEq, Eq)] |
107 | struct CrateData { | 107 | pub struct CrateData { |
108 | file_id: FileId, | 108 | pub root_file_id: FileId, |
109 | edition: Edition, | 109 | pub edition: Edition, |
110 | cfg_options: CfgOptions, | 110 | /// The name to display to the end user. |
111 | env: Env, | 111 | /// This actual crate name can be different in a particular dependent crate |
112 | dependencies: Vec<Dependency>, | 112 | /// or may even be missing for some cases, such as a dummy crate for the code snippet. |
113 | pub display_name: Option<String>, | ||
114 | pub cfg_options: CfgOptions, | ||
115 | pub env: Env, | ||
116 | pub extern_source: ExternSource, | ||
117 | pub dependencies: Vec<Dependency>, | ||
113 | } | 118 | } |
114 | 119 | ||
115 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 120 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -118,11 +123,22 @@ pub enum Edition { | |||
118 | Edition2015, | 123 | Edition2015, |
119 | } | 124 | } |
120 | 125 | ||
126 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
127 | pub struct ExternSourceId(pub u32); | ||
128 | |||
121 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 129 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
122 | pub struct Env { | 130 | pub struct Env { |
123 | entries: FxHashMap<String, String>, | 131 | entries: FxHashMap<String, String>, |
124 | } | 132 | } |
125 | 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 | |||
126 | #[derive(Debug, Clone, PartialEq, Eq)] | 142 | #[derive(Debug, Clone, PartialEq, Eq)] |
127 | pub struct Dependency { | 143 | pub struct Dependency { |
128 | pub crate_id: CrateId, | 144 | pub crate_id: CrateId, |
@@ -134,20 +150,26 @@ impl CrateGraph { | |||
134 | &mut self, | 150 | &mut self, |
135 | file_id: FileId, | 151 | file_id: FileId, |
136 | edition: Edition, | 152 | edition: Edition, |
153 | display_name: Option<String>, | ||
137 | cfg_options: CfgOptions, | 154 | cfg_options: CfgOptions, |
138 | env: Env, | 155 | env: Env, |
156 | extern_source: ExternSource, | ||
139 | ) -> CrateId { | 157 | ) -> CrateId { |
140 | let data = CrateData::new(file_id, edition, cfg_options, env); | 158 | let data = CrateData { |
159 | root_file_id: file_id, | ||
160 | edition, | ||
161 | display_name, | ||
162 | cfg_options, | ||
163 | env, | ||
164 | extern_source, | ||
165 | dependencies: Vec::new(), | ||
166 | }; | ||
141 | let crate_id = CrateId(self.arena.len() as u32); | 167 | let crate_id = CrateId(self.arena.len() as u32); |
142 | let prev = self.arena.insert(crate_id, data); | 168 | let prev = self.arena.insert(crate_id, data); |
143 | assert!(prev.is_none()); | 169 | assert!(prev.is_none()); |
144 | crate_id | 170 | crate_id |
145 | } | 171 | } |
146 | 172 | ||
147 | pub fn cfg_options(&self, crate_id: CrateId) -> &CfgOptions { | ||
148 | &self.arena[&crate_id].cfg_options | ||
149 | } | ||
150 | |||
151 | pub fn add_dep( | 173 | pub fn add_dep( |
152 | &mut self, | 174 | &mut self, |
153 | from: CrateId, | 175 | from: CrateId, |
@@ -169,24 +191,13 @@ impl CrateGraph { | |||
169 | self.arena.keys().copied() | 191 | self.arena.keys().copied() |
170 | } | 192 | } |
171 | 193 | ||
172 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | ||
173 | self.arena[&crate_id].file_id | ||
174 | } | ||
175 | |||
176 | pub fn edition(&self, crate_id: CrateId) -> Edition { | ||
177 | self.arena[&crate_id].edition | ||
178 | } | ||
179 | |||
180 | // FIXME: this only finds one crate with the given root; we could have multiple | 194 | // FIXME: this only finds one crate with the given root; we could have multiple |
181 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 195 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
182 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; | 196 | let (&crate_id, _) = |
197 | self.arena.iter().find(|(_crate_id, data)| data.root_file_id == file_id)?; | ||
183 | Some(crate_id) | 198 | Some(crate_id) |
184 | } | 199 | } |
185 | 200 | ||
186 | pub fn dependencies(&self, crate_id: CrateId) -> impl Iterator<Item = &Dependency> { | ||
187 | self.arena[&crate_id].dependencies.iter() | ||
188 | } | ||
189 | |||
190 | /// Extends this crate graph by adding a complete disjoint second crate | 201 | /// Extends this crate graph by adding a complete disjoint second crate |
191 | /// graph. | 202 | /// graph. |
192 | /// | 203 | /// |
@@ -209,8 +220,8 @@ impl CrateGraph { | |||
209 | return false; | 220 | return false; |
210 | } | 221 | } |
211 | 222 | ||
212 | for dep in self.dependencies(from) { | 223 | for dep in &self[from].dependencies { |
213 | let crate_id = dep.crate_id(); | 224 | let crate_id = dep.crate_id; |
214 | if crate_id == target { | 225 | if crate_id == target { |
215 | return true; | 226 | return true; |
216 | } | 227 | } |
@@ -223,6 +234,13 @@ impl CrateGraph { | |||
223 | } | 234 | } |
224 | } | 235 | } |
225 | 236 | ||
237 | impl ops::Index<CrateId> for CrateGraph { | ||
238 | type Output = CrateData; | ||
239 | fn index(&self, crate_id: CrateId) -> &CrateData { | ||
240 | &self.arena[&crate_id] | ||
241 | } | ||
242 | } | ||
243 | |||
226 | impl CrateId { | 244 | impl CrateId { |
227 | pub fn shift(self, amount: u32) -> CrateId { | 245 | pub fn shift(self, amount: u32) -> CrateId { |
228 | CrateId(self.0 + amount) | 246 | CrateId(self.0 + amount) |
@@ -230,10 +248,6 @@ impl CrateId { | |||
230 | } | 248 | } |
231 | 249 | ||
232 | impl CrateData { | 250 | impl CrateData { |
233 | fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData { | ||
234 | CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env } | ||
235 | } | ||
236 | |||
237 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 251 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
238 | self.dependencies.push(Dependency { name, crate_id }) | 252 | self.dependencies.push(Dependency { name, crate_id }) |
239 | } | 253 | } |
@@ -261,9 +275,34 @@ impl fmt::Display for Edition { | |||
261 | } | 275 | } |
262 | } | 276 | } |
263 | 277 | ||
264 | impl Dependency { | 278 | impl Env { |
265 | pub fn crate_id(&self) -> CrateId { | 279 | pub fn set(&mut self, env: &str, value: String) { |
266 | self.crate_id | 280 | self.entries.insert(env.to_owned(), value); |
281 | } | ||
282 | |||
283 | pub fn get(&self, env: &str) -> Option<String> { | ||
284 | self.entries.get(env).cloned() | ||
285 | } | ||
286 | } | ||
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); | ||
267 | } | 306 | } |
268 | } | 307 | } |
269 | 308 | ||
@@ -290,12 +329,30 @@ mod tests { | |||
290 | #[test] | 329 | #[test] |
291 | fn it_should_panic_because_of_cycle_dependencies() { | 330 | fn it_should_panic_because_of_cycle_dependencies() { |
292 | let mut graph = CrateGraph::default(); | 331 | let mut graph = CrateGraph::default(); |
293 | let crate1 = | 332 | let crate1 = graph.add_crate_root( |
294 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 333 | FileId(1u32), |
295 | let crate2 = | 334 | Edition2018, |
296 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 335 | None, |
297 | let crate3 = | 336 | CfgOptions::default(), |
298 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 337 | Env::default(), |
338 | Default::default(), | ||
339 | ); | ||
340 | let crate2 = graph.add_crate_root( | ||
341 | FileId(2u32), | ||
342 | Edition2018, | ||
343 | None, | ||
344 | CfgOptions::default(), | ||
345 | Env::default(), | ||
346 | Default::default(), | ||
347 | ); | ||
348 | let crate3 = graph.add_crate_root( | ||
349 | FileId(3u32), | ||
350 | Edition2018, | ||
351 | None, | ||
352 | CfgOptions::default(), | ||
353 | Env::default(), | ||
354 | Default::default(), | ||
355 | ); | ||
299 | 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()); |
300 | 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()); |
301 | assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); | 358 | assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); |
@@ -304,12 +361,30 @@ mod tests { | |||
304 | #[test] | 361 | #[test] |
305 | fn it_works() { | 362 | fn it_works() { |
306 | let mut graph = CrateGraph::default(); | 363 | let mut graph = CrateGraph::default(); |
307 | let crate1 = | 364 | let crate1 = graph.add_crate_root( |
308 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 365 | FileId(1u32), |
309 | let crate2 = | 366 | Edition2018, |
310 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 367 | None, |
311 | let crate3 = | 368 | CfgOptions::default(), |
312 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 369 | Env::default(), |
370 | Default::default(), | ||
371 | ); | ||
372 | let crate2 = graph.add_crate_root( | ||
373 | FileId(2u32), | ||
374 | Edition2018, | ||
375 | None, | ||
376 | CfgOptions::default(), | ||
377 | Env::default(), | ||
378 | Default::default(), | ||
379 | ); | ||
380 | let crate3 = graph.add_crate_root( | ||
381 | FileId(3u32), | ||
382 | Edition2018, | ||
383 | None, | ||
384 | CfgOptions::default(), | ||
385 | Env::default(), | ||
386 | Default::default(), | ||
387 | ); | ||
313 | 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()); |
314 | 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()); |
315 | } | 390 | } |
@@ -317,16 +392,28 @@ mod tests { | |||
317 | #[test] | 392 | #[test] |
318 | fn dashes_are_normalized() { | 393 | fn dashes_are_normalized() { |
319 | let mut graph = CrateGraph::default(); | 394 | let mut graph = CrateGraph::default(); |
320 | let crate1 = | 395 | let crate1 = graph.add_crate_root( |
321 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 396 | FileId(1u32), |
322 | let crate2 = | 397 | Edition2018, |
323 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 398 | None, |
399 | CfgOptions::default(), | ||
400 | Env::default(), | ||
401 | Default::default(), | ||
402 | ); | ||
403 | let crate2 = graph.add_crate_root( | ||
404 | FileId(2u32), | ||
405 | Edition2018, | ||
406 | None, | ||
407 | CfgOptions::default(), | ||
408 | Env::default(), | ||
409 | Default::default(), | ||
410 | ); | ||
324 | assert!(graph | 411 | assert!(graph |
325 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) | 412 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) |
326 | .is_ok()); | 413 | .is_ok()); |
327 | assert_eq!( | 414 | assert_eq!( |
328 | graph.dependencies(crate1).collect::<Vec<_>>(), | 415 | graph[crate1].dependencies, |
329 | vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] | 416 | vec![Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] |
330 | ); | 417 | ); |
331 | } | 418 | } |
332 | } | 419 | } |
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}; | |||
11 | pub use crate::{ | 11 | pub 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 | }; |
17 | pub use relative_path::{RelativePath, RelativePathBuf}; | 18 | pub 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 | } |