aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_db
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_db')
-rw-r--r--crates/ra_db/Cargo.toml4
-rw-r--r--crates/ra_db/src/fixture.rs10
-rw-r--r--crates/ra_db/src/input.rs58
-rw-r--r--crates/ra_db/src/lib.rs18
4 files changed, 53 insertions, 37 deletions
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 372fb242b..5f334d04f 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -3,13 +3,13 @@ edition = "2018"
3name = "ra_db" 3name = "ra_db"
4version = "0.1.0" 4version = "0.1.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0"
6 7
7[lib] 8[lib]
8doctest = false 9doctest = false
9 10
10[dependencies] 11[dependencies]
11salsa = "0.14.1" 12salsa = "0.15.0"
12relative-path = "1.0.0"
13rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
14 14
15ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
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
9use std::{fmt, ops, str::FromStr, sync::Arc}; 9use std::{fmt, iter::FromIterator, ops, str::FromStr, sync::Arc};
10 10
11use ra_cfg::CfgOptions; 11use ra_cfg::CfgOptions;
12use ra_syntax::SmolStr; 12use 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)]
68pub struct CrateId(pub u32); 68pub struct CrateId(pub u32);
69 69
70#[derive(Debug, Clone, PartialEq, Eq)] 70#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub struct CrateName(SmolStr); 71pub struct CrateName(SmolStr);
72 72
73impl CrateName { 73impl CrateName {
@@ -94,6 +94,13 @@ impl fmt::Display for CrateName {
94 } 94 }
95} 95}
96 96
97impl 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)]
98pub struct ProcMacroId(pub u32); 105pub 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)]
139pub struct Dependency { 146pub struct Dependency {
140 pub crate_id: CrateId, 147 pub crate_id: CrateId,
141 pub name: SmolStr, 148 pub name: CrateName,
142} 149}
143 150
144impl CrateGraph { 151impl 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
249impl CrateData { 273impl 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
277impl<'a, T> From<T> for Env 301impl FromIterator<(String, String)> for Env {
278where 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};
19pub use relative_path::{RelativePath, RelativePathBuf};
20pub use salsa; 19pub use salsa;
21pub use vfs::{file_set::FileSet, AbsPathBuf, VfsPath}; 20pub use vfs::{file_set::FileSet, VfsPath};
22 21
23#[macro_export] 22#[macro_export]
24macro_rules! impl_intern_key { 23macro_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)]
84pub struct FileRange { 83pub 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
116fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { 115fn 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
139fn source_root_crates( 138fn 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()