diff options
Diffstat (limited to 'crates/ra_ide/src/references/search_scope.rs')
-rw-r--r-- | crates/ra_ide/src/references/search_scope.rs | 102 |
1 files changed, 50 insertions, 52 deletions
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs index 97c65c2cd..279f57be0 100644 --- a/crates/ra_ide/src/references/search_scope.rs +++ b/crates/ra_ide/src/references/search_scope.rs | |||
@@ -19,59 +19,13 @@ pub struct SearchScope { | |||
19 | } | 19 | } |
20 | 20 | ||
21 | impl SearchScope { | 21 | impl 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 | |||
59 | impl 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 | |||
67 | impl 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 | |||
132 | impl 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 | } |