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/src/lib.rs | |
parent | eeb8b9e236796da8734ba81a49164864497f7226 (diff) | |
parent | b56ad148db0c69eb279c225f45d324b4e80e7367 (diff) |
Merge branch 'master' into keyword_completion
# Conflicts:
# docs/user/generated_features.adoc
Diffstat (limited to 'crates/ra_db/src/lib.rs')
-rw-r--r-- | crates/ra_db/src/lib.rs | 79 |
1 files changed, 40 insertions, 39 deletions
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 | } |