diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/display.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 66 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 149 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs | 12 |
4 files changed, 58 insertions, 171 deletions
diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs index fbe89841b..1c26a8697 100644 --- a/crates/ra_ide/src/display.rs +++ b/crates/ra_ide/src/display.rs | |||
@@ -15,7 +15,7 @@ pub use function_signature::FunctionSignature; | |||
15 | pub use navigation_target::NavigationTarget; | 15 | pub use navigation_target::NavigationTarget; |
16 | pub use structure::{file_structure, StructureNode}; | 16 | pub use structure::{file_structure, StructureNode}; |
17 | 17 | ||
18 | pub(crate) use navigation_target::ToNav; | 18 | pub(crate) use navigation_target::{ToNav, TryToNav}; |
19 | pub(crate) use short_label::ShortLabel; | 19 | pub(crate) use short_label::ShortLabel; |
20 | 20 | ||
21 | pub(crate) fn function_label(node: &ast::FnDef) -> String { | 21 | pub(crate) fn function_label(node: &ast::FnDef) -> String { |
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index 096c41c81..b42cb477e 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | TextRange, | 11 | TextRange, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{expand::original_range, FileSymbol}; | 14 | use crate::{expand::original_range, references::NameDefinition, FileSymbol}; |
15 | 15 | ||
16 | use super::short_label::ShortLabel; | 16 | use super::short_label::ShortLabel; |
17 | 17 | ||
@@ -36,6 +36,10 @@ pub(crate) trait ToNav { | |||
36 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; | 36 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget; |
37 | } | 37 | } |
38 | 38 | ||
39 | pub(crate) trait TryToNav { | ||
40 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget>; | ||
41 | } | ||
42 | |||
39 | impl NavigationTarget { | 43 | impl NavigationTarget { |
40 | /// When `focus_range` is specified, returns it. otherwise | 44 | /// When `focus_range` is specified, returns it. otherwise |
41 | /// returns `full_range` | 45 | /// returns `full_range` |
@@ -96,26 +100,6 @@ impl NavigationTarget { | |||
96 | module.to_nav(db) | 100 | module.to_nav(db) |
97 | } | 101 | } |
98 | 102 | ||
99 | pub(crate) fn from_def( | ||
100 | db: &RootDatabase, | ||
101 | module_def: hir::ModuleDef, | ||
102 | ) -> Option<NavigationTarget> { | ||
103 | let nav = match module_def { | ||
104 | hir::ModuleDef::Module(module) => module.to_nav(db), | ||
105 | hir::ModuleDef::Function(it) => it.to_nav(db), | ||
106 | hir::ModuleDef::Adt(it) => it.to_nav(db), | ||
107 | hir::ModuleDef::Const(it) => it.to_nav(db), | ||
108 | hir::ModuleDef::Static(it) => it.to_nav(db), | ||
109 | hir::ModuleDef::EnumVariant(it) => it.to_nav(db), | ||
110 | hir::ModuleDef::Trait(it) => it.to_nav(db), | ||
111 | hir::ModuleDef::TypeAlias(it) => it.to_nav(db), | ||
112 | hir::ModuleDef::BuiltinType(..) => { | ||
113 | return None; | ||
114 | } | ||
115 | }; | ||
116 | Some(nav) | ||
117 | } | ||
118 | |||
119 | #[cfg(test)] | 103 | #[cfg(test)] |
120 | pub(crate) fn assert_match(&self, expected: &str) { | 104 | pub(crate) fn assert_match(&self, expected: &str) { |
121 | let actual = self.debug_render(); | 105 | let actual = self.debug_render(); |
@@ -201,6 +185,36 @@ impl ToNav for FileSymbol { | |||
201 | } | 185 | } |
202 | } | 186 | } |
203 | 187 | ||
188 | impl TryToNav for NameDefinition { | ||
189 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | ||
190 | match self { | ||
191 | NameDefinition::Macro(it) => Some(it.to_nav(db)), | ||
192 | NameDefinition::StructField(it) => Some(it.to_nav(db)), | ||
193 | NameDefinition::ModuleDef(it) => it.try_to_nav(db), | ||
194 | NameDefinition::SelfType(it) => Some(it.to_nav(db)), | ||
195 | NameDefinition::Local(it) => Some(it.to_nav(db)), | ||
196 | NameDefinition::TypeParam(it) => Some(it.to_nav(db)), | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | impl TryToNav for hir::ModuleDef { | ||
202 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | ||
203 | let res = match self { | ||
204 | hir::ModuleDef::Module(it) => it.to_nav(db), | ||
205 | hir::ModuleDef::Function(it) => it.to_nav(db), | ||
206 | hir::ModuleDef::Adt(it) => it.to_nav(db), | ||
207 | hir::ModuleDef::EnumVariant(it) => it.to_nav(db), | ||
208 | hir::ModuleDef::Const(it) => it.to_nav(db), | ||
209 | hir::ModuleDef::Static(it) => it.to_nav(db), | ||
210 | hir::ModuleDef::Trait(it) => it.to_nav(db), | ||
211 | hir::ModuleDef::TypeAlias(it) => it.to_nav(db), | ||
212 | hir::ModuleDef::BuiltinType(_) => return None, | ||
213 | }; | ||
214 | Some(res) | ||
215 | } | ||
216 | } | ||
217 | |||
204 | pub(crate) trait ToNavFromAst {} | 218 | pub(crate) trait ToNavFromAst {} |
205 | impl ToNavFromAst for hir::Function {} | 219 | impl ToNavFromAst for hir::Function {} |
206 | impl ToNavFromAst for hir::Const {} | 220 | impl ToNavFromAst for hir::Const {} |
@@ -232,15 +246,17 @@ impl ToNav for hir::Module { | |||
232 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 246 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
233 | let src = self.definition_source(db); | 247 | let src = self.definition_source(db); |
234 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 248 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
235 | let syntax = match &src.value { | 249 | let (syntax, focus) = match &src.value { |
236 | ModuleSource::SourceFile(node) => node.syntax(), | 250 | ModuleSource::SourceFile(node) => (node.syntax(), None), |
237 | ModuleSource::Module(node) => node.syntax(), | 251 | ModuleSource::Module(node) => { |
252 | (node.syntax(), node.name().map(|it| it.syntax().text_range())) | ||
253 | } | ||
238 | }; | 254 | }; |
239 | let frange = original_range(db, src.with_value(syntax)); | 255 | let frange = original_range(db, src.with_value(syntax)); |
240 | NavigationTarget::from_syntax( | 256 | NavigationTarget::from_syntax( |
241 | frange.file_id, | 257 | frange.file_id, |
242 | name, | 258 | name, |
243 | None, | 259 | focus, |
244 | frange.range, | 260 | frange.range, |
245 | syntax.kind(), | 261 | syntax.kind(), |
246 | None, | 262 | None, |
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)] |
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 7f790a62d..aadc2dbcb 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -25,7 +25,7 @@ use ra_syntax::{ | |||
25 | match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset, | 25 | match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TextUnit, TokenAtOffset, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | use crate::{display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; | 28 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; |
29 | 29 | ||
30 | pub(crate) use self::{ | 30 | pub(crate) use self::{ |
31 | classify::{classify_name, classify_name_ref}, | 31 | classify::{classify_name, classify_name_ref}, |
@@ -125,15 +125,7 @@ pub(crate) fn find_all_refs( | |||
125 | }; | 125 | }; |
126 | 126 | ||
127 | let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?; | 127 | let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?; |
128 | 128 | let declaration = def.try_to_nav(db)?; | |
129 | let declaration = match def { | ||
130 | NameDefinition::Macro(mac) => mac.to_nav(db), | ||
131 | NameDefinition::StructField(field) => field.to_nav(db), | ||
132 | NameDefinition::ModuleDef(def) => NavigationTarget::from_def(db, def)?, | ||
133 | NameDefinition::SelfType(imp) => imp.to_nav(db), | ||
134 | NameDefinition::Local(local) => local.to_nav(db), | ||
135 | NameDefinition::TypeParam(_) => return None, | ||
136 | }; | ||
137 | 129 | ||
138 | let search_scope = { | 130 | let search_scope = { |
139 | let base = SearchScope::for_def(&def, db); | 131 | let base = SearchScope::for_def(&def, db); |