aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/references/search_scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/references/search_scope.rs')
-rw-r--r--crates/ra_ide/src/references/search_scope.rs104
1 files changed, 51 insertions, 53 deletions
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index f8211a746..279f57be0 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -10,7 +10,7 @@ use ra_prof::profile;
10use ra_syntax::{AstNode, TextRange}; 10use ra_syntax::{AstNode, TextRange};
11use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
12 12
13use crate::db::RootDatabase; 13use ra_ide_db::RootDatabase;
14 14
15use super::{NameDefinition, NameKind}; 15use super::{NameDefinition, NameKind};
16 16
@@ -19,59 +19,13 @@ pub struct SearchScope {
19} 19}
20 20
21impl SearchScope { 21impl SearchScope {
22 fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope { 22 pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope {
23 SearchScope { entries }
24 }
25 pub fn single_file(file: FileId) -> SearchScope {
26 SearchScope::new(std::iter::once((file, None)).collect())
27 }
28 pub(crate) fn intersection(&self, other: &SearchScope) -> SearchScope {
29 let (mut small, mut large) = (&self.entries, &other.entries);
30 if small.len() > large.len() {
31 mem::swap(&mut small, &mut large)
32 }
33
34 let res = small
35 .iter()
36 .filter_map(|(file_id, r1)| {
37 let r2 = large.get(file_id)?;
38 let r = intersect_ranges(*r1, *r2)?;
39 Some((*file_id, r))
40 })
41 .collect();
42 return SearchScope::new(res);
43
44 fn intersect_ranges(
45 r1: Option<TextRange>,
46 r2: Option<TextRange>,
47 ) -> Option<Option<TextRange>> {
48 match (r1, r2) {
49 (None, r) | (r, None) => Some(r),
50 (Some(r1), Some(r2)) => {
51 let r = r1.intersection(&r2)?;
52 Some(Some(r))
53 }
54 }
55 }
56 }
57}
58
59impl IntoIterator for SearchScope {
60 type Item = (FileId, Option<TextRange>);
61 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
62 fn into_iter(self) -> Self::IntoIter {
63 self.entries.into_iter()
64 }
65}
66
67impl NameDefinition {
68 pub(crate) fn search_scope(&self, db: &RootDatabase) -> SearchScope {
69 let _p = profile("search_scope"); 23 let _p = profile("search_scope");
70 24
71 let module_src = self.container.definition_source(db); 25 let module_src = def.container.definition_source(db);
72 let file_id = module_src.file_id.original_file(db); 26 let file_id = module_src.file_id.original_file(db);
73 27
74 if let NameKind::Local(var) = self.kind { 28 if let NameKind::Local(var) = def.kind {
75 let range = match var.parent(db) { 29 let range = match var.parent(db) {
76 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), 30 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(),
77 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), 31 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(),
@@ -82,10 +36,10 @@ impl NameDefinition {
82 return SearchScope::new(res); 36 return SearchScope::new(res);
83 } 37 }
84 38
85 let vis = self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); 39 let vis = def.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default();
86 40
87 if vis.as_str() == "pub(super)" { 41 if vis.as_str() == "pub(super)" {
88 if let Some(parent_module) = self.container.parent(db) { 42 if let Some(parent_module) = def.container.parent(db) {
89 let mut res = FxHashMap::default(); 43 let mut res = FxHashMap::default();
90 let parent_src = parent_module.definition_source(db); 44 let parent_src = parent_module.definition_source(db);
91 let file_id = parent_src.file_id.original_file(db); 45 let file_id = parent_src.file_id.original_file(db);
@@ -118,7 +72,7 @@ impl NameDefinition {
118 return SearchScope::new(res); 72 return SearchScope::new(res);
119 } 73 }
120 if vis.as_str() == "pub" { 74 if vis.as_str() == "pub" {
121 let krate = self.container.krate(); 75 let krate = def.container.krate();
122 for rev_dep in krate.reverse_dependencies(db) { 76 for rev_dep in krate.reverse_dependencies(db) {
123 let root_file = rev_dep.root_file(db); 77 let root_file = rev_dep.root_file(db);
124 let source_root_id = db.file_source_root(root_file); 78 let source_root_id = db.file_source_root(root_file);
@@ -137,4 +91,48 @@ impl NameDefinition {
137 res.insert(file_id, range); 91 res.insert(file_id, range);
138 SearchScope::new(res) 92 SearchScope::new(res)
139 } 93 }
94
95 fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope {
96 SearchScope { entries }
97 }
98 pub fn single_file(file: FileId) -> SearchScope {
99 SearchScope::new(std::iter::once((file, None)).collect())
100 }
101 pub(crate) fn intersection(&self, other: &SearchScope) -> SearchScope {
102 let (mut small, mut large) = (&self.entries, &other.entries);
103 if small.len() > large.len() {
104 mem::swap(&mut small, &mut large)
105 }
106
107 let res = small
108 .iter()
109 .filter_map(|(file_id, r1)| {
110 let r2 = large.get(file_id)?;
111 let r = intersect_ranges(*r1, *r2)?;
112 Some((*file_id, r))
113 })
114 .collect();
115 return SearchScope::new(res);
116
117 fn intersect_ranges(
118 r1: Option<TextRange>,
119 r2: Option<TextRange>,
120 ) -> Option<Option<TextRange>> {
121 match (r1, r2) {
122 (None, r) | (r, None) => Some(r),
123 (Some(r1), Some(r2)) => {
124 let r = r1.intersection(&r2)?;
125 Some(Some(r))
126 }
127 }
128 }
129 }
130}
131
132impl IntoIterator for SearchScope {
133 type Item = (FileId, Option<TextRange>);
134 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
135 fn into_iter(self) -> Self::IntoIter {
136 self.entries.into_iter()
137 }
140} 138}