aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r--crates/ra_db/src/fixture.rs11
-rw-r--r--crates/ra_db/src/input.rs148
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
9use std::{fmt, str::FromStr}; 9use std::{fmt, ops, str::FromStr};
10 10
11use ra_cfg::CfgOptions; 11use ra_cfg::CfgOptions;
12use ra_syntax::SmolStr; 12use ra_syntax::SmolStr;
@@ -86,7 +86,7 @@ pub struct CrateId(pub u32);
86pub struct CrateName(SmolStr); 86pub struct CrateName(SmolStr);
87 87
88impl CrateName { 88impl 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)]
107struct CrateData { 107pub 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
223impl 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
226impl CrateId { 230impl 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
232impl CrateData { 236impl 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
264impl Dependency {
265 pub fn crate_id(&self) -> CrateId {
266 self.crate_id
267 }
268}
269
270#[derive(Debug)] 264#[derive(Debug)]
271pub struct ParseEditionError { 265pub 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}