diff options
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 31 |
1 files changed, 25 insertions, 6 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( |