aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs122
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs37
2 files changed, 114 insertions, 45 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index 5cb67fb95..0c3e25ce6 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -29,6 +29,20 @@ pub struct NavigationTarget {
29 docs: Option<String>, 29 docs: Option<String>,
30} 30}
31 31
32fn find_range_from_node(
33 db: &RootDatabase,
34 src: hir::HirFileId,
35 node: &SyntaxNode,
36) -> (FileId, TextRange) {
37 let text_range = node.text_range();
38 let (file_id, text_range) = src
39 .parent_expansion(db)
40 .and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files))
41 .unwrap_or((src, text_range));
42
43 (file_id.original_file(db), text_range)
44}
45
32impl NavigationTarget { 46impl NavigationTarget {
33 /// When `focus_range` is specified, returns it. otherwise 47 /// When `focus_range` is specified, returns it. otherwise
34 /// returns `full_range` 48 /// returns `full_range`
@@ -72,8 +86,12 @@ impl NavigationTarget {
72 self.focus_range 86 self.focus_range
73 } 87 }
74 88
75 pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget { 89 pub(crate) fn from_bind_pat(
76 NavigationTarget::from_named(file_id, pat, None, None) 90 db: &RootDatabase,
91 file_id: FileId,
92 pat: &ast::BindPat,
93 ) -> NavigationTarget {
94 NavigationTarget::from_named(db, file_id.into(), pat, None, None)
77 } 95 }
78 96
79 pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { 97 pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget {
@@ -96,7 +114,7 @@ impl NavigationTarget {
96 ) -> NavigationTarget { 114 ) -> NavigationTarget {
97 let parse = db.parse(file_id); 115 let parse = db.parse(file_id);
98 let pat = pat.to_node(parse.tree().syntax()); 116 let pat = pat.to_node(parse.tree().syntax());
99 NavigationTarget::from_bind_pat(file_id, &pat) 117 NavigationTarget::from_bind_pat(db, file_id, &pat)
100 } 118 }
101 119
102 pub(crate) fn from_self_param( 120 pub(crate) fn from_self_param(
@@ -119,31 +137,47 @@ impl NavigationTarget {
119 137
120 pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { 138 pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
121 let src = module.definition_source(db); 139 let src = module.definition_source(db);
122 let file_id = src.file_id.original_file(db);
123 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 140 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
141
124 match src.ast { 142 match src.ast {
125 ModuleSource::SourceFile(node) => { 143 ModuleSource::SourceFile(node) => {
126 NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None) 144 let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax());
145
146 NavigationTarget::from_syntax(
147 file_id,
148 name,
149 None,
150 text_range,
151 node.syntax(),
152 None,
153 None,
154 )
155 }
156 ModuleSource::Module(node) => {
157 let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax());
158
159 NavigationTarget::from_syntax(
160 file_id,
161 name,
162 None,
163 text_range,
164 node.syntax(),
165 node.doc_comment_text(),
166 node.short_label(),
167 )
127 } 168 }
128 ModuleSource::Module(node) => NavigationTarget::from_syntax(
129 file_id,
130 name,
131 None,
132 node.syntax(),
133 node.doc_comment_text(),
134 node.short_label(),
135 ),
136 } 169 }
137 } 170 }
138 171
139 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { 172 pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
140 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 173 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
141 if let Some(src) = module.declaration_source(db) { 174 if let Some(src) = module.declaration_source(db) {
142 let file_id = src.file_id.original_file(db); 175 let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax());
143 return NavigationTarget::from_syntax( 176 return NavigationTarget::from_syntax(
144 file_id, 177 file_id,
145 name, 178 name,
146 None, 179 None,
180 text_range,
147 src.ast.syntax(), 181 src.ast.syntax(),
148 src.ast.doc_comment_text(), 182 src.ast.doc_comment_text(),
149 src.ast.short_label(), 183 src.ast.short_label(),
@@ -154,13 +188,25 @@ impl NavigationTarget {
154 188
155 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { 189 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
156 let src = field.source(db); 190 let src = field.source(db);
157 let file_id = src.file_id.original_file(db);
158 match src.ast { 191 match src.ast {
159 FieldSource::Named(it) => { 192 FieldSource::Named(it) => NavigationTarget::from_named(
160 NavigationTarget::from_named(file_id, &it, it.doc_comment_text(), it.short_label()) 193 db,
161 } 194 src.file_id,
195 &it,
196 it.doc_comment_text(),
197 it.short_label(),
198 ),
162 FieldSource::Pos(it) => { 199 FieldSource::Pos(it) => {
163 NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax(), None, None) 200 let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax());
201 NavigationTarget::from_syntax(
202 file_id,
203 "".into(),
204 None,
205 text_range,
206 it.syntax(),
207 None,
208 None,
209 )
164 } 210 }
165 } 211 }
166 } 212 }
@@ -172,7 +218,8 @@ impl NavigationTarget {
172 { 218 {
173 let src = def.source(db); 219 let src = def.source(db);
174 NavigationTarget::from_named( 220 NavigationTarget::from_named(
175 src.file_id.original_file(db), 221 db,
222 src.file_id,
176 &src.ast, 223 &src.ast,
177 src.ast.doc_comment_text(), 224 src.ast.doc_comment_text(),
178 src.ast.short_label(), 225 src.ast.short_label(),
@@ -212,10 +259,13 @@ impl NavigationTarget {
212 impl_block: hir::ImplBlock, 259 impl_block: hir::ImplBlock,
213 ) -> NavigationTarget { 260 ) -> NavigationTarget {
214 let src = impl_block.source(db); 261 let src = impl_block.source(db);
262 let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax());
263
215 NavigationTarget::from_syntax( 264 NavigationTarget::from_syntax(
216 src.file_id.original_file(db), 265 file_id,
217 "impl".into(), 266 "impl".into(),
218 None, 267 None,
268 text_range,
219 src.ast.syntax(), 269 src.ast.syntax(),
220 None, 270 None,
221 None, 271 None,
@@ -236,12 +286,7 @@ impl NavigationTarget {
236 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { 286 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
237 let src = macro_call.source(db); 287 let src = macro_call.source(db);
238 log::debug!("nav target {:#?}", src.ast.syntax()); 288 log::debug!("nav target {:#?}", src.ast.syntax());
239 NavigationTarget::from_named( 289 NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None)
240 src.file_id.original_file(db),
241 &src.ast,
242 src.ast.doc_comment_text(),
243 None,
244 )
245 } 290 }
246 291
247 #[cfg(test)] 292 #[cfg(test)]
@@ -270,21 +315,35 @@ impl NavigationTarget {
270 315
271 /// Allows `NavigationTarget` to be created from a `NameOwner` 316 /// Allows `NavigationTarget` to be created from a `NameOwner`
272 pub(crate) fn from_named( 317 pub(crate) fn from_named(
273 file_id: FileId, 318 db: &RootDatabase,
319 file_id: hir::HirFileId,
274 node: &impl ast::NameOwner, 320 node: &impl ast::NameOwner,
275 docs: Option<String>, 321 docs: Option<String>,
276 description: Option<String>, 322 description: Option<String>,
277 ) -> NavigationTarget { 323 ) -> NavigationTarget {
278 //FIXME: use `_` instead of empty string 324 //FIXME: use `_` instead of empty string
279 let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); 325 let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
280 let focus_range = node.name().map(|it| it.syntax().text_range()); 326
281 NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description) 327 let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1);
328
329 let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax());
330
331 NavigationTarget::from_syntax(
332 file_id,
333 name,
334 focus_range,
335 full_range,
336 node.syntax(),
337 docs,
338 description,
339 )
282 } 340 }
283 341
284 fn from_syntax( 342 fn from_syntax(
285 file_id: FileId, 343 file_id: FileId,
286 name: SmolStr, 344 name: SmolStr,
287 focus_range: Option<TextRange>, 345 focus_range: Option<TextRange>,
346 full_range: TextRange,
288 node: &SyntaxNode, 347 node: &SyntaxNode,
289 docs: Option<String>, 348 docs: Option<String>,
290 description: Option<String>, 349 description: Option<String>,
@@ -293,9 +352,8 @@ impl NavigationTarget {
293 file_id, 352 file_id,
294 name, 353 name,
295 kind: node.kind(), 354 kind: node.kind(),
296 full_range: node.text_range(), 355 full_range,
297 focus_range, 356 focus_range,
298 // ptr: Some(LocalSyntaxPtr::new(node)),
299 container_name: None, 357 container_name: None,
300 description, 358 description,
301 docs, 359 docs,
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index c1ce54bea..97127706f 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -101,19 +101,20 @@ pub(crate) fn name_definition(
101 } 101 }
102 } 102 }
103 103
104 if let Some(nav) = named_target(file_id, &parent) { 104 if let Some(nav) = named_target(db, file_id, &parent) {
105 return Some(vec![nav]); 105 return Some(vec![nav]);
106 } 106 }
107 107
108 None 108 None
109} 109}
110 110
111fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> { 111fn named_target(db: &RootDatabase, file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> {
112 match_ast! { 112 match_ast! {
113 match node { 113 match node {
114 ast::StructDef(it) => { 114 ast::StructDef(it) => {
115 Some(NavigationTarget::from_named( 115 Some(NavigationTarget::from_named(
116 file_id, 116 db,
117 file_id.into(),
117 &it, 118 &it,
118 it.doc_comment_text(), 119 it.doc_comment_text(),
119 it.short_label(), 120 it.short_label(),
@@ -121,7 +122,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
121 }, 122 },
122 ast::EnumDef(it) => { 123 ast::EnumDef(it) => {
123 Some(NavigationTarget::from_named( 124 Some(NavigationTarget::from_named(
124 file_id, 125 db,
126 file_id.into(),
125 &it, 127 &it,
126 it.doc_comment_text(), 128 it.doc_comment_text(),
127 it.short_label(), 129 it.short_label(),
@@ -129,7 +131,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
129 }, 131 },
130 ast::EnumVariant(it) => { 132 ast::EnumVariant(it) => {
131 Some(NavigationTarget::from_named( 133 Some(NavigationTarget::from_named(
132 file_id, 134 db,
135 file_id.into(),
133 &it, 136 &it,
134 it.doc_comment_text(), 137 it.doc_comment_text(),
135 it.short_label(), 138 it.short_label(),
@@ -137,7 +140,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
137 }, 140 },
138 ast::FnDef(it) => { 141 ast::FnDef(it) => {
139 Some(NavigationTarget::from_named( 142 Some(NavigationTarget::from_named(
140 file_id, 143 db,
144 file_id.into(),
141 &it, 145 &it,
142 it.doc_comment_text(), 146 it.doc_comment_text(),
143 it.short_label(), 147 it.short_label(),
@@ -145,7 +149,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
145 }, 149 },
146 ast::TypeAliasDef(it) => { 150 ast::TypeAliasDef(it) => {
147 Some(NavigationTarget::from_named( 151 Some(NavigationTarget::from_named(
148 file_id, 152 db,
153 file_id.into(),
149 &it, 154 &it,
150 it.doc_comment_text(), 155 it.doc_comment_text(),
151 it.short_label(), 156 it.short_label(),
@@ -153,7 +158,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
153 }, 158 },
154 ast::ConstDef(it) => { 159 ast::ConstDef(it) => {
155 Some(NavigationTarget::from_named( 160 Some(NavigationTarget::from_named(
156 file_id, 161 db,
162 file_id.into(),
157 &it, 163 &it,
158 it.doc_comment_text(), 164 it.doc_comment_text(),
159 it.short_label(), 165 it.short_label(),
@@ -161,7 +167,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
161 }, 167 },
162 ast::StaticDef(it) => { 168 ast::StaticDef(it) => {
163 Some(NavigationTarget::from_named( 169 Some(NavigationTarget::from_named(
164 file_id, 170 db,
171 file_id.into(),
165 &it, 172 &it,
166 it.doc_comment_text(), 173 it.doc_comment_text(),
167 it.short_label(), 174 it.short_label(),
@@ -169,7 +176,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
169 }, 176 },
170 ast::TraitDef(it) => { 177 ast::TraitDef(it) => {
171 Some(NavigationTarget::from_named( 178 Some(NavigationTarget::from_named(
172 file_id, 179 db,
180 file_id.into(),
173 &it, 181 &it,
174 it.doc_comment_text(), 182 it.doc_comment_text(),
175 it.short_label(), 183 it.short_label(),
@@ -177,7 +185,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
177 }, 185 },
178 ast::RecordFieldDef(it) => { 186 ast::RecordFieldDef(it) => {
179 Some(NavigationTarget::from_named( 187 Some(NavigationTarget::from_named(
180 file_id, 188 db,
189 file_id.into(),
181 &it, 190 &it,
182 it.doc_comment_text(), 191 it.doc_comment_text(),
183 it.short_label(), 192 it.short_label(),
@@ -185,7 +194,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
185 }, 194 },
186 ast::Module(it) => { 195 ast::Module(it) => {
187 Some(NavigationTarget::from_named( 196 Some(NavigationTarget::from_named(
188 file_id, 197 db,
198 file_id.into(),
189 &it, 199 &it,
190 it.doc_comment_text(), 200 it.doc_comment_text(),
191 it.short_label(), 201 it.short_label(),
@@ -193,7 +203,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
193 }, 203 },
194 ast::MacroCall(it) => { 204 ast::MacroCall(it) => {
195 Some(NavigationTarget::from_named( 205 Some(NavigationTarget::from_named(
196 file_id, 206 db,
207 file_id.into(),
197 &it, 208 &it,
198 it.doc_comment_text(), 209 it.doc_comment_text(),
199 None, 210 None,