diff options
author | Mikhail Rakhmanov <[email protected]> | 2020-06-13 07:42:15 +0100 |
---|---|---|
committer | Mikhail Rakhmanov <[email protected]> | 2020-06-13 07:42:15 +0100 |
commit | 16bbf4ab7f132e6e5e5318dccdef9a5d71afdd7f (patch) | |
tree | 4b79fa8c046be56b02427ba843e70cdf3ac05767 /crates/ra_db | |
parent | eeb8b9e236796da8734ba81a49164864497f7226 (diff) | |
parent | b56ad148db0c69eb279c225f45d324b4e80e7367 (diff) |
Merge branch 'master' into keyword_completion
# Conflicts:
# docs/user/generated_features.adoc
Diffstat (limited to 'crates/ra_db')
-rw-r--r-- | crates/ra_db/src/input.rs | 20 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 79 |
2 files changed, 47 insertions, 52 deletions
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 4d2d3b48a..bf26048f2 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -15,12 +15,10 @@ use std::{ | |||
15 | 15 | ||
16 | use ra_cfg::CfgOptions; | 16 | use ra_cfg::CfgOptions; |
17 | use ra_syntax::SmolStr; | 17 | use ra_syntax::SmolStr; |
18 | use rustc_hash::FxHashMap; | 18 | use ra_tt::TokenExpander; |
19 | use rustc_hash::FxHashSet; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
20 | 20 | ||
21 | use crate::{RelativePath, RelativePathBuf}; | 21 | use crate::{RelativePath, RelativePathBuf}; |
22 | use fmt::Display; | ||
23 | use ra_tt::TokenExpander; | ||
24 | 22 | ||
25 | /// `FileId` is an integer which uniquely identifies a file. File paths are | 23 | /// `FileId` is an integer which uniquely identifies a file. File paths are |
26 | /// messy and system-dependent, so most of the code should work directly with | 24 | /// messy and system-dependent, so most of the code should work directly with |
@@ -111,7 +109,7 @@ impl CrateName { | |||
111 | } | 109 | } |
112 | } | 110 | } |
113 | 111 | ||
114 | impl Display for CrateName { | 112 | impl fmt::Display for CrateName { |
115 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
116 | write!(f, "{}", self.0) | 114 | write!(f, "{}", self.0) |
117 | } | 115 | } |
@@ -337,15 +335,11 @@ impl Env { | |||
337 | } | 335 | } |
338 | 336 | ||
339 | impl ExternSource { | 337 | impl ExternSource { |
340 | pub fn extern_path(&self, path: impl AsRef<Path>) -> Option<(ExternSourceId, RelativePathBuf)> { | 338 | pub fn extern_path(&self, path: &Path) -> Option<(ExternSourceId, RelativePathBuf)> { |
341 | let path = path.as_ref(); | ||
342 | self.extern_paths.iter().find_map(|(root_path, id)| { | 339 | self.extern_paths.iter().find_map(|(root_path, id)| { |
343 | if let Ok(rel_path) = path.strip_prefix(root_path) { | 340 | let rel_path = path.strip_prefix(root_path).ok()?; |
344 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | 341 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; |
345 | Some((*id, rel_path)) | 342 | Some((*id, rel_path)) |
346 | } else { | ||
347 | None | ||
348 | } | ||
349 | }) | 343 | }) |
350 | } | 344 | } |
351 | 345 | ||
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index fd4280de2..80ddb6058 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -7,12 +7,13 @@ use std::{panic, sync::Arc}; | |||
7 | 7 | ||
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | use ra_syntax::{ast, Parse, SourceFile, TextRange, TextSize}; | 9 | use ra_syntax::{ast, Parse, SourceFile, TextRange, TextSize}; |
10 | use rustc_hash::FxHashSet; | ||
10 | 11 | ||
11 | pub use crate::{ | 12 | pub use crate::{ |
12 | cancellation::Canceled, | 13 | cancellation::Canceled, |
13 | input::{ | 14 | input::{ |
14 | CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId, | 15 | CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, |
15 | FileId, ProcMacroId, SourceRoot, SourceRootId, | 16 | ExternSourceId, FileId, ProcMacroId, SourceRoot, SourceRootId, |
16 | }, | 17 | }, |
17 | }; | 18 | }; |
18 | pub use relative_path::{RelativePath, RelativePathBuf}; | 19 | pub use relative_path::{RelativePath, RelativePathBuf}; |
@@ -89,15 +90,13 @@ pub const DEFAULT_LRU_CAP: usize = 128; | |||
89 | pub trait FileLoader { | 90 | pub trait FileLoader { |
90 | /// Text of the file. | 91 | /// Text of the file. |
91 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 92 | fn file_text(&self, file_id: FileId) -> Arc<String>; |
92 | fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath) | 93 | /// Note that we intentionally accept a `&str` and not a `&Path` here. This |
93 | -> Option<FileId>; | 94 | /// method exists to handle `#[path = "/some/path.rs"] mod foo;` and such, |
94 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>; | 95 | /// so the input is guaranteed to be utf-8 string. We might introduce |
95 | 96 | /// `struct StrPath(str)` for clarity some day, but it's a bit messy, so we | |
96 | fn resolve_extern_path( | 97 | /// get by with a `&str` for the time being. |
97 | &self, | 98 | fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId>; |
98 | extern_id: ExternSourceId, | 99 | fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>; |
99 | relative_path: &RelativePath, | ||
100 | ) -> Option<FileId>; | ||
101 | } | 100 | } |
102 | 101 | ||
103 | /// Database which stores all significant input facts: source code and project | 102 | /// Database which stores all significant input facts: source code and project |
@@ -135,16 +134,21 @@ pub trait SourceDatabaseExt: SourceDatabase { | |||
135 | #[salsa::input] | 134 | #[salsa::input] |
136 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; | 135 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; |
137 | 136 | ||
138 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; | 137 | fn source_root_crates(&self, id: SourceRootId) -> Arc<FxHashSet<CrateId>>; |
139 | } | 138 | } |
140 | 139 | ||
141 | fn source_root_crates( | 140 | fn source_root_crates( |
142 | db: &(impl SourceDatabaseExt + SourceDatabase), | 141 | db: &(impl SourceDatabaseExt + SourceDatabase), |
143 | id: SourceRootId, | 142 | id: SourceRootId, |
144 | ) -> Arc<Vec<CrateId>> { | 143 | ) -> Arc<FxHashSet<CrateId>> { |
145 | let root = db.source_root(id); | ||
146 | let graph = db.crate_graph(); | 144 | let graph = db.crate_graph(); |
147 | let res = root.walk().filter_map(|it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>(); | 145 | let res = graph |
146 | .iter() | ||
147 | .filter(|&krate| { | ||
148 | let root_file = graph[krate].root_file_id; | ||
149 | db.file_source_root(root_file) == id | ||
150 | }) | ||
151 | .collect::<FxHashSet<_>>(); | ||
148 | Arc::new(res) | 152 | Arc::new(res) |
149 | } | 153 | } |
150 | 154 | ||
@@ -155,33 +159,30 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> { | |||
155 | fn file_text(&self, file_id: FileId) -> Arc<String> { | 159 | fn file_text(&self, file_id: FileId) -> Arc<String> { |
156 | SourceDatabaseExt::file_text(self.0, file_id) | 160 | SourceDatabaseExt::file_text(self.0, file_id) |
157 | } | 161 | } |
158 | fn resolve_relative_path( | 162 | fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> { |
159 | &self, | 163 | // FIXME: this *somehow* should be platform agnostic... |
160 | anchor: FileId, | 164 | if std::path::Path::new(path).is_absolute() { |
161 | relative_path: &RelativePath, | 165 | let krate = *self.relevant_crates(anchor).iter().next()?; |
162 | ) -> Option<FileId> { | 166 | let (extern_source_id, relative_file) = |
163 | let path = { | 167 | self.0.crate_graph()[krate].extern_source.extern_path(path.as_ref())?; |
164 | let mut path = self.0.file_relative_path(anchor); | 168 | |
165 | assert!(path.pop()); | 169 | let source_root = self.0.source_root(SourceRootId(extern_source_id.0)); |
166 | path.push(relative_path); | 170 | source_root.file_by_relative_path(&relative_file) |
167 | path.normalize() | 171 | } else { |
168 | }; | 172 | let rel_path = { |
169 | let source_root = self.0.file_source_root(anchor); | 173 | let mut rel_path = self.0.file_relative_path(anchor); |
170 | let source_root = self.0.source_root(source_root); | 174 | assert!(rel_path.pop()); |
171 | source_root.file_by_relative_path(&path) | 175 | rel_path.push(path); |
176 | rel_path.normalize() | ||
177 | }; | ||
178 | let source_root = self.0.file_source_root(anchor); | ||
179 | let source_root = self.0.source_root(source_root); | ||
180 | source_root.file_by_relative_path(&rel_path) | ||
181 | } | ||
172 | } | 182 | } |
173 | 183 | ||
174 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 184 | fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> { |
175 | let source_root = self.0.file_source_root(file_id); | 185 | let source_root = self.0.file_source_root(file_id); |
176 | self.0.source_root_crates(source_root) | 186 | self.0.source_root_crates(source_root) |
177 | } | 187 | } |
178 | |||
179 | fn resolve_extern_path( | ||
180 | &self, | ||
181 | extern_id: ExternSourceId, | ||
182 | relative_path: &RelativePath, | ||
183 | ) -> Option<FileId> { | ||
184 | let source_root = self.0.source_root(SourceRootId(extern_id.0)); | ||
185 | source_root.file_by_relative_path(&relative_path) | ||
186 | } | ||
187 | } | 188 | } |