aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/display/navigation_target.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-11-03 17:49:41 +0000
committerEdwin Cheng <[email protected]>2019-11-04 17:38:20 +0000
commite8741b9d75eb4edd711c6516c3b17c87c0431166 (patch)
tree49c2f6a78a35fcf7399a40b96805caa68aec6172 /crates/ra_ide_api/src/display/navigation_target.rs
parent67226ebc8288b9489867ea2454f9d976b65ff15e (diff)
Use new expansion feature in goto_definition
Diffstat (limited to 'crates/ra_ide_api/src/display/navigation_target.rs')
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs122
1 files changed, 90 insertions, 32 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,