aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/search.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/search.rs')
-rw-r--r--crates/ra_ide_db/src/search.rs94
1 files changed, 47 insertions, 47 deletions
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs
index 0963ea257..7bd99d4cc 100644
--- a/crates/ra_ide_db/src/search.rs
+++ b/crates/ra_ide_db/src/search.rs
@@ -55,16 +55,58 @@ impl SearchScope {
55 SearchScope::new(std::iter::once((file, None)).collect()) 55 SearchScope::new(std::iter::once((file, None)).collect())
56 } 56 }
57 57
58 pub fn for_def(def: &Definition, db: &RootDatabase) -> SearchScope { 58 pub fn intersection(&self, other: &SearchScope) -> SearchScope {
59 let (mut small, mut large) = (&self.entries, &other.entries);
60 if small.len() > large.len() {
61 mem::swap(&mut small, &mut large)
62 }
63
64 let res = small
65 .iter()
66 .filter_map(|(file_id, r1)| {
67 let r2 = large.get(file_id)?;
68 let r = intersect_ranges(*r1, *r2)?;
69 Some((*file_id, r))
70 })
71 .collect();
72
73 return SearchScope::new(res);
74
75 fn intersect_ranges(
76 r1: Option<TextRange>,
77 r2: Option<TextRange>,
78 ) -> Option<Option<TextRange>> {
79 match (r1, r2) {
80 (None, r) | (r, None) => Some(r),
81 (Some(r1), Some(r2)) => {
82 let r = r1.intersection(&r2)?;
83 Some(Some(r))
84 }
85 }
86 }
87 }
88}
89
90impl IntoIterator for SearchScope {
91 type Item = (FileId, Option<TextRange>);
92 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
93
94 fn into_iter(self) -> Self::IntoIter {
95 self.entries.into_iter()
96 }
97}
98
99impl Definition {
100 fn search_scope(&self, db: &RootDatabase) -> SearchScope {
59 let _p = profile("search_scope"); 101 let _p = profile("search_scope");
60 let module = match def.module(db) { 102 let module = match self.module(db) {
61 Some(it) => it, 103 Some(it) => it,
62 None => return SearchScope::empty(), 104 None => return SearchScope::empty(),
63 }; 105 };
64 let module_src = module.definition_source(db); 106 let module_src = module.definition_source(db);
65 let file_id = module_src.file_id.original_file(db); 107 let file_id = module_src.file_id.original_file(db);
66 108
67 if let Definition::Local(var) = def { 109 if let Definition::Local(var) = self {
68 let range = match var.parent(db) { 110 let range = match var.parent(db) {
69 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), 111 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(),
70 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), 112 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(),
@@ -75,7 +117,7 @@ impl SearchScope {
75 return SearchScope::new(res); 117 return SearchScope::new(res);
76 } 118 }
77 119
78 let vis = def.visibility(db).as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); 120 let vis = self.visibility(db).as_ref().map(|v| v.syntax().to_string()).unwrap_or_default();
79 121
80 if vis.as_str() == "pub(super)" { 122 if vis.as_str() == "pub(super)" {
81 if let Some(parent_module) = module.parent(db) { 123 if let Some(parent_module) = module.parent(db) {
@@ -131,48 +173,6 @@ impl SearchScope {
131 SearchScope::new(res) 173 SearchScope::new(res)
132 } 174 }
133 175
134 pub fn intersection(&self, other: &SearchScope) -> SearchScope {
135 let (mut small, mut large) = (&self.entries, &other.entries);
136 if small.len() > large.len() {
137 mem::swap(&mut small, &mut large)
138 }
139
140 let res = small
141 .iter()
142 .filter_map(|(file_id, r1)| {
143 let r2 = large.get(file_id)?;
144 let r = intersect_ranges(*r1, *r2)?;
145 Some((*file_id, r))
146 })
147 .collect();
148
149 return SearchScope::new(res);
150
151 fn intersect_ranges(
152 r1: Option<TextRange>,
153 r2: Option<TextRange>,
154 ) -> Option<Option<TextRange>> {
155 match (r1, r2) {
156 (None, r) | (r, None) => Some(r),
157 (Some(r1), Some(r2)) => {
158 let r = r1.intersection(&r2)?;
159 Some(Some(r))
160 }
161 }
162 }
163 }
164}
165
166impl IntoIterator for SearchScope {
167 type Item = (FileId, Option<TextRange>);
168 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
169
170 fn into_iter(self) -> Self::IntoIter {
171 self.entries.into_iter()
172 }
173}
174
175impl Definition {
176 pub fn find_usages( 176 pub fn find_usages(
177 &self, 177 &self,
178 db: &RootDatabase, 178 db: &RootDatabase,
@@ -181,7 +181,7 @@ impl Definition {
181 let _p = profile("Definition::find_usages"); 181 let _p = profile("Definition::find_usages");
182 182
183 let search_scope = { 183 let search_scope = {
184 let base = SearchScope::for_def(self, db); 184 let base = self.search_scope(db);
185 match search_scope { 185 match search_scope {
186 None => base, 186 None => base,
187 Some(scope) => base.intersection(&scope), 187 Some(scope) => base.intersection(&scope),