diff options
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/completion.rs (renamed from crates/ra_analysis/src/completion/mod.rs) | 0 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 39 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 29 |
3 files changed, 57 insertions, 11 deletions
diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion.rs index 0f154112a..0f154112a 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion.rs | |||
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 975afc145..03d17de0d 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -27,6 +27,7 @@ use crate::{ | |||
27 | symbol_index::{SymbolIndex, SymbolsDatabase}, | 27 | symbol_index::{SymbolIndex, SymbolsDatabase}, |
28 | AnalysisChange, Cancelable, CrateId, Diagnostic, FileId, | 28 | AnalysisChange, Cancelable, CrateId, Diagnostic, FileId, |
29 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, | 29 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, |
30 | ReferenceResolution, | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | #[derive(Debug, Default)] | 33 | #[derive(Debug, Default)] |
@@ -144,7 +145,7 @@ impl AnalysisImpl { | |||
144 | } else { | 145 | } else { |
145 | let files = &self.db.source_root(WORKSPACE).files; | 146 | let files = &self.db.source_root(WORKSPACE).files; |
146 | 147 | ||
147 | /// Need to wrap Snapshot to provide `Clon` impl for `map_with` | 148 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` |
148 | struct Snap(salsa::Snapshot<db::RootDatabase>); | 149 | struct Snap(salsa::Snapshot<db::RootDatabase>); |
149 | impl Clone for Snap { | 150 | impl Clone for Snap { |
150 | fn clone(&self) -> Snap { | 151 | fn clone(&self) -> Snap { |
@@ -164,7 +165,7 @@ impl AnalysisImpl { | |||
164 | .sweep(salsa::SweepStrategy::default().discard_values()); | 165 | .sweep(salsa::SweepStrategy::default().discard_values()); |
165 | Ok(query.search(&buf)) | 166 | Ok(query.search(&buf)) |
166 | } | 167 | } |
167 | /// This return `Vec`: a module may be included from several places. We | 168 | /// This returns `Vec` because a module may be included from several places. We |
168 | /// don't handle this case yet though, so the Vec has length at most one. | 169 | /// don't handle this case yet though, so the Vec has length at most one. |
169 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 170 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
170 | let descr = match source_binder::module_from_position(&*self.db, position)? { | 171 | let descr = match source_binder::module_from_position(&*self.db, position)? { |
@@ -206,10 +207,11 @@ impl AnalysisImpl { | |||
206 | pub fn approximately_resolve_symbol( | 207 | pub fn approximately_resolve_symbol( |
207 | &self, | 208 | &self, |
208 | position: FilePosition, | 209 | position: FilePosition, |
209 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 210 | ) -> Cancelable<Option<ReferenceResolution>> { |
210 | let file = self.db.source_file(position.file_id); | 211 | let file = self.db.source_file(position.file_id); |
211 | let syntax = file.syntax(); | 212 | let syntax = file.syntax(); |
212 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 213 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
214 | let mut rr = ReferenceResolution::new(name_ref.syntax().range()); | ||
213 | if let Some(fn_descr) = source_binder::function_from_child_node( | 215 | if let Some(fn_descr) = source_binder::function_from_child_node( |
214 | &*self.db, | 216 | &*self.db, |
215 | position.file_id, | 217 | position.file_id, |
@@ -218,22 +220,25 @@ impl AnalysisImpl { | |||
218 | let scope = fn_descr.scope(&*self.db); | 220 | let scope = fn_descr.scope(&*self.db); |
219 | // First try to resolve the symbol locally | 221 | // First try to resolve the symbol locally |
220 | if let Some(entry) = scope.resolve_local_name(name_ref) { | 222 | if let Some(entry) = scope.resolve_local_name(name_ref) { |
221 | let mut vec = vec![]; | 223 | rr.add_resolution( |
222 | vec.push(( | ||
223 | position.file_id, | 224 | position.file_id, |
224 | FileSymbol { | 225 | FileSymbol { |
225 | name: entry.name().clone(), | 226 | name: entry.name().clone(), |
226 | node_range: entry.ptr().range(), | 227 | node_range: entry.ptr().range(), |
227 | kind: NAME, | 228 | kind: NAME, |
228 | }, | 229 | }, |
229 | )); | 230 | ); |
230 | return Ok(vec); | 231 | return Ok(Some(rr)); |
231 | }; | 232 | }; |
232 | } | 233 | } |
233 | // If that fails try the index based approach. | 234 | // If that fails try the index based approach. |
234 | return self.index_resolve(name_ref); | 235 | for (file_id, symbol) in self.index_resolve(name_ref)? { |
236 | rr.add_resolution(file_id, symbol); | ||
237 | } | ||
238 | return Ok(Some(rr)); | ||
235 | } | 239 | } |
236 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 240 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
241 | let mut rr = ReferenceResolution::new(name.syntax().range()); | ||
237 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 242 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
238 | if module.has_semi() { | 243 | if module.has_semi() { |
239 | let parent_module = | 244 | let parent_module = |
@@ -248,7 +253,8 @@ impl AnalysisImpl { | |||
248 | node_range: TextRange::offset_len(0.into(), 0.into()), | 253 | node_range: TextRange::offset_len(0.into(), 0.into()), |
249 | kind: MODULE, | 254 | kind: MODULE, |
250 | }; | 255 | }; |
251 | return Ok(vec![(file_id, symbol)]); | 256 | rr.add_resolution(file_id, symbol); |
257 | return Ok(Some(rr)); | ||
252 | } | 258 | } |
253 | } | 259 | } |
254 | _ => (), | 260 | _ => (), |
@@ -256,7 +262,7 @@ impl AnalysisImpl { | |||
256 | } | 262 | } |
257 | } | 263 | } |
258 | } | 264 | } |
259 | Ok(vec![]) | 265 | Ok(None) |
260 | } | 266 | } |
261 | 267 | ||
262 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { | 268 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { |
@@ -318,6 +324,19 @@ impl AnalysisImpl { | |||
318 | 324 | ||
319 | Ok(symbol.docs(&file)) | 325 | Ok(symbol.docs(&file)) |
320 | } | 326 | } |
327 | pub fn doc_text_for(&self, file_id: FileId, symbol: FileSymbol) -> Cancelable<Option<String>> { | ||
328 | let file = self.db.source_file(file_id); | ||
329 | let result = match (symbol.description(&file), symbol.docs(&file)) { | ||
330 | (Some(desc), Some(docs)) => { | ||
331 | Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs) | ||
332 | } | ||
333 | (Some(desc), None) => Some("```rust\n".to_string() + &*desc + "\n```"), | ||
334 | (None, Some(docs)) => Some(docs), | ||
335 | _ => None, | ||
336 | }; | ||
337 | |||
338 | Ok(result) | ||
339 | } | ||
321 | 340 | ||
322 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { | 341 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
323 | let syntax = self.db.source_file(file_id); | 342 | let syntax = self.db.source_file(file_id); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 4b8b10816..eaf24cb36 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -178,6 +178,30 @@ impl Query { | |||
178 | } | 178 | } |
179 | } | 179 | } |
180 | 180 | ||
181 | /// Result of "goto def" query. | ||
182 | #[derive(Debug)] | ||
183 | pub struct ReferenceResolution { | ||
184 | /// The range of the reference itself. Client does not know what constitutes | ||
185 | /// a reference, it handles us only the offset. It's helpful to tell the | ||
186 | /// client where the reference was. | ||
187 | pub reference_range: TextRange, | ||
188 | /// What this reference resolves to. | ||
189 | pub resolves_to: Vec<(FileId, FileSymbol)>, | ||
190 | } | ||
191 | |||
192 | impl ReferenceResolution { | ||
193 | fn new(reference_range: TextRange) -> ReferenceResolution { | ||
194 | ReferenceResolution { | ||
195 | reference_range, | ||
196 | resolves_to: Vec::new(), | ||
197 | } | ||
198 | } | ||
199 | |||
200 | fn add_resolution(&mut self, file_id: FileId, symbol: FileSymbol) { | ||
201 | self.resolves_to.push((file_id, symbol)) | ||
202 | } | ||
203 | } | ||
204 | |||
181 | /// Analysis is a snapshot of a world state at a moment in time. It is the main | 205 | /// Analysis is a snapshot of a world state at a moment in time. It is the main |
182 | /// entry point for asking semantic information about the world. When the world | 206 | /// entry point for asking semantic information about the world. When the world |
183 | /// state is advanced using `AnalysisHost::apply_change` method, all existing | 207 | /// state is advanced using `AnalysisHost::apply_change` method, all existing |
@@ -236,7 +260,7 @@ impl Analysis { | |||
236 | pub fn approximately_resolve_symbol( | 260 | pub fn approximately_resolve_symbol( |
237 | &self, | 261 | &self, |
238 | position: FilePosition, | 262 | position: FilePosition, |
239 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 263 | ) -> Cancelable<Option<ReferenceResolution>> { |
240 | self.imp.approximately_resolve_symbol(position) | 264 | self.imp.approximately_resolve_symbol(position) |
241 | } | 265 | } |
242 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { | 266 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { |
@@ -249,6 +273,9 @@ impl Analysis { | |||
249 | ) -> Cancelable<Option<String>> { | 273 | ) -> Cancelable<Option<String>> { |
250 | self.imp.doc_comment_for(file_id, symbol) | 274 | self.imp.doc_comment_for(file_id, symbol) |
251 | } | 275 | } |
276 | pub fn doc_text_for(&self, file_id: FileId, symbol: FileSymbol) -> Cancelable<Option<String>> { | ||
277 | self.imp.doc_text_for(file_id, symbol) | ||
278 | } | ||
252 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 279 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
253 | self.imp.parent_module(position) | 280 | self.imp.parent_module(position) |
254 | } | 281 | } |