diff options
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 31 | ||||
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 15 |
2 files changed, 36 insertions, 10 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 8d2ff561a..e2537758d 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -13,8 +13,11 @@ pub(crate) fn goto_definition( | |||
13 | let file = db.source_file(position.file_id); | 13 | let file = db.source_file(position.file_id); |
14 | let syntax = file.syntax(); | 14 | let syntax = file.syntax(); |
15 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 15 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
16 | let navs = reference_definition(db, position.file_id, name_ref)?; | 16 | let navs = reference_definition(db, position.file_id, name_ref)?.to_vec(); |
17 | return Ok(Some(RangeInfo::new(name_ref.syntax().range(), navs))); | 17 | return Ok(Some(RangeInfo::new( |
18 | name_ref.syntax().range(), | ||
19 | navs.to_vec(), | ||
20 | ))); | ||
18 | } | 21 | } |
19 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 22 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
20 | let navs = ctry!(name_definition(db, position.file_id, name)?); | 23 | let navs = ctry!(name_definition(db, position.file_id, name)?); |
@@ -23,11 +26,27 @@ pub(crate) fn goto_definition( | |||
23 | Ok(None) | 26 | Ok(None) |
24 | } | 27 | } |
25 | 28 | ||
29 | pub(crate) enum ReferenceResult { | ||
30 | Exact(NavigationTarget), | ||
31 | Approximate(Vec<NavigationTarget>), | ||
32 | } | ||
33 | |||
34 | impl ReferenceResult { | ||
35 | fn to_vec(self) -> Vec<NavigationTarget> { | ||
36 | use self::ReferenceResult::*; | ||
37 | match self { | ||
38 | Exact(target) => vec![target], | ||
39 | Approximate(vec) => vec, | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
26 | pub(crate) fn reference_definition( | 44 | pub(crate) fn reference_definition( |
27 | db: &RootDatabase, | 45 | db: &RootDatabase, |
28 | file_id: FileId, | 46 | file_id: FileId, |
29 | name_ref: &ast::NameRef, | 47 | name_ref: &ast::NameRef, |
30 | ) -> Cancelable<Vec<NavigationTarget>> { | 48 | ) -> Cancelable<ReferenceResult> { |
49 | use self::ReferenceResult::*; | ||
31 | if let Some(fn_descr) = | 50 | if let Some(fn_descr) = |
32 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? | 51 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? |
33 | { | 52 | { |
@@ -35,7 +54,7 @@ pub(crate) fn reference_definition( | |||
35 | // First try to resolve the symbol locally | 54 | // First try to resolve the symbol locally |
36 | if let Some(entry) = scope.resolve_local_name(name_ref) { | 55 | if let Some(entry) = scope.resolve_local_name(name_ref) { |
37 | let nav = NavigationTarget::from_scope_entry(file_id, &entry); | 56 | let nav = NavigationTarget::from_scope_entry(file_id, &entry); |
38 | return Ok(vec![nav]); | 57 | return Ok(Exact(nav)); |
39 | }; | 58 | }; |
40 | } | 59 | } |
41 | // Then try module name resolution | 60 | // Then try module name resolution |
@@ -51,7 +70,7 @@ pub(crate) fn reference_definition( | |||
51 | let resolved = module.resolve_path(db, &path)?; | 70 | let resolved = module.resolve_path(db, &path)?; |
52 | if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { | 71 | if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { |
53 | if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)?)? { | 72 | if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)?)? { |
54 | return Ok(vec![target]); | 73 | return Ok(Exact(target)); |
55 | } | 74 | } |
56 | } | 75 | } |
57 | } | 76 | } |
@@ -62,7 +81,7 @@ pub(crate) fn reference_definition( | |||
62 | .into_iter() | 81 | .into_iter() |
63 | .map(NavigationTarget::from_symbol) | 82 | .map(NavigationTarget::from_symbol) |
64 | .collect(); | 83 | .collect(); |
65 | Ok(navs) | 84 | Ok(Approximate(navs)) |
66 | } | 85 | } |
67 | 86 | ||
68 | fn name_definition( | 87 | fn name_definition( |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index b66774cdf..2968b807c 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -16,9 +16,16 @@ pub(crate) fn hover( | |||
16 | 16 | ||
17 | let mut range = None; | 17 | let mut range = None; |
18 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { | 18 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { |
19 | let navs = crate::goto_definition::reference_definition(db, position.file_id, name_ref)?; | 19 | use crate::goto_definition::{ReferenceResult::*, reference_definition}; |
20 | for nav in navs { | 20 | let ref_result = reference_definition(db, position.file_id, name_ref)?; |
21 | res.extend(doc_text_for(db, nav)?) | 21 | match ref_result { |
22 | Exact(nav) => res.extend(doc_text_for(db, nav)?), | ||
23 | Approximate(navs) => { | ||
24 | res.push("Failed to exactly resolve the symbol. This is probably because rust_analyzer does not yet support glob imports or traits. \nThese methods were found instead:".to_string()); | ||
25 | for nav in navs { | ||
26 | res.extend(doc_text_for(db, nav)?) | ||
27 | } | ||
28 | } | ||
22 | } | 29 | } |
23 | if !res.is_empty() { | 30 | if !res.is_empty() { |
24 | range = Some(name_ref.syntax().range()) | 31 | range = Some(name_ref.syntax().range()) |
@@ -34,7 +41,7 @@ pub(crate) fn hover( | |||
34 | file_id: position.file_id, | 41 | file_id: position.file_id, |
35 | range: node.range(), | 42 | range: node.range(), |
36 | }; | 43 | }; |
37 | res.extend(type_of(db, frange)?); | 44 | res.extend(type_of(db, frange)?.map(Into::into)); |
38 | range = Some(node.range()); | 45 | range = Some(node.range()); |
39 | }; | 46 | }; |
40 | 47 | ||