diff options
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r-- | crates/ide_db/src/search.rs | 63 |
1 files changed, 20 insertions, 43 deletions
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index d0aed26f7..38b20f2dc 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -10,9 +10,7 @@ use base_db::{FileId, FileRange, SourceDatabaseExt}; | |||
10 | use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; | 10 | use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; |
11 | use once_cell::unsync::Lazy; | 11 | use once_cell::unsync::Lazy; |
12 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
13 | use syntax::{ | 13 | use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; |
14 | ast, match_ast, AstNode, NodeOrToken, SyntaxElement, SyntaxNode, TextRange, TextSize, | ||
15 | }; | ||
16 | 14 | ||
17 | use crate::defs::NameClass; | 15 | use crate::defs::NameClass; |
18 | use crate::{ | 16 | use crate::{ |
@@ -20,13 +18,6 @@ use crate::{ | |||
20 | RootDatabase, | 18 | RootDatabase, |
21 | }; | 19 | }; |
22 | 20 | ||
23 | #[derive(Debug, Clone)] | ||
24 | pub enum NameKind { | ||
25 | Name, | ||
26 | NameRef, | ||
27 | Lifetime, | ||
28 | } | ||
29 | |||
30 | #[derive(Debug, Default, Clone)] | 21 | #[derive(Debug, Default, Clone)] |
31 | pub struct UsageSearchResult { | 22 | pub struct UsageSearchResult { |
32 | pub references: FxHashMap<FileId, Vec<FileReference>>, | 23 | pub references: FxHashMap<FileId, Vec<FileReference>>, |
@@ -68,6 +59,15 @@ pub enum NameLike { | |||
68 | Lifetime(ast::Lifetime), | 59 | Lifetime(ast::Lifetime), |
69 | } | 60 | } |
70 | 61 | ||
62 | impl NameLike { | ||
63 | pub fn as_name_ref(&self) -> Option<&ast::NameRef> { | ||
64 | match self { | ||
65 | NameLike::NameRef(name_ref) => Some(name_ref), | ||
66 | _ => None, | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | mod __ { | 71 | mod __ { |
72 | use super::{ | 72 | use super::{ |
73 | ast::{Lifetime, Name, NameRef}, | 73 | ast::{Lifetime, Name, NameRef}, |
@@ -79,37 +79,10 @@ mod __ { | |||
79 | #[derive(Debug, Clone)] | 79 | #[derive(Debug, Clone)] |
80 | pub struct FileReference { | 80 | pub struct FileReference { |
81 | pub range: TextRange, | 81 | pub range: TextRange, |
82 | pub name: NameKind, | 82 | pub name: NameLike, |
83 | pub access: Option<ReferenceAccess>, | 83 | pub access: Option<ReferenceAccess>, |
84 | } | 84 | } |
85 | 85 | ||
86 | impl FileReference { | ||
87 | pub fn name_from_syntax(&self, root: &SyntaxNode) -> Option<NameLike> { | ||
88 | let node = node_or_parent(root.covering_element(self.range)); | ||
89 | match self.name { | ||
90 | NameKind::Name => ast::Name::cast(node).map(Into::into), | ||
91 | NameKind::NameRef => ast::NameRef::cast(node).map(Into::into), | ||
92 | NameKind::Lifetime => ast::Lifetime::cast(node).map(Into::into), | ||
93 | } | ||
94 | } | ||
95 | |||
96 | pub fn as_name_ref(&self, root: &SyntaxNode) -> Option<ast::NameRef> { | ||
97 | match self.name { | ||
98 | NameKind::NameRef => { | ||
99 | ast::NameRef::cast(node_or_parent(root.covering_element(self.range))) | ||
100 | } | ||
101 | _ => None, | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | fn node_or_parent(ele: SyntaxElement) -> SyntaxNode { | ||
107 | match ele { | ||
108 | NodeOrToken::Node(node) => node, | ||
109 | NodeOrToken::Token(token) => token.parent(), | ||
110 | } | ||
111 | } | ||
112 | |||
113 | #[derive(Debug, Copy, Clone, PartialEq)] | 86 | #[derive(Debug, Copy, Clone, PartialEq)] |
114 | pub enum ReferenceAccess { | 87 | pub enum ReferenceAccess { |
115 | Read, | 88 | Read, |
@@ -408,7 +381,11 @@ impl<'a> FindUsages<'a> { | |||
408 | match NameRefClass::classify_lifetime(self.sema, lifetime) { | 381 | match NameRefClass::classify_lifetime(self.sema, lifetime) { |
409 | Some(NameRefClass::Definition(def)) if &def == self.def => { | 382 | Some(NameRefClass::Definition(def)) if &def == self.def => { |
410 | let FileRange { file_id, range } = self.sema.original_range(lifetime.syntax()); | 383 | let FileRange { file_id, range } = self.sema.original_range(lifetime.syntax()); |
411 | let reference = FileReference { range, name: NameKind::Lifetime, access: None }; | 384 | let reference = FileReference { |
385 | range, | ||
386 | name: NameLike::Lifetime(lifetime.clone()), | ||
387 | access: None, | ||
388 | }; | ||
412 | sink(file_id, reference) | 389 | sink(file_id, reference) |
413 | } | 390 | } |
414 | _ => false, // not a usage | 391 | _ => false, // not a usage |
@@ -425,7 +402,7 @@ impl<'a> FindUsages<'a> { | |||
425 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); | 402 | let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax()); |
426 | let reference = FileReference { | 403 | let reference = FileReference { |
427 | range, | 404 | range, |
428 | name: NameKind::NameRef, | 405 | name: NameLike::NameRef(name_ref.clone()), |
429 | access: reference_access(&def, &name_ref), | 406 | access: reference_access(&def, &name_ref), |
430 | }; | 407 | }; |
431 | sink(file_id, reference) | 408 | sink(file_id, reference) |
@@ -435,12 +412,12 @@ impl<'a> FindUsages<'a> { | |||
435 | let reference = match self.def { | 412 | let reference = match self.def { |
436 | Definition::Field(_) if &field == self.def => FileReference { | 413 | Definition::Field(_) if &field == self.def => FileReference { |
437 | range, | 414 | range, |
438 | name: NameKind::NameRef, | 415 | name: NameLike::NameRef(name_ref.clone()), |
439 | access: reference_access(&field, &name_ref), | 416 | access: reference_access(&field, &name_ref), |
440 | }, | 417 | }, |
441 | Definition::Local(l) if &local == l => FileReference { | 418 | Definition::Local(l) if &local == l => FileReference { |
442 | range, | 419 | range, |
443 | name: NameKind::NameRef, | 420 | name: NameLike::NameRef(name_ref.clone()), |
444 | access: reference_access(&Definition::Local(local), &name_ref), | 421 | access: reference_access(&Definition::Local(local), &name_ref), |
445 | }, | 422 | }, |
446 | _ => return false, // not a usage | 423 | _ => return false, // not a usage |
@@ -464,7 +441,7 @@ impl<'a> FindUsages<'a> { | |||
464 | let FileRange { file_id, range } = self.sema.original_range(name.syntax()); | 441 | let FileRange { file_id, range } = self.sema.original_range(name.syntax()); |
465 | let reference = FileReference { | 442 | let reference = FileReference { |
466 | range, | 443 | range, |
467 | name: NameKind::Name, | 444 | name: NameLike::Name(name.clone()), |
468 | // FIXME: mutable patterns should have `Write` access | 445 | // FIXME: mutable patterns should have `Write` access |
469 | access: Some(ReferenceAccess::Read), | 446 | access: Some(ReferenceAccess::Read), |
470 | }; | 447 | }; |