aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r--crates/ide_db/src/search.rs63
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};
10use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; 10use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility};
11use once_cell::unsync::Lazy; 11use once_cell::unsync::Lazy;
12use rustc_hash::FxHashMap; 12use rustc_hash::FxHashMap;
13use syntax::{ 13use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
14 ast, match_ast, AstNode, NodeOrToken, SyntaxElement, SyntaxNode, TextRange, TextSize,
15};
16 14
17use crate::defs::NameClass; 15use crate::defs::NameClass;
18use crate::{ 16use crate::{
@@ -20,13 +18,6 @@ use crate::{
20 RootDatabase, 18 RootDatabase,
21}; 19};
22 20
23#[derive(Debug, Clone)]
24pub enum NameKind {
25 Name,
26 NameRef,
27 Lifetime,
28}
29
30#[derive(Debug, Default, Clone)] 21#[derive(Debug, Default, Clone)]
31pub struct UsageSearchResult { 22pub 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
62impl 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
71mod __ { 71mod __ {
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)]
80pub struct FileReference { 80pub 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
86impl 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
106fn 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)]
114pub enum ReferenceAccess { 87pub 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 };