aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/goto_definition.rs')
-rw-r--r--crates/ra_ide/src/goto_definition.rs39
1 files changed, 20 insertions, 19 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 79d332e8c..5a12a619c 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::AstDatabase, InFile}; 3use hir::{db::AstDatabase, InFile, SourceBinder};
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{self, DocCommentsOwner}, 5 ast::{self, DocCommentsOwner},
6 match_ast, AstNode, 6 match_ast, AstNode,
@@ -24,13 +24,14 @@ pub(crate) fn goto_definition(
24 let original_token = pick_best(file.token_at_offset(position.offset))?; 24 let original_token = pick_best(file.token_at_offset(position.offset))?;
25 let token = descend_into_macros(db, position.file_id, original_token.clone()); 25 let token = descend_into_macros(db, position.file_id, original_token.clone());
26 26
27 let mut sb = SourceBinder::new(db);
27 let nav_targets = match_ast! { 28 let nav_targets = match_ast! {
28 match (token.value.parent()) { 29 match (token.value.parent()) {
29 ast::NameRef(name_ref) => { 30 ast::NameRef(name_ref) => {
30 reference_definition(db, token.with_value(&name_ref)).to_vec() 31 reference_definition(&mut sb, token.with_value(&name_ref)).to_vec()
31 }, 32 },
32 ast::Name(name) => { 33 ast::Name(name) => {
33 name_definition(db, token.with_value(&name))? 34 name_definition(&mut sb, token.with_value(&name))?
34 }, 35 },
35 _ => return None, 36 _ => return None,
36 } 37 }
@@ -67,19 +68,19 @@ impl ReferenceResult {
67} 68}
68 69
69pub(crate) fn reference_definition( 70pub(crate) fn reference_definition(
70 db: &RootDatabase, 71 sb: &mut SourceBinder<RootDatabase>,
71 name_ref: InFile<&ast::NameRef>, 72 name_ref: InFile<&ast::NameRef>,
72) -> ReferenceResult { 73) -> ReferenceResult {
73 use self::ReferenceResult::*; 74 use self::ReferenceResult::*;
74 75
75 let name_kind = classify_name_ref(db, name_ref).map(|d| d.kind); 76 let name_kind = classify_name_ref(sb, name_ref).map(|d| d.kind);
76 match name_kind { 77 match name_kind {
77 Some(Macro(it)) => return Exact(it.to_nav(db)), 78 Some(Macro(it)) => return Exact(it.to_nav(sb.db)),
78 Some(Field(it)) => return Exact(it.to_nav(db)), 79 Some(Field(it)) => return Exact(it.to_nav(sb.db)),
79 Some(TypeParam(it)) => return Exact(it.to_nav(db)), 80 Some(TypeParam(it)) => return Exact(it.to_nav(sb.db)),
80 Some(AssocItem(it)) => return Exact(it.to_nav(db)), 81 Some(AssocItem(it)) => return Exact(it.to_nav(sb.db)),
81 Some(Local(it)) => return Exact(it.to_nav(db)), 82 Some(Local(it)) => return Exact(it.to_nav(sb.db)),
82 Some(Def(def)) => match NavigationTarget::from_def(db, def) { 83 Some(Def(def)) => match NavigationTarget::from_def(sb.db, def) {
83 Some(nav) => return Exact(nav), 84 Some(nav) => return Exact(nav),
84 None => return Approximate(vec![]), 85 None => return Approximate(vec![]),
85 }, 86 },
@@ -87,21 +88,21 @@ pub(crate) fn reference_definition(
87 // FIXME: ideally, this should point to the type in the impl, and 88 // FIXME: ideally, this should point to the type in the impl, and
88 // not at the whole impl. And goto **type** definition should bring 89 // not at the whole impl. And goto **type** definition should bring
89 // us to the actual type 90 // us to the actual type
90 return Exact(imp.to_nav(db)); 91 return Exact(imp.to_nav(sb.db));
91 } 92 }
92 None => {} 93 None => {}
93 }; 94 };
94 95
95 // Fallback index based approach: 96 // Fallback index based approach:
96 let navs = crate::symbol_index::index_resolve(db, name_ref.value) 97 let navs = crate::symbol_index::index_resolve(sb.db, name_ref.value)
97 .into_iter() 98 .into_iter()
98 .map(|s| s.to_nav(db)) 99 .map(|s| s.to_nav(sb.db))
99 .collect(); 100 .collect();
100 Approximate(navs) 101 Approximate(navs)
101} 102}
102 103
103pub(crate) fn name_definition( 104fn name_definition(
104 db: &RootDatabase, 105 sb: &mut SourceBinder<RootDatabase>,
105 name: InFile<&ast::Name>, 106 name: InFile<&ast::Name>,
106) -> Option<Vec<NavigationTarget>> { 107) -> Option<Vec<NavigationTarget>> {
107 let parent = name.value.syntax().parent()?; 108 let parent = name.value.syntax().parent()?;
@@ -109,14 +110,14 @@ pub(crate) fn name_definition(
109 if let Some(module) = ast::Module::cast(parent.clone()) { 110 if let Some(module) = ast::Module::cast(parent.clone()) {
110 if module.has_semi() { 111 if module.has_semi() {
111 let src = name.with_value(module); 112 let src = name.with_value(module);
112 if let Some(child_module) = hir::Module::from_declaration(db, src) { 113 if let Some(child_module) = sb.to_def(src) {
113 let nav = child_module.to_nav(db); 114 let nav = child_module.to_nav(sb.db);
114 return Some(vec![nav]); 115 return Some(vec![nav]);
115 } 116 }
116 } 117 }
117 } 118 }
118 119
119 if let Some(nav) = named_target(db, name.with_value(&parent)) { 120 if let Some(nav) = named_target(sb.db, name.with_value(&parent)) {
120 return Some(vec![nav]); 121 return Some(vec![nav]);
121 } 122 }
122 123