diff options
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r-- | crates/ra_db/src/fixture.rs | 10 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 58 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 18 |
3 files changed, 51 insertions, 35 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 4f4fb4494..2aafb9965 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -149,15 +149,17 @@ fn with_files( | |||
149 | let crate_id = crate_graph.add_crate_root( | 149 | let crate_id = crate_graph.add_crate_root( |
150 | file_id, | 150 | file_id, |
151 | meta.edition, | 151 | meta.edition, |
152 | Some(CrateName::new(&krate).unwrap()), | 152 | Some(krate.clone()), |
153 | meta.cfg, | 153 | meta.cfg, |
154 | meta.env, | 154 | meta.env, |
155 | Default::default(), | 155 | Default::default(), |
156 | ); | 156 | ); |
157 | let prev = crates.insert(krate.clone(), crate_id); | 157 | let crate_name = CrateName::new(&krate).unwrap(); |
158 | let prev = crates.insert(crate_name.clone(), crate_id); | ||
158 | assert!(prev.is_none()); | 159 | assert!(prev.is_none()); |
159 | for dep in meta.deps { | 160 | for dep in meta.deps { |
160 | crate_deps.push((krate.clone(), dep)) | 161 | let dep = CrateName::new(&dep).unwrap(); |
162 | crate_deps.push((crate_name.clone(), dep)) | ||
161 | } | 163 | } |
162 | } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { | 164 | } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { |
163 | assert!(default_crate_root.is_none()); | 165 | assert!(default_crate_root.is_none()); |
@@ -220,7 +222,7 @@ impl From<Fixture> for FileMeta { | |||
220 | .edition | 222 | .edition |
221 | .as_ref() | 223 | .as_ref() |
222 | .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()), | 224 | .map_or(Edition::Edition2018, |v| Edition::from_str(&v).unwrap()), |
223 | env: Env::from(f.env.iter()), | 225 | env: f.env.into_iter().collect(), |
224 | } | 226 | } |
225 | } | 227 | } |
226 | } | 228 | } |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 7f3660118..6f2e5cfc7 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, ops, str::FromStr, sync::Arc}; | 9 | use std::{fmt, iter::FromIterator, ops, str::FromStr, sync::Arc}; |
10 | 10 | ||
11 | use ra_cfg::CfgOptions; | 11 | use ra_cfg::CfgOptions; |
12 | use ra_syntax::SmolStr; | 12 | use ra_syntax::SmolStr; |
@@ -67,7 +67,7 @@ pub struct CrateGraph { | |||
67 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 67 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
68 | pub struct CrateId(pub u32); | 68 | pub struct CrateId(pub u32); |
69 | 69 | ||
70 | #[derive(Debug, Clone, PartialEq, Eq)] | 70 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
71 | pub struct CrateName(SmolStr); | 71 | pub struct CrateName(SmolStr); |
72 | 72 | ||
73 | impl CrateName { | 73 | impl CrateName { |
@@ -94,6 +94,13 @@ impl fmt::Display for CrateName { | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | impl ops::Deref for CrateName { | ||
98 | type Target = str; | ||
99 | fn deref(&self) -> &Self::Target { | ||
100 | &*self.0 | ||
101 | } | ||
102 | } | ||
103 | |||
97 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 104 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
98 | pub struct ProcMacroId(pub u32); | 105 | pub struct ProcMacroId(pub u32); |
99 | 106 | ||
@@ -117,7 +124,7 @@ pub struct CrateData { | |||
117 | /// The name to display to the end user. | 124 | /// The name to display to the end user. |
118 | /// This actual crate name can be different in a particular dependent crate | 125 | /// This actual crate name can be different in a particular dependent crate |
119 | /// or may even be missing for some cases, such as a dummy crate for the code snippet. | 126 | /// or may even be missing for some cases, such as a dummy crate for the code snippet. |
120 | pub display_name: Option<CrateName>, | 127 | pub display_name: Option<String>, |
121 | pub cfg_options: CfgOptions, | 128 | pub cfg_options: CfgOptions, |
122 | pub env: Env, | 129 | pub env: Env, |
123 | pub dependencies: Vec<Dependency>, | 130 | pub dependencies: Vec<Dependency>, |
@@ -138,7 +145,7 @@ pub struct Env { | |||
138 | #[derive(Debug, Clone, PartialEq, Eq)] | 145 | #[derive(Debug, Clone, PartialEq, Eq)] |
139 | pub struct Dependency { | 146 | pub struct Dependency { |
140 | pub crate_id: CrateId, | 147 | pub crate_id: CrateId, |
141 | pub name: SmolStr, | 148 | pub name: CrateName, |
142 | } | 149 | } |
143 | 150 | ||
144 | impl CrateGraph { | 151 | impl CrateGraph { |
@@ -146,7 +153,7 @@ impl CrateGraph { | |||
146 | &mut self, | 153 | &mut self, |
147 | file_id: FileId, | 154 | file_id: FileId, |
148 | edition: Edition, | 155 | edition: Edition, |
149 | display_name: Option<CrateName>, | 156 | display_name: Option<String>, |
150 | cfg_options: CfgOptions, | 157 | cfg_options: CfgOptions, |
151 | env: Env, | 158 | env: Env, |
152 | proc_macro: Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)>, | 159 | proc_macro: Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)>, |
@@ -178,7 +185,7 @@ impl CrateGraph { | |||
178 | if self.dfs_find(from, to, &mut FxHashSet::default()) { | 185 | if self.dfs_find(from, to, &mut FxHashSet::default()) { |
179 | return Err(CyclicDependenciesError); | 186 | return Err(CyclicDependenciesError); |
180 | } | 187 | } |
181 | self.arena.get_mut(&from).unwrap().add_dep(name.0, to); | 188 | self.arena.get_mut(&from).unwrap().add_dep(name, to); |
182 | Ok(()) | 189 | Ok(()) |
183 | } | 190 | } |
184 | 191 | ||
@@ -190,6 +197,23 @@ impl CrateGraph { | |||
190 | self.arena.keys().copied() | 197 | self.arena.keys().copied() |
191 | } | 198 | } |
192 | 199 | ||
200 | /// Returns an iterator over all transitive dependencies of the given crate. | ||
201 | pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> + '_ { | ||
202 | let mut worklist = vec![of]; | ||
203 | let mut deps = FxHashSet::default(); | ||
204 | |||
205 | while let Some(krate) = worklist.pop() { | ||
206 | if !deps.insert(krate) { | ||
207 | continue; | ||
208 | } | ||
209 | |||
210 | worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id)); | ||
211 | } | ||
212 | |||
213 | deps.remove(&of); | ||
214 | deps.into_iter() | ||
215 | } | ||
216 | |||
193 | // FIXME: this only finds one crate with the given root; we could have multiple | 217 | // FIXME: this only finds one crate with the given root; we could have multiple |
194 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 218 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
195 | let (&crate_id, _) = | 219 | let (&crate_id, _) = |
@@ -247,7 +271,7 @@ impl CrateId { | |||
247 | } | 271 | } |
248 | 272 | ||
249 | impl CrateData { | 273 | impl CrateData { |
250 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 274 | fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { |
251 | self.dependencies.push(Dependency { name, crate_id }) | 275 | self.dependencies.push(Dependency { name, crate_id }) |
252 | } | 276 | } |
253 | } | 277 | } |
@@ -274,18 +298,9 @@ impl fmt::Display for Edition { | |||
274 | } | 298 | } |
275 | } | 299 | } |
276 | 300 | ||
277 | impl<'a, T> From<T> for Env | 301 | impl FromIterator<(String, String)> for Env { |
278 | where | 302 | fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self { |
279 | T: Iterator<Item = (&'a String, &'a String)>, | 303 | Env { entries: FromIterator::from_iter(iter) } |
280 | { | ||
281 | fn from(iter: T) -> Self { | ||
282 | let mut result = Self::default(); | ||
283 | |||
284 | for (k, v) in iter { | ||
285 | result.entries.insert(k.to_owned(), v.to_owned()); | ||
286 | } | ||
287 | |||
288 | result | ||
289 | } | 304 | } |
290 | } | 305 | } |
291 | 306 | ||
@@ -429,7 +444,10 @@ mod tests { | |||
429 | .is_ok()); | 444 | .is_ok()); |
430 | assert_eq!( | 445 | assert_eq!( |
431 | graph[crate1].dependencies, | 446 | graph[crate1].dependencies, |
432 | vec![Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] | 447 | vec![Dependency { |
448 | crate_id: crate2, | ||
449 | name: CrateName::new("crate_name_with_dashes").unwrap() | ||
450 | }] | ||
433 | ); | 451 | ); |
434 | } | 452 | } |
435 | } | 453 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 4a3ba57da..f25be24fe 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -16,9 +16,8 @@ pub use crate::{ | |||
16 | SourceRoot, SourceRootId, | 16 | SourceRoot, SourceRootId, |
17 | }, | 17 | }, |
18 | }; | 18 | }; |
19 | pub use relative_path::{RelativePath, RelativePathBuf}; | ||
20 | pub use salsa; | 19 | pub use salsa; |
21 | pub use vfs::{file_set::FileSet, AbsPathBuf, VfsPath}; | 20 | pub use vfs::{file_set::FileSet, VfsPath}; |
22 | 21 | ||
23 | #[macro_export] | 22 | #[macro_export] |
24 | macro_rules! impl_intern_key { | 23 | macro_rules! impl_intern_key { |
@@ -80,7 +79,7 @@ pub struct FilePosition { | |||
80 | pub offset: TextSize, | 79 | pub offset: TextSize, |
81 | } | 80 | } |
82 | 81 | ||
83 | #[derive(Clone, Copy, Debug)] | 82 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
84 | pub struct FileRange { | 83 | pub struct FileRange { |
85 | pub file_id: FileId, | 84 | pub file_id: FileId, |
86 | pub range: TextRange, | 85 | pub range: TextRange, |
@@ -93,9 +92,9 @@ pub trait FileLoader { | |||
93 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 92 | fn file_text(&self, file_id: FileId) -> Arc<String>; |
94 | /// Note that we intentionally accept a `&str` and not a `&Path` here. This | 93 | /// Note that we intentionally accept a `&str` and not a `&Path` here. This |
95 | /// method exists to handle `#[path = "/some/path.rs"] mod foo;` and such, | 94 | /// method exists to handle `#[path = "/some/path.rs"] mod foo;` and such, |
96 | /// so the input is guaranteed to be utf-8 string. We might introduce | 95 | /// so the input is guaranteed to be utf-8 string. One might be tempted to |
97 | /// `struct StrPath(str)` for clarity some day, but it's a bit messy, so we | 96 | /// introduce some kind of "utf-8 path with / separators", but that's a bad idea. Behold |
98 | /// get by with a `&str` for the time being. | 97 | /// `#[path = "C://no/way"]` |
99 | fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId>; | 98 | fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId>; |
100 | fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>; | 99 | fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>; |
101 | } | 100 | } |
@@ -113,7 +112,7 @@ pub trait SourceDatabase: CheckCanceled + FileLoader + std::fmt::Debug { | |||
113 | fn crate_graph(&self) -> Arc<CrateGraph>; | 112 | fn crate_graph(&self) -> Arc<CrateGraph>; |
114 | } | 113 | } |
115 | 114 | ||
116 | fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { | 115 | fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { |
117 | let _p = profile("parse_query").detail(|| format!("{:?}", file_id)); | 116 | let _p = profile("parse_query").detail(|| format!("{:?}", file_id)); |
118 | let text = db.file_text(file_id); | 117 | let text = db.file_text(file_id); |
119 | SourceFile::parse(&*text) | 118 | SourceFile::parse(&*text) |
@@ -136,10 +135,7 @@ pub trait SourceDatabaseExt: SourceDatabase { | |||
136 | fn source_root_crates(&self, id: SourceRootId) -> Arc<FxHashSet<CrateId>>; | 135 | fn source_root_crates(&self, id: SourceRootId) -> Arc<FxHashSet<CrateId>>; |
137 | } | 136 | } |
138 | 137 | ||
139 | fn source_root_crates( | 138 | fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<FxHashSet<CrateId>> { |
140 | db: &(impl SourceDatabaseExt + SourceDatabase), | ||
141 | id: SourceRootId, | ||
142 | ) -> Arc<FxHashSet<CrateId>> { | ||
143 | let graph = db.crate_graph(); | 139 | let graph = db.crate_graph(); |
144 | let res = graph | 140 | let res = graph |
145 | .iter() | 141 | .iter() |