diff options
Diffstat (limited to 'crates/ra_ide_api/src/lib.rs')
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 124 |
1 files changed, 11 insertions, 113 deletions
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 65d21d899..6155d903a 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -18,25 +18,26 @@ macro_rules! ctry { | |||
18 | }; | 18 | }; |
19 | } | 19 | } |
20 | 20 | ||
21 | mod completion; | ||
22 | mod db; | 21 | mod db; |
23 | mod goto_definition; | ||
24 | mod imp; | 22 | mod imp; |
25 | pub mod mock_analysis; | 23 | pub mod mock_analysis; |
26 | mod runnables; | ||
27 | mod symbol_index; | 24 | mod symbol_index; |
25 | mod navigation_target; | ||
28 | 26 | ||
27 | mod completion; | ||
28 | mod runnables; | ||
29 | mod goto_definition; | ||
29 | mod extend_selection; | 30 | mod extend_selection; |
30 | mod hover; | 31 | mod hover; |
31 | mod call_info; | 32 | mod call_info; |
32 | mod syntax_highlighting; | 33 | mod syntax_highlighting; |
34 | mod parent_module; | ||
33 | 35 | ||
34 | use std::{fmt, sync::Arc}; | 36 | use std::{fmt, sync::Arc}; |
35 | 37 | ||
36 | use hir::{Def, ModuleSource, Name}; | 38 | use ra_syntax::{SourceFile, TreePtr, TextRange, TextUnit}; |
37 | use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, SyntaxNode, TextRange, TextUnit, AstNode}; | ||
38 | use ra_text_edit::TextEdit; | 39 | use ra_text_edit::TextEdit; |
39 | use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase}; | 40 | use ra_db::{SyntaxDatabase, FilesDatabase, BaseDatabase}; |
40 | use rayon::prelude::*; | 41 | use rayon::prelude::*; |
41 | use relative_path::RelativePathBuf; | 42 | use relative_path::RelativePathBuf; |
42 | use rustc_hash::FxHashMap; | 43 | use rustc_hash::FxHashMap; |
@@ -50,6 +51,7 @@ use crate::{ | |||
50 | pub use crate::{ | 51 | pub use crate::{ |
51 | completion::{CompletionItem, CompletionItemKind, InsertText}, | 52 | completion::{CompletionItem, CompletionItemKind, InsertText}, |
52 | runnables::{Runnable, RunnableKind}, | 53 | runnables::{Runnable, RunnableKind}, |
54 | navigation_target::NavigationTarget, | ||
53 | }; | 55 | }; |
54 | pub use ra_ide_api_light::{ | 56 | pub use ra_ide_api_light::{ |
55 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, | 57 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, |
@@ -243,110 +245,6 @@ impl Query { | |||
243 | } | 245 | } |
244 | } | 246 | } |
245 | 247 | ||
246 | /// `NavigationTarget` represents and element in the editor's UI whihc you can | ||
247 | /// click on to navigate to a particular piece of code. | ||
248 | /// | ||
249 | /// Typically, a `NavigationTarget` corresponds to some element in the source | ||
250 | /// code, like a function or a struct, but this is not strictly required. | ||
251 | #[derive(Debug, Clone)] | ||
252 | pub struct NavigationTarget { | ||
253 | file_id: FileId, | ||
254 | name: SmolStr, | ||
255 | kind: SyntaxKind, | ||
256 | range: TextRange, | ||
257 | // Should be DefId ideally | ||
258 | ptr: Option<LocalSyntaxPtr>, | ||
259 | } | ||
260 | |||
261 | impl NavigationTarget { | ||
262 | fn from_symbol(symbol: FileSymbol) -> NavigationTarget { | ||
263 | NavigationTarget { | ||
264 | file_id: symbol.file_id, | ||
265 | name: symbol.name.clone(), | ||
266 | kind: symbol.ptr.kind(), | ||
267 | range: symbol.ptr.range(), | ||
268 | ptr: Some(symbol.ptr.clone()), | ||
269 | } | ||
270 | } | ||
271 | |||
272 | fn from_syntax(name: Option<Name>, file_id: FileId, node: &SyntaxNode) -> NavigationTarget { | ||
273 | NavigationTarget { | ||
274 | file_id, | ||
275 | name: name.map(|n| n.to_string().into()).unwrap_or("".into()), | ||
276 | kind: node.kind(), | ||
277 | range: node.range(), | ||
278 | ptr: Some(LocalSyntaxPtr::new(node)), | ||
279 | } | ||
280 | } | ||
281 | // TODO once Def::Item is gone, this should be able to always return a NavigationTarget | ||
282 | fn from_def(db: &db::RootDatabase, def: Def) -> Cancelable<Option<NavigationTarget>> { | ||
283 | Ok(match def { | ||
284 | Def::Struct(s) => { | ||
285 | let (file_id, node) = s.source(db)?; | ||
286 | Some(NavigationTarget::from_syntax( | ||
287 | s.name(db)?, | ||
288 | file_id.original_file(db), | ||
289 | node.syntax(), | ||
290 | )) | ||
291 | } | ||
292 | Def::Enum(e) => { | ||
293 | let (file_id, node) = e.source(db)?; | ||
294 | Some(NavigationTarget::from_syntax( | ||
295 | e.name(db)?, | ||
296 | file_id.original_file(db), | ||
297 | node.syntax(), | ||
298 | )) | ||
299 | } | ||
300 | Def::EnumVariant(ev) => { | ||
301 | let (file_id, node) = ev.source(db)?; | ||
302 | Some(NavigationTarget::from_syntax( | ||
303 | ev.name(db)?, | ||
304 | file_id.original_file(db), | ||
305 | node.syntax(), | ||
306 | )) | ||
307 | } | ||
308 | Def::Function(f) => { | ||
309 | let (file_id, node) = f.source(db)?; | ||
310 | let name = f.signature(db).name().clone(); | ||
311 | Some(NavigationTarget::from_syntax( | ||
312 | Some(name), | ||
313 | file_id.original_file(db), | ||
314 | node.syntax(), | ||
315 | )) | ||
316 | } | ||
317 | Def::Module(m) => { | ||
318 | let (file_id, source) = m.definition_source(db)?; | ||
319 | let name = m.name(db)?; | ||
320 | match source { | ||
321 | ModuleSource::SourceFile(node) => { | ||
322 | Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) | ||
323 | } | ||
324 | ModuleSource::Module(node) => { | ||
325 | Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | Def::Item => None, | ||
330 | }) | ||
331 | } | ||
332 | |||
333 | pub fn name(&self) -> &SmolStr { | ||
334 | &self.name | ||
335 | } | ||
336 | |||
337 | pub fn kind(&self) -> SyntaxKind { | ||
338 | self.kind | ||
339 | } | ||
340 | |||
341 | pub fn file_id(&self) -> FileId { | ||
342 | self.file_id | ||
343 | } | ||
344 | |||
345 | pub fn range(&self) -> TextRange { | ||
346 | self.range | ||
347 | } | ||
348 | } | ||
349 | |||
350 | #[derive(Debug)] | 248 | #[derive(Debug)] |
351 | pub struct RangeInfo<T> { | 249 | pub struct RangeInfo<T> { |
352 | pub range: TextRange, | 250 | pub range: TextRange, |
@@ -354,7 +252,7 @@ pub struct RangeInfo<T> { | |||
354 | } | 252 | } |
355 | 253 | ||
356 | impl<T> RangeInfo<T> { | 254 | impl<T> RangeInfo<T> { |
357 | fn new(range: TextRange, info: T) -> RangeInfo<T> { | 255 | pub fn new(range: TextRange, info: T) -> RangeInfo<T> { |
358 | RangeInfo { range, info } | 256 | RangeInfo { range, info } |
359 | } | 257 | } |
360 | } | 258 | } |
@@ -494,7 +392,7 @@ impl Analysis { | |||
494 | pub fn goto_definition( | 392 | pub fn goto_definition( |
495 | &self, | 393 | &self, |
496 | position: FilePosition, | 394 | position: FilePosition, |
497 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { | 395 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
498 | self.db | 396 | self.db |
499 | .catch_canceled(|db| goto_definition::goto_definition(db, position))? | 397 | .catch_canceled(|db| goto_definition::goto_definition(db, position))? |
500 | } | 398 | } |
@@ -517,7 +415,7 @@ impl Analysis { | |||
517 | 415 | ||
518 | /// Returns a `mod name;` declaration which created the current module. | 416 | /// Returns a `mod name;` declaration which created the current module. |
519 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { | 417 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { |
520 | self.with_db(|db| db.parent_module(position))? | 418 | self.with_db(|db| parent_module::parent_module(db, position))? |
521 | } | 419 | } |
522 | 420 | ||
523 | /// Returns crates this file belongs too. | 421 | /// Returns crates this file belongs too. |