aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/references.rs
diff options
context:
space:
mode:
authorEkaterina Babshukova <[email protected]>2019-10-22 21:46:53 +0100
committerEkaterina Babshukova <[email protected]>2019-10-22 22:35:06 +0100
commitdecfd28bd14b56befa17257694caacc57a090939 (patch)
treecdf5a5b39600b41a9eee301b9760cde1282aeb33 /crates/ra_ide_api/src/references.rs
parentb5a3ee93e24931c8bba628ddc7be4f098a19a326 (diff)
some fixes, add docs
Diffstat (limited to 'crates/ra_ide_api/src/references.rs')
-rw-r--r--crates/ra_ide_api/src/references.rs39
1 files changed, 20 insertions, 19 deletions
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index aadd52616..f35d835ac 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -1,4 +1,13 @@
1//! FIXME: write short doc here 1//! This module implements a reference search.
2//! First, the element at the cursor position must be either an `ast::Name`
3//! or `ast::NameRef`. If it's a `ast::NameRef`, at the classification step we
4//! try to resolve the direct tree parent of this element, otherwise we
5//! already have a definition and just need to get its HIR together with
6//! some information that is needed for futher steps of searching.
7//! After that, we collect files that might contain references and look
8//! for text occurrences of the identifier. If there's an `ast::NameRef`
9//! at the index that the match starts at and its tree parent is
10//! resolved to the search element definition, we get a reference.
2 11
3mod classify; 12mod classify;
4mod name_definition; 13mod name_definition;
@@ -9,7 +18,7 @@ use once_cell::unsync::Lazy;
9use ra_db::{SourceDatabase, SourceDatabaseExt}; 18use ra_db::{SourceDatabase, SourceDatabaseExt};
10use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode, TextUnit}; 19use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode, TextUnit};
11 20
12use crate::{db::RootDatabase, FileId, FilePosition, FileRange, NavigationTarget, RangeInfo}; 21use crate::{db::RootDatabase, FilePosition, FileRange, NavigationTarget, RangeInfo};
13 22
14pub(crate) use self::{ 23pub(crate) use self::{
15 classify::{classify_name, classify_name_ref}, 24 classify::{classify_name, classify_name_ref},
@@ -102,16 +111,7 @@ fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> V
102 let scope = def.search_scope(db); 111 let scope = def.search_scope(db);
103 let mut refs = vec![]; 112 let mut refs = vec![];
104 113
105 let is_match = |file_id: FileId, name_ref: &ast::NameRef| -> bool { 114 for (file_id, search_range) in scope {
106 let classified = classify_name_ref(db, file_id, &name_ref);
107 if let Some(d) = classified {
108 d == def
109 } else {
110 false
111 }
112 };
113
114 for (file_id, text_range) in scope {
115 let text = db.file_text(file_id); 115 let text = db.file_text(file_id);
116 let parse = Lazy::new(|| SourceFile::parse(&text)); 116 let parse = Lazy::new(|| SourceFile::parse(&text));
117 117
@@ -122,19 +122,20 @@ fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> V
122 find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset) 122 find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset)
123 { 123 {
124 let range = name_ref.syntax().text_range(); 124 let range = name_ref.syntax().text_range();
125 125 if let Some(search_range) = search_range {
126 if let Some(text_range) = text_range { 126 if !range.is_subrange(&search_range) {
127 if range.is_subrange(&text_range) && is_match(file_id, &name_ref) { 127 continue;
128 }
129 }
130 if let Some(d) = classify_name_ref(db, file_id, &name_ref) {
131 if d == def {
128 refs.push(FileRange { file_id, range }); 132 refs.push(FileRange { file_id, range });
129 } 133 }
130 } else if is_match(file_id, &name_ref) {
131 refs.push(FileRange { file_id, range });
132 } 134 }
133 } 135 }
134 } 136 }
135 } 137 }
136 138 refs
137 return refs;
138} 139}
139 140
140#[cfg(test)] 141#[cfg(test)]