aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs31
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
29pub(crate) enum ReferenceResult {
30 Exact(NavigationTarget),
31 Approximate(Vec<NavigationTarget>),
32}
33
34impl 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
26pub(crate) fn reference_definition( 44pub(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
68fn name_definition( 87fn name_definition(