diff options
Diffstat (limited to 'crates/ra_ide/src/goto_definition.rs')
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 149 |
1 files changed, 14 insertions, 135 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index cce539e56..feff1ec3f 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -1,18 +1,18 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{db::AstDatabase, InFile, SourceBinder}; | 3 | use hir::{db::AstDatabase, InFile, SourceBinder}; |
4 | use ra_ide_db::{defs::NameDefinition, symbol_index, RootDatabase}; | 4 | use ra_ide_db::{symbol_index, RootDatabase}; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, DocCommentsOwner}, | 6 | ast::{self}, |
7 | match_ast, AstNode, | 7 | match_ast, AstNode, |
8 | SyntaxKind::*, | 8 | SyntaxKind::*, |
9 | SyntaxNode, SyntaxToken, TokenAtOffset, | 9 | SyntaxToken, TokenAtOffset, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | display::{ShortLabel, ToNav}, | 13 | display::{ToNav, TryToNav}, |
14 | expand::descend_into_macros, | 14 | expand::descend_into_macros, |
15 | references::classify_name_ref, | 15 | references::{classify_name, classify_name_ref}, |
16 | FilePosition, NavigationTarget, RangeInfo, | 16 | FilePosition, NavigationTarget, RangeInfo, |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -74,23 +74,12 @@ pub(crate) fn reference_definition( | |||
74 | use self::ReferenceResult::*; | 74 | use self::ReferenceResult::*; |
75 | 75 | ||
76 | let name_kind = classify_name_ref(sb, name_ref); | 76 | let name_kind = classify_name_ref(sb, name_ref); |
77 | match name_kind { | 77 | if let Some(def) = name_kind { |
78 | Some(NameDefinition::Macro(it)) => return Exact(it.to_nav(sb.db)), | 78 | return match def.try_to_nav(sb.db) { |
79 | Some(NameDefinition::StructField(it)) => return Exact(it.to_nav(sb.db)), | 79 | Some(nav) => ReferenceResult::Exact(nav), |
80 | Some(NameDefinition::TypeParam(it)) => return Exact(it.to_nav(sb.db)), | 80 | None => ReferenceResult::Approximate(Vec::new()), |
81 | Some(NameDefinition::Local(it)) => return Exact(it.to_nav(sb.db)), | 81 | }; |
82 | Some(NameDefinition::ModuleDef(def)) => match NavigationTarget::from_def(sb.db, def) { | 82 | } |
83 | Some(nav) => return Exact(nav), | ||
84 | None => return Approximate(vec![]), | ||
85 | }, | ||
86 | Some(NameDefinition::SelfType(imp)) => { | ||
87 | // 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 | // us to the actual type | ||
90 | return Exact(imp.to_nav(sb.db)); | ||
91 | } | ||
92 | None => {} | ||
93 | }; | ||
94 | 83 | ||
95 | // Fallback index based approach: | 84 | // Fallback index based approach: |
96 | let navs = symbol_index::index_resolve(sb.db, name_ref.value) | 85 | let navs = symbol_index::index_resolve(sb.db, name_ref.value) |
@@ -104,119 +93,9 @@ fn name_definition( | |||
104 | sb: &mut SourceBinder<RootDatabase>, | 93 | sb: &mut SourceBinder<RootDatabase>, |
105 | name: InFile<&ast::Name>, | 94 | name: InFile<&ast::Name>, |
106 | ) -> Option<Vec<NavigationTarget>> { | 95 | ) -> Option<Vec<NavigationTarget>> { |
107 | let parent = name.value.syntax().parent()?; | 96 | let def = classify_name(sb, name)?; |
108 | 97 | let nav = def.try_to_nav(sb.db)?; | |
109 | if let Some(module) = ast::Module::cast(parent.clone()) { | 98 | Some(vec![nav]) |
110 | if module.has_semi() { | ||
111 | let src = name.with_value(module); | ||
112 | if let Some(child_module) = sb.to_def(src) { | ||
113 | let nav = child_module.to_nav(sb.db); | ||
114 | return Some(vec![nav]); | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | if let Some(nav) = named_target(sb.db, name.with_value(&parent)) { | ||
120 | return Some(vec![nav]); | ||
121 | } | ||
122 | |||
123 | None | ||
124 | } | ||
125 | |||
126 | fn named_target(db: &RootDatabase, node: InFile<&SyntaxNode>) -> Option<NavigationTarget> { | ||
127 | match_ast! { | ||
128 | match (node.value) { | ||
129 | ast::StructDef(it) => { | ||
130 | Some(NavigationTarget::from_named( | ||
131 | db, | ||
132 | node.with_value(&it), | ||
133 | it.doc_comment_text(), | ||
134 | it.short_label(), | ||
135 | )) | ||
136 | }, | ||
137 | ast::EnumDef(it) => { | ||
138 | Some(NavigationTarget::from_named( | ||
139 | db, | ||
140 | node.with_value(&it), | ||
141 | it.doc_comment_text(), | ||
142 | it.short_label(), | ||
143 | )) | ||
144 | }, | ||
145 | ast::EnumVariant(it) => { | ||
146 | Some(NavigationTarget::from_named( | ||
147 | db, | ||
148 | node.with_value(&it), | ||
149 | it.doc_comment_text(), | ||
150 | it.short_label(), | ||
151 | )) | ||
152 | }, | ||
153 | ast::FnDef(it) => { | ||
154 | Some(NavigationTarget::from_named( | ||
155 | db, | ||
156 | node.with_value(&it), | ||
157 | it.doc_comment_text(), | ||
158 | it.short_label(), | ||
159 | )) | ||
160 | }, | ||
161 | ast::TypeAliasDef(it) => { | ||
162 | Some(NavigationTarget::from_named( | ||
163 | db, | ||
164 | node.with_value(&it), | ||
165 | it.doc_comment_text(), | ||
166 | it.short_label(), | ||
167 | )) | ||
168 | }, | ||
169 | ast::ConstDef(it) => { | ||
170 | Some(NavigationTarget::from_named( | ||
171 | db, | ||
172 | node.with_value(&it), | ||
173 | it.doc_comment_text(), | ||
174 | it.short_label(), | ||
175 | )) | ||
176 | }, | ||
177 | ast::StaticDef(it) => { | ||
178 | Some(NavigationTarget::from_named( | ||
179 | db, | ||
180 | node.with_value(&it), | ||
181 | it.doc_comment_text(), | ||
182 | it.short_label(), | ||
183 | )) | ||
184 | }, | ||
185 | ast::TraitDef(it) => { | ||
186 | Some(NavigationTarget::from_named( | ||
187 | db, | ||
188 | node.with_value(&it), | ||
189 | it.doc_comment_text(), | ||
190 | it.short_label(), | ||
191 | )) | ||
192 | }, | ||
193 | ast::RecordFieldDef(it) => { | ||
194 | Some(NavigationTarget::from_named( | ||
195 | db, | ||
196 | node.with_value(&it), | ||
197 | it.doc_comment_text(), | ||
198 | it.short_label(), | ||
199 | )) | ||
200 | }, | ||
201 | ast::Module(it) => { | ||
202 | Some(NavigationTarget::from_named( | ||
203 | db, | ||
204 | node.with_value(&it), | ||
205 | it.doc_comment_text(), | ||
206 | it.short_label(), | ||
207 | )) | ||
208 | }, | ||
209 | ast::MacroCall(it) => { | ||
210 | Some(NavigationTarget::from_named( | ||
211 | db, | ||
212 | node.with_value(&it), | ||
213 | it.doc_comment_text(), | ||
214 | None, | ||
215 | )) | ||
216 | }, | ||
217 | _ => None, | ||
218 | } | ||
219 | } | ||
220 | } | 99 | } |
221 | 100 | ||
222 | #[cfg(test)] | 101 | #[cfg(test)] |