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.rs149
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
3use hir::{db::AstDatabase, InFile, SourceBinder}; 3use hir::{db::AstDatabase, InFile, SourceBinder};
4use ra_ide_db::{defs::NameDefinition, symbol_index, RootDatabase}; 4use ra_ide_db::{symbol_index, RootDatabase};
5use ra_syntax::{ 5use 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
12use crate::{ 12use 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
126fn 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)]