diff options
Diffstat (limited to 'crates/ra_ide/src/goto_definition.rs')
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 39 |
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 | ||
3 | use hir::{db::AstDatabase, InFile}; | 3 | use hir::{db::AstDatabase, InFile, SourceBinder}; |
4 | use ra_syntax::{ | 4 | use 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 | ||
69 | pub(crate) fn reference_definition( | 70 | pub(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 | ||
103 | pub(crate) fn name_definition( | 104 | fn 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 | ||