aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_scope.rs
diff options
context:
space:
mode:
authorPaul Daniel Faria <[email protected]>2020-06-26 02:34:39 +0100
committerPaul Daniel Faria <[email protected]>2020-06-26 16:11:51 +0100
commit76755ce176222128c354647941cea65ac30ff4bd (patch)
treec79df926033b6eb94522c5dcf6f17734640eeb13 /crates/ra_hir_def/src/item_scope.rs
parentde9e964e4ac21897bd48adbe37f379d74422919f (diff)
Split glob import map to per-ns, switch ExprCollector to use a simpler push_res
Diffstat (limited to 'crates/ra_hir_def/src/item_scope.rs')
-rw-r--r--crates/ra_hir_def/src/item_scope.rs77
1 files changed, 56 insertions, 21 deletions
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index 511c08a8d..d0923df6d 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -4,12 +4,12 @@
4use hir_expand::name::Name; 4use hir_expand::name::Name;
5use once_cell::sync::Lazy; 5use once_cell::sync::Lazy;
6use ra_db::CrateId; 6use ra_db::CrateId;
7use rustc_hash::FxHashMap; 7use rustc_hash::{FxHashMap, FxHashSet};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, 11 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId,
12 Lookup, MacroDefId, ModuleDefId, TraitId, 12 LocalModuleId, Lookup, MacroDefId, ModuleDefId, TraitId,
13}; 13};
14 14
15#[derive(Copy, Clone)] 15#[derive(Copy, Clone)]
@@ -19,13 +19,6 @@ pub(crate) enum ImportType {
19} 19}
20 20
21impl ImportType { 21impl ImportType {
22 fn is_glob(&self) -> bool {
23 match self {
24 ImportType::Glob => true,
25 ImportType::Named => false,
26 }
27 }
28
29 fn is_named(&self) -> bool { 22 fn is_named(&self) -> bool {
30 match self { 23 match self {
31 ImportType::Glob => false, 24 ImportType::Glob => false,
@@ -34,6 +27,13 @@ impl ImportType {
34 } 27 }
35} 28}
36 29
30#[derive(Debug, Default)]
31pub struct PerNsGlobImports {
32 types: FxHashSet<(LocalModuleId, Name)>,
33 values: FxHashSet<(LocalModuleId, Name)>,
34 macros: FxHashSet<(LocalModuleId, Name)>,
35}
36
37#[derive(Debug, Default, PartialEq, Eq)] 37#[derive(Debug, Default, PartialEq, Eq)]
38pub struct ItemScope { 38pub struct ItemScope {
39 visible: FxHashMap<Name, PerNs>, 39 visible: FxHashMap<Name, PerNs>,
@@ -145,30 +145,65 @@ impl ItemScope {
145 self.legacy_macros.insert(name, mac); 145 self.legacy_macros.insert(name, mac);
146 } 146 }
147 147
148 pub(crate) fn push_res( 148 pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool {
149 let mut changed = false;
150 let existing = self.visible.entry(name).or_default();
151
152 if existing.types.is_none() && def.types.is_some() {
153 existing.types = def.types;
154 changed = true;
155 }
156
157 if existing.values.is_none() && def.values.is_some() {
158 existing.values = def.values;
159 changed = true;
160 }
161
162 if existing.macros.is_none() && def.macros.is_some() {
163 existing.macros = def.macros;
164 changed = true;
165 }
166
167 changed
168 }
169
170 pub(crate) fn push_res_with_import(
149 &mut self, 171 &mut self,
150 existing_import_map: &mut FxHashMap<Name, ImportType>, 172 glob_imports: &mut PerNsGlobImports,
151 name: Name, 173 lookup: (LocalModuleId, Name),
152 def: PerNs, 174 def: PerNs,
153 def_import_type: ImportType, 175 def_import_type: ImportType,
154 ) -> bool { 176 ) -> bool {
155 let mut changed = false; 177 let mut changed = false;
156 let existing = self.visible.entry(name.clone()).or_default(); 178 let existing = self.visible.entry(lookup.1.clone()).or_default();
157 let existing_import_type = existing_import_map.entry(name).or_insert(def_import_type);
158 179
159 macro_rules! check_changed { 180 macro_rules! check_changed {
160 ($changed:ident, ($existing:ident/$def:ident).$field:ident, $existing_import_type:ident, $def_import_type:ident) => { 181 (
182 $changed:ident,
183 ( $existing:ident / $def:ident ) . $field:ident,
184 $glob_imports:ident [ $lookup:ident ],
185 $def_import_type:ident
186 ) => {
161 match ($existing.$field, $def.$field) { 187 match ($existing.$field, $def.$field) {
162 (None, Some(_)) => { 188 (None, Some(_)) => {
163 *existing_import_type = $def_import_type; 189 match $def_import_type {
190 ImportType::Glob => {
191 $glob_imports.$field.insert($lookup.clone());
192 }
193 ImportType::Named => {
194 $glob_imports.$field.remove(&$lookup);
195 }
196 }
197
164 $existing.$field = $def.$field; 198 $existing.$field = $def.$field;
165 $changed = true; 199 $changed = true;
166 } 200 }
167 (Some(_), Some(_)) 201 (Some(_), Some(_))
168 if $existing_import_type.is_glob() && $def_import_type.is_named() => 202 if $glob_imports.$field.contains(&$lookup)
203 && $def_import_type.is_named() =>
169 { 204 {
170 mark::hit!(import_shadowed); 205 mark::hit!(import_shadowed);
171 *$existing_import_type = $def_import_type; 206 $glob_imports.$field.remove(&$lookup);
172 $existing.$field = $def.$field; 207 $existing.$field = $def.$field;
173 $changed = true; 208 $changed = true;
174 } 209 }
@@ -177,9 +212,9 @@ impl ItemScope {
177 }; 212 };
178 } 213 }
179 214
180 check_changed!(changed, (existing / def).types, existing_import_type, def_import_type); 215 check_changed!(changed, (existing / def).types, glob_imports[lookup], def_import_type);
181 check_changed!(changed, (existing / def).values, existing_import_type, def_import_type); 216 check_changed!(changed, (existing / def).values, glob_imports[lookup], def_import_type);
182 check_changed!(changed, (existing / def).macros, existing_import_type, def_import_type); 217 check_changed!(changed, (existing / def).macros, glob_imports[lookup], def_import_type);
183 218
184 changed 219 changed
185 } 220 }