diff options
Diffstat (limited to 'crates/ra_db')
-rw-r--r-- | crates/ra_db/src/fixture.rs | 11 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 148 |
2 files changed, 100 insertions, 59 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index da7af110c..947d6ad56 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -56,6 +56,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId { | |||
56 | crate_graph.add_crate_root( | 56 | crate_graph.add_crate_root( |
57 | file_id, | 57 | file_id, |
58 | Edition::Edition2018, | 58 | Edition::Edition2018, |
59 | None, | ||
59 | CfgOptions::default(), | 60 | CfgOptions::default(), |
60 | Env::default(), | 61 | Env::default(), |
61 | ); | 62 | ); |
@@ -98,8 +99,13 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
98 | assert!(meta.path.starts_with(&source_root_prefix)); | 99 | assert!(meta.path.starts_with(&source_root_prefix)); |
99 | 100 | ||
100 | if let Some(krate) = meta.krate { | 101 | if let Some(krate) = meta.krate { |
101 | let crate_id = | 102 | let crate_id = crate_graph.add_crate_root( |
102 | crate_graph.add_crate_root(file_id, meta.edition, meta.cfg, Env::default()); | 103 | file_id, |
104 | meta.edition, | ||
105 | Some(krate.clone()), | ||
106 | meta.cfg, | ||
107 | Env::default(), | ||
108 | ); | ||
103 | let prev = crates.insert(krate.clone(), crate_id); | 109 | let prev = crates.insert(krate.clone(), crate_id); |
104 | assert!(prev.is_none()); | 110 | assert!(prev.is_none()); |
105 | for dep in meta.deps { | 111 | for dep in meta.deps { |
@@ -132,6 +138,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
132 | crate_graph.add_crate_root( | 138 | crate_graph.add_crate_root( |
133 | crate_root, | 139 | crate_root, |
134 | Edition::Edition2018, | 140 | Edition::Edition2018, |
141 | None, | ||
135 | CfgOptions::default(), | 142 | CfgOptions::default(), |
136 | Env::default(), | 143 | Env::default(), |
137 | ); | 144 | ); |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index eaff99fd3..b77640b2b 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,23 @@ 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 dependencies: Vec<Dependency>, | ||
113 | } | 117 | } |
114 | 118 | ||
115 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 119 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -134,20 +138,24 @@ impl CrateGraph { | |||
134 | &mut self, | 138 | &mut self, |
135 | file_id: FileId, | 139 | file_id: FileId, |
136 | edition: Edition, | 140 | edition: Edition, |
141 | display_name: Option<String>, | ||
137 | cfg_options: CfgOptions, | 142 | cfg_options: CfgOptions, |
138 | env: Env, | 143 | env: Env, |
139 | ) -> CrateId { | 144 | ) -> CrateId { |
140 | let data = CrateData::new(file_id, edition, cfg_options, env); | 145 | let data = CrateData { |
146 | root_file_id: file_id, | ||
147 | edition, | ||
148 | display_name, | ||
149 | cfg_options, | ||
150 | env, | ||
151 | dependencies: Vec::new(), | ||
152 | }; | ||
141 | let crate_id = CrateId(self.arena.len() as u32); | 153 | let crate_id = CrateId(self.arena.len() as u32); |
142 | let prev = self.arena.insert(crate_id, data); | 154 | let prev = self.arena.insert(crate_id, data); |
143 | assert!(prev.is_none()); | 155 | assert!(prev.is_none()); |
144 | crate_id | 156 | crate_id |
145 | } | 157 | } |
146 | 158 | ||
147 | pub fn cfg_options(&self, crate_id: CrateId) -> &CfgOptions { | ||
148 | &self.arena[&crate_id].cfg_options | ||
149 | } | ||
150 | |||
151 | pub fn add_dep( | 159 | pub fn add_dep( |
152 | &mut self, | 160 | &mut self, |
153 | from: CrateId, | 161 | from: CrateId, |
@@ -169,24 +177,13 @@ impl CrateGraph { | |||
169 | self.arena.keys().copied() | 177 | self.arena.keys().copied() |
170 | } | 178 | } |
171 | 179 | ||
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 | 180 | // 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> { | 181 | 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)?; | 182 | let (&crate_id, _) = |
183 | self.arena.iter().find(|(_crate_id, data)| data.root_file_id == file_id)?; | ||
183 | Some(crate_id) | 184 | Some(crate_id) |
184 | } | 185 | } |
185 | 186 | ||
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 | 187 | /// Extends this crate graph by adding a complete disjoint second crate |
191 | /// graph. | 188 | /// graph. |
192 | /// | 189 | /// |
@@ -209,8 +206,8 @@ impl CrateGraph { | |||
209 | return false; | 206 | return false; |
210 | } | 207 | } |
211 | 208 | ||
212 | for dep in self.dependencies(from) { | 209 | for dep in &self[from].dependencies { |
213 | let crate_id = dep.crate_id(); | 210 | let crate_id = dep.crate_id; |
214 | if crate_id == target { | 211 | if crate_id == target { |
215 | return true; | 212 | return true; |
216 | } | 213 | } |
@@ -223,6 +220,13 @@ impl CrateGraph { | |||
223 | } | 220 | } |
224 | } | 221 | } |
225 | 222 | ||
223 | impl ops::Index<CrateId> for CrateGraph { | ||
224 | type Output = CrateData; | ||
225 | fn index(&self, crate_id: CrateId) -> &CrateData { | ||
226 | &self.arena[&crate_id] | ||
227 | } | ||
228 | } | ||
229 | |||
226 | impl CrateId { | 230 | impl CrateId { |
227 | pub fn shift(self, amount: u32) -> CrateId { | 231 | pub fn shift(self, amount: u32) -> CrateId { |
228 | CrateId(self.0 + amount) | 232 | CrateId(self.0 + amount) |
@@ -230,10 +234,6 @@ impl CrateId { | |||
230 | } | 234 | } |
231 | 235 | ||
232 | impl CrateData { | 236 | 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) { | 237 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
238 | self.dependencies.push(Dependency { name, crate_id }) | 238 | self.dependencies.push(Dependency { name, crate_id }) |
239 | } | 239 | } |
@@ -261,12 +261,6 @@ impl fmt::Display for Edition { | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | impl Dependency { | ||
265 | pub fn crate_id(&self) -> CrateId { | ||
266 | self.crate_id | ||
267 | } | ||
268 | } | ||
269 | |||
270 | #[derive(Debug)] | 264 | #[derive(Debug)] |
271 | pub struct ParseEditionError { | 265 | pub struct ParseEditionError { |
272 | invalid_input: String, | 266 | invalid_input: String, |
@@ -290,12 +284,27 @@ mod tests { | |||
290 | #[test] | 284 | #[test] |
291 | fn it_should_panic_because_of_cycle_dependencies() { | 285 | fn it_should_panic_because_of_cycle_dependencies() { |
292 | let mut graph = CrateGraph::default(); | 286 | let mut graph = CrateGraph::default(); |
293 | let crate1 = | 287 | let crate1 = graph.add_crate_root( |
294 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 288 | FileId(1u32), |
295 | let crate2 = | 289 | Edition2018, |
296 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 290 | None, |
297 | let crate3 = | 291 | CfgOptions::default(), |
298 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 292 | Env::default(), |
293 | ); | ||
294 | let crate2 = graph.add_crate_root( | ||
295 | FileId(2u32), | ||
296 | Edition2018, | ||
297 | None, | ||
298 | CfgOptions::default(), | ||
299 | Env::default(), | ||
300 | ); | ||
301 | let crate3 = graph.add_crate_root( | ||
302 | FileId(3u32), | ||
303 | Edition2018, | ||
304 | None, | ||
305 | CfgOptions::default(), | ||
306 | Env::default(), | ||
307 | ); | ||
299 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 308 | 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()); | 309 | 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()); | 310 | assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); |
@@ -304,12 +313,27 @@ mod tests { | |||
304 | #[test] | 313 | #[test] |
305 | fn it_works() { | 314 | fn it_works() { |
306 | let mut graph = CrateGraph::default(); | 315 | let mut graph = CrateGraph::default(); |
307 | let crate1 = | 316 | let crate1 = graph.add_crate_root( |
308 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 317 | FileId(1u32), |
309 | let crate2 = | 318 | Edition2018, |
310 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 319 | None, |
311 | let crate3 = | 320 | CfgOptions::default(), |
312 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | 321 | Env::default(), |
322 | ); | ||
323 | let crate2 = graph.add_crate_root( | ||
324 | FileId(2u32), | ||
325 | Edition2018, | ||
326 | None, | ||
327 | CfgOptions::default(), | ||
328 | Env::default(), | ||
329 | ); | ||
330 | let crate3 = graph.add_crate_root( | ||
331 | FileId(3u32), | ||
332 | Edition2018, | ||
333 | None, | ||
334 | CfgOptions::default(), | ||
335 | Env::default(), | ||
336 | ); | ||
313 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 337 | 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()); | 338 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
315 | } | 339 | } |
@@ -317,16 +341,26 @@ mod tests { | |||
317 | #[test] | 341 | #[test] |
318 | fn dashes_are_normalized() { | 342 | fn dashes_are_normalized() { |
319 | let mut graph = CrateGraph::default(); | 343 | let mut graph = CrateGraph::default(); |
320 | let crate1 = | 344 | let crate1 = graph.add_crate_root( |
321 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); | 345 | FileId(1u32), |
322 | let crate2 = | 346 | Edition2018, |
323 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | 347 | None, |
348 | CfgOptions::default(), | ||
349 | Env::default(), | ||
350 | ); | ||
351 | let crate2 = graph.add_crate_root( | ||
352 | FileId(2u32), | ||
353 | Edition2018, | ||
354 | None, | ||
355 | CfgOptions::default(), | ||
356 | Env::default(), | ||
357 | ); | ||
324 | assert!(graph | 358 | assert!(graph |
325 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) | 359 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) |
326 | .is_ok()); | 360 | .is_ok()); |
327 | assert_eq!( | 361 | assert_eq!( |
328 | graph.dependencies(crate1).collect::<Vec<_>>(), | 362 | graph[crate1].dependencies, |
329 | vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] | 363 | vec![Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] |
330 | ); | 364 | ); |
331 | } | 365 | } |
332 | } | 366 | } |