diff options
Diffstat (limited to 'crates/ide/src/references.rs')
-rw-r--r-- | crates/ide/src/references.rs | 119 |
1 files changed, 23 insertions, 96 deletions
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 7d4757e02..51a2f4327 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | pub(crate) mod rename; | 12 | pub(crate) mod rename; |
13 | 13 | ||
14 | use either::Either; | ||
14 | use hir::Semantics; | 15 | use hir::Semantics; |
15 | use ide_db::{ | 16 | use ide_db::{ |
16 | base_db::FileId, | 17 | base_db::FileId, |
@@ -21,10 +22,10 @@ use ide_db::{ | |||
21 | use syntax::{ | 22 | use syntax::{ |
22 | algo::find_node_at_offset, | 23 | algo::find_node_at_offset, |
23 | ast::{self, NameOwner}, | 24 | ast::{self, NameOwner}, |
24 | match_ast, AstNode, SyntaxNode, TextRange, TokenAtOffset, T, | 25 | AstNode, SyntaxNode, TextRange, TokenAtOffset, T, |
25 | }; | 26 | }; |
26 | 27 | ||
27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind}; | 28 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; |
28 | 29 | ||
29 | #[derive(Debug, Clone)] | 30 | #[derive(Debug, Clone)] |
30 | pub struct ReferenceSearchResult { | 31 | pub struct ReferenceSearchResult { |
@@ -90,10 +91,6 @@ pub(crate) fn find_all_refs( | |||
90 | let _p = profile::span("find_all_refs"); | 91 | let _p = profile::span("find_all_refs"); |
91 | let syntax = sema.parse(position.file_id).syntax().clone(); | 92 | let syntax = sema.parse(position.file_id).syntax().clone(); |
92 | 93 | ||
93 | if let Some(res) = try_find_self_references(&syntax, position) { | ||
94 | return Some(res); | ||
95 | } | ||
96 | |||
97 | let (opt_name, search_kind) = if let Some(name) = | 94 | let (opt_name, search_kind) = if let Some(name) = |
98 | get_struct_def_name_for_struct_literal_search(&sema, &syntax, position) | 95 | get_struct_def_name_for_struct_literal_search(&sema, &syntax, position) |
99 | { | 96 | { |
@@ -122,13 +119,16 @@ pub(crate) fn find_all_refs( | |||
122 | 119 | ||
123 | let mut kind = ReferenceKind::Other; | 120 | let mut kind = ReferenceKind::Other; |
124 | if let Definition::Local(local) = def { | 121 | if let Definition::Local(local) = def { |
125 | if let either::Either::Left(pat) = local.source(sema.db).value { | 122 | match local.source(sema.db).value { |
126 | if matches!( | 123 | Either::Left(pat) => { |
127 | pat.syntax().parent().and_then(ast::RecordPatField::cast), | 124 | if matches!( |
128 | Some(pat_field) if pat_field.name_ref().is_none() | 125 | pat.syntax().parent().and_then(ast::RecordPatField::cast), |
129 | ) { | 126 | Some(pat_field) if pat_field.name_ref().is_none() |
130 | kind = ReferenceKind::FieldShorthandForLocal; | 127 | ) { |
128 | kind = ReferenceKind::FieldShorthandForLocal; | ||
129 | } | ||
131 | } | 130 | } |
131 | Either::Right(_) => kind = ReferenceKind::SelfParam, | ||
132 | } | 132 | } |
133 | } else if matches!( | 133 | } else if matches!( |
134 | def, | 134 | def, |
@@ -251,79 +251,6 @@ fn get_enum_def_name_for_struct_literal_search( | |||
251 | None | 251 | None |
252 | } | 252 | } |
253 | 253 | ||
254 | fn try_find_self_references( | ||
255 | syntax: &SyntaxNode, | ||
256 | position: FilePosition, | ||
257 | ) -> Option<RangeInfo<ReferenceSearchResult>> { | ||
258 | let FilePosition { file_id, offset } = position; | ||
259 | let self_token = syntax.token_at_offset(offset).find(|t| t.kind() == T![self])?; | ||
260 | let parent = self_token.parent(); | ||
261 | match_ast! { | ||
262 | match parent { | ||
263 | ast::SelfParam(it) => (), | ||
264 | ast::PathSegment(segment) => { | ||
265 | segment.self_token()?; | ||
266 | let path = segment.parent_path(); | ||
267 | if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) { | ||
268 | return None; | ||
269 | } | ||
270 | }, | ||
271 | _ => return None, | ||
272 | } | ||
273 | }; | ||
274 | let function = parent.ancestors().find_map(ast::Fn::cast)?; | ||
275 | let self_param = function.param_list()?.self_param()?; | ||
276 | let param_self_token = self_param.self_token()?; | ||
277 | |||
278 | let declaration = Declaration { | ||
279 | nav: NavigationTarget { | ||
280 | file_id, | ||
281 | full_range: self_param.syntax().text_range(), | ||
282 | focus_range: Some(param_self_token.text_range()), | ||
283 | name: param_self_token.text().clone(), | ||
284 | kind: Some(SymbolKind::SelfParam), | ||
285 | container_name: None, | ||
286 | description: None, | ||
287 | docs: None, | ||
288 | }, | ||
289 | kind: ReferenceKind::SelfKw, | ||
290 | access: Some(if self_param.mut_token().is_some() { | ||
291 | ReferenceAccess::Write | ||
292 | } else { | ||
293 | ReferenceAccess::Read | ||
294 | }), | ||
295 | }; | ||
296 | let refs = function | ||
297 | .body() | ||
298 | .map(|body| { | ||
299 | body.syntax() | ||
300 | .descendants() | ||
301 | .filter_map(ast::PathExpr::cast) | ||
302 | .filter_map(|expr| { | ||
303 | let path = expr.path()?; | ||
304 | if path.qualifier().is_none() { | ||
305 | path.segment()?.self_token() | ||
306 | } else { | ||
307 | None | ||
308 | } | ||
309 | }) | ||
310 | .map(|token| FileReference { | ||
311 | range: token.text_range(), | ||
312 | kind: ReferenceKind::SelfKw, | ||
313 | access: declaration.access, // FIXME: properly check access kind here instead of copying it from the declaration | ||
314 | }) | ||
315 | .collect() | ||
316 | }) | ||
317 | .unwrap_or_default(); | ||
318 | let mut references = UsageSearchResult::default(); | ||
319 | references.references.insert(file_id, refs); | ||
320 | |||
321 | Some(RangeInfo::new( | ||
322 | param_self_token.text_range(), | ||
323 | ReferenceSearchResult { declaration, references }, | ||
324 | )) | ||
325 | } | ||
326 | |||
327 | #[cfg(test)] | 254 | #[cfg(test)] |
328 | mod tests { | 255 | mod tests { |
329 | use expect_test::{expect, Expect}; | 256 | use expect_test::{expect, Expect}; |
@@ -512,7 +439,7 @@ fn main() { | |||
512 | i = 5; | 439 | i = 5; |
513 | }"#, | 440 | }"#, |
514 | expect![[r#" | 441 | expect![[r#" |
515 | i Local FileId(0) 24..25 Other Write | 442 | i Local FileId(0) 20..25 24..25 Other Write |
516 | 443 | ||
517 | FileId(0) 50..51 Other Write | 444 | FileId(0) 50..51 Other Write |
518 | FileId(0) 54..55 Other Read | 445 | FileId(0) 54..55 Other Read |
@@ -536,7 +463,7 @@ fn bar() { | |||
536 | } | 463 | } |
537 | "#, | 464 | "#, |
538 | expect![[r#" | 465 | expect![[r#" |
539 | spam Local FileId(0) 19..23 Other | 466 | spam Local FileId(0) 19..23 19..23 Other |
540 | 467 | ||
541 | FileId(0) 34..38 Other Read | 468 | FileId(0) 34..38 Other Read |
542 | FileId(0) 41..45 Other Read | 469 | FileId(0) 41..45 Other Read |
@@ -551,7 +478,7 @@ fn bar() { | |||
551 | fn foo(i : u32) -> u32 { i$0 } | 478 | fn foo(i : u32) -> u32 { i$0 } |
552 | "#, | 479 | "#, |
553 | expect![[r#" | 480 | expect![[r#" |
554 | i ValueParam FileId(0) 7..8 Other | 481 | i ValueParam FileId(0) 7..8 7..8 Other |
555 | 482 | ||
556 | FileId(0) 25..26 Other Read | 483 | FileId(0) 25..26 Other Read |
557 | "#]], | 484 | "#]], |
@@ -565,7 +492,7 @@ fn foo(i : u32) -> u32 { i$0 } | |||
565 | fn foo(i$0 : u32) -> u32 { i } | 492 | fn foo(i$0 : u32) -> u32 { i } |
566 | "#, | 493 | "#, |
567 | expect![[r#" | 494 | expect![[r#" |
568 | i ValueParam FileId(0) 7..8 Other | 495 | i ValueParam FileId(0) 7..8 7..8 Other |
569 | 496 | ||
570 | FileId(0) 25..26 Other Read | 497 | FileId(0) 25..26 Other Read |
571 | "#]], | 498 | "#]], |
@@ -813,7 +740,7 @@ fn foo() { | |||
813 | } | 740 | } |
814 | "#, | 741 | "#, |
815 | expect![[r#" | 742 | expect![[r#" |
816 | i Local FileId(0) 23..24 Other Write | 743 | i Local FileId(0) 19..24 23..24 Other Write |
817 | 744 | ||
818 | FileId(0) 34..35 Other Write | 745 | FileId(0) 34..35 Other Write |
819 | FileId(0) 38..39 Other Read | 746 | FileId(0) 38..39 Other Read |
@@ -853,7 +780,7 @@ fn foo() { | |||
853 | } | 780 | } |
854 | "#, | 781 | "#, |
855 | expect![[r#" | 782 | expect![[r#" |
856 | i Local FileId(0) 19..20 Other | 783 | i Local FileId(0) 19..20 19..20 Other |
857 | 784 | ||
858 | FileId(0) 26..27 Other Write | 785 | FileId(0) 26..27 Other Write |
859 | "#]], | 786 | "#]], |
@@ -995,10 +922,10 @@ impl Foo { | |||
995 | } | 922 | } |
996 | "#, | 923 | "#, |
997 | expect![[r#" | 924 | expect![[r#" |
998 | self SelfParam FileId(0) 47..51 47..51 SelfKw Read | 925 | self SelfParam FileId(0) 47..51 47..51 SelfParam |
999 | 926 | ||
1000 | FileId(0) 71..75 SelfKw Read | 927 | FileId(0) 71..75 Other Read |
1001 | FileId(0) 152..156 SelfKw Read | 928 | FileId(0) 152..156 Other Read |
1002 | "#]], | 929 | "#]], |
1003 | ); | 930 | ); |
1004 | } | 931 | } |
@@ -1105,7 +1032,7 @@ fn main() { | |||
1105 | } | 1032 | } |
1106 | "#, | 1033 | "#, |
1107 | expect![[r#" | 1034 | expect![[r#" |
1108 | a Local FileId(0) 59..60 Other | 1035 | a Local FileId(0) 59..60 59..60 Other |
1109 | 1036 | ||
1110 | FileId(0) 80..81 Other Read | 1037 | FileId(0) 80..81 Other Read |
1111 | "#]], | 1038 | "#]], |
@@ -1123,7 +1050,7 @@ fn main() { | |||
1123 | } | 1050 | } |
1124 | "#, | 1051 | "#, |
1125 | expect![[r#" | 1052 | expect![[r#" |
1126 | a Local FileId(0) 59..60 Other | 1053 | a Local FileId(0) 59..60 59..60 Other |
1127 | 1054 | ||
1128 | FileId(0) 80..81 Other Read | 1055 | FileId(0) 80..81 Other Read |
1129 | "#]], | 1056 | "#]], |