diff options
Diffstat (limited to 'crates/ide/src/call_hierarchy.rs')
-rw-r--r-- | crates/ide/src/call_hierarchy.rs | 77 |
1 files changed, 32 insertions, 45 deletions
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 60e0cd4ad..e8999a7f3 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs | |||
@@ -5,10 +5,10 @@ use indexmap::IndexMap; | |||
5 | use hir::Semantics; | 5 | use hir::Semantics; |
6 | use ide_db::call_info::FnCallNode; | 6 | use ide_db::call_info::FnCallNode; |
7 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
8 | use syntax::{ast, match_ast, AstNode, TextRange}; | 8 | use syntax::{ast, AstNode, TextRange}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | display::ToNav, goto_definition, references, FilePosition, NavigationTarget, RangeInfo, | 11 | display::TryToNav, goto_definition, references, FilePosition, NavigationTarget, RangeInfo, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | #[derive(Debug, Clone)] | 14 | #[derive(Debug, Clone)] |
@@ -47,28 +47,23 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio | |||
47 | 47 | ||
48 | let mut calls = CallLocations::default(); | 48 | let mut calls = CallLocations::default(); |
49 | 49 | ||
50 | for reference in refs.info.references() { | 50 | for (&file_id, references) in refs.info.references().iter() { |
51 | let file_id = reference.file_range.file_id; | ||
52 | let file = sema.parse(file_id); | 51 | let file = sema.parse(file_id); |
53 | let file = file.syntax(); | 52 | let file = file.syntax(); |
54 | let token = file.token_at_offset(reference.file_range.range.start()).next()?; | 53 | for reference in references { |
55 | let token = sema.descend_into_macros(token); | 54 | let token = file.token_at_offset(reference.range.start()).next()?; |
56 | let syntax = token.parent(); | 55 | let token = sema.descend_into_macros(token); |
57 | 56 | let syntax = token.parent(); | |
58 | // This target is the containing function | 57 | |
59 | if let Some(nav) = syntax.ancestors().find_map(|node| { | 58 | // This target is the containing function |
60 | match_ast! { | 59 | if let Some(nav) = syntax.ancestors().find_map(|node| { |
61 | match node { | 60 | let fn_ = ast::Fn::cast(node)?; |
62 | ast::Fn(it) => { | 61 | let def = sema.to_def(&fn_)?; |
63 | let def = sema.to_def(&it)?; | 62 | def.try_to_nav(sema.db) |
64 | Some(def.to_nav(sema.db)) | 63 | }) { |
65 | }, | 64 | let relative_range = reference.range; |
66 | _ => None, | 65 | calls.add(&nav, relative_range); |
67 | } | ||
68 | } | 66 | } |
69 | }) { | ||
70 | let relative_range = reference.file_range.range; | ||
71 | calls.add(&nav, relative_range); | ||
72 | } | 67 | } |
73 | } | 68 | } |
74 | 69 | ||
@@ -91,29 +86,21 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio | |||
91 | .filter_map(|node| FnCallNode::with_node_exact(&node)) | 86 | .filter_map(|node| FnCallNode::with_node_exact(&node)) |
92 | .filter_map(|call_node| { | 87 | .filter_map(|call_node| { |
93 | let name_ref = call_node.name_ref()?; | 88 | let name_ref = call_node.name_ref()?; |
94 | 89 | let func_target = match call_node { | |
95 | if let Some(func_target) = match &call_node { | ||
96 | FnCallNode::CallExpr(expr) => { | 90 | FnCallNode::CallExpr(expr) => { |
97 | //FIXME: Type::as_callable is broken | 91 | //FIXME: Type::as_callable is broken |
98 | let callable = sema.type_of_expr(&expr.expr()?)?.as_callable(db)?; | 92 | let callable = sema.type_of_expr(&expr.expr()?)?.as_callable(db)?; |
99 | match callable.kind() { | 93 | match callable.kind() { |
100 | hir::CallableKind::Function(it) => { | 94 | hir::CallableKind::Function(it) => it.try_to_nav(db), |
101 | let fn_def: hir::Function = it.into(); | ||
102 | let nav = fn_def.to_nav(db); | ||
103 | Some(nav) | ||
104 | } | ||
105 | _ => None, | 95 | _ => None, |
106 | } | 96 | } |
107 | } | 97 | } |
108 | FnCallNode::MethodCallExpr(expr) => { | 98 | FnCallNode::MethodCallExpr(expr) => { |
109 | let function = sema.resolve_method_call(&expr)?; | 99 | let function = sema.resolve_method_call(&expr)?; |
110 | Some(function.to_nav(db)) | 100 | function.try_to_nav(db) |
111 | } | 101 | } |
112 | } { | 102 | }?; |
113 | Some((func_target, name_ref.syntax().text_range())) | 103 | Some((func_target, name_ref.syntax().text_range())) |
114 | } else { | ||
115 | None | ||
116 | } | ||
117 | }) | 104 | }) |
118 | .for_each(|(nav, range)| calls.add(&nav, range)); | 105 | .for_each(|(nav, range)| calls.add(&nav, range)); |
119 | 106 | ||
@@ -178,7 +165,7 @@ mod tests { | |||
178 | //- /lib.rs | 165 | //- /lib.rs |
179 | fn callee() {} | 166 | fn callee() {} |
180 | fn caller() { | 167 | fn caller() { |
181 | call<|>ee(); | 168 | call$0ee(); |
182 | } | 169 | } |
183 | "#, | 170 | "#, |
184 | "callee Function FileId(0) 0..14 3..9", | 171 | "callee Function FileId(0) 0..14 3..9", |
@@ -192,7 +179,7 @@ fn caller() { | |||
192 | check_hierarchy( | 179 | check_hierarchy( |
193 | r#" | 180 | r#" |
194 | //- /lib.rs | 181 | //- /lib.rs |
195 | fn call<|>ee() {} | 182 | fn call$0ee() {} |
196 | fn caller() { | 183 | fn caller() { |
197 | callee(); | 184 | callee(); |
198 | } | 185 | } |
@@ -210,7 +197,7 @@ fn caller() { | |||
210 | //- /lib.rs | 197 | //- /lib.rs |
211 | fn callee() {} | 198 | fn callee() {} |
212 | fn caller() { | 199 | fn caller() { |
213 | call<|>ee(); | 200 | call$0ee(); |
214 | callee(); | 201 | callee(); |
215 | } | 202 | } |
216 | "#, | 203 | "#, |
@@ -227,7 +214,7 @@ fn caller() { | |||
227 | //- /lib.rs | 214 | //- /lib.rs |
228 | fn callee() {} | 215 | fn callee() {} |
229 | fn caller1() { | 216 | fn caller1() { |
230 | call<|>ee(); | 217 | call$0ee(); |
231 | } | 218 | } |
232 | 219 | ||
233 | fn caller2() { | 220 | fn caller2() { |
@@ -250,7 +237,7 @@ fn caller2() { | |||
250 | //- /lib.rs cfg:test | 237 | //- /lib.rs cfg:test |
251 | fn callee() {} | 238 | fn callee() {} |
252 | fn caller1() { | 239 | fn caller1() { |
253 | call<|>ee(); | 240 | call$0ee(); |
254 | } | 241 | } |
255 | 242 | ||
256 | #[cfg(test)] | 243 | #[cfg(test)] |
@@ -281,7 +268,7 @@ mod foo; | |||
281 | use foo::callee; | 268 | use foo::callee; |
282 | 269 | ||
283 | fn caller() { | 270 | fn caller() { |
284 | call<|>ee(); | 271 | call$0ee(); |
285 | } | 272 | } |
286 | 273 | ||
287 | //- /foo/mod.rs | 274 | //- /foo/mod.rs |
@@ -299,7 +286,7 @@ pub fn callee() {} | |||
299 | r#" | 286 | r#" |
300 | //- /lib.rs | 287 | //- /lib.rs |
301 | fn callee() {} | 288 | fn callee() {} |
302 | fn call<|>er() { | 289 | fn call$0er() { |
303 | callee(); | 290 | callee(); |
304 | callee(); | 291 | callee(); |
305 | } | 292 | } |
@@ -318,7 +305,7 @@ fn call<|>er() { | |||
318 | mod foo; | 305 | mod foo; |
319 | use foo::callee; | 306 | use foo::callee; |
320 | 307 | ||
321 | fn call<|>er() { | 308 | fn call$0er() { |
322 | callee(); | 309 | callee(); |
323 | } | 310 | } |
324 | 311 | ||
@@ -337,7 +324,7 @@ pub fn callee() {} | |||
337 | r#" | 324 | r#" |
338 | //- /lib.rs | 325 | //- /lib.rs |
339 | fn caller1() { | 326 | fn caller1() { |
340 | call<|>er2(); | 327 | call$0er2(); |
341 | } | 328 | } |
342 | 329 | ||
343 | fn caller2() { | 330 | fn caller2() { |
@@ -365,7 +352,7 @@ fn a() { | |||
365 | fn b() {} | 352 | fn b() {} |
366 | 353 | ||
367 | fn main() { | 354 | fn main() { |
368 | a<|>() | 355 | a$0() |
369 | } | 356 | } |
370 | "#, | 357 | "#, |
371 | "a Function FileId(0) 0..18 3..4", | 358 | "a Function FileId(0) 0..18 3..4", |
@@ -376,7 +363,7 @@ fn main() { | |||
376 | check_hierarchy( | 363 | check_hierarchy( |
377 | r#" | 364 | r#" |
378 | fn a() { | 365 | fn a() { |
379 | b<|>() | 366 | b$0() |
380 | } | 367 | } |
381 | 368 | ||
382 | fn b() {} | 369 | fn b() {} |