diff options
Diffstat (limited to 'crates/hir_def/src/per_ns.rs')
-rw-r--r-- | crates/hir_def/src/per_ns.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/crates/hir_def/src/per_ns.rs b/crates/hir_def/src/per_ns.rs new file mode 100644 index 000000000..74665c588 --- /dev/null +++ b/crates/hir_def/src/per_ns.rs | |||
@@ -0,0 +1,95 @@ | |||
1 | //! In rust, it is possible to have a value, a type and a macro with the same | ||
2 | //! name without conflicts. | ||
3 | //! | ||
4 | //! `PerNs` (per namespace) captures this. | ||
5 | |||
6 | use hir_expand::MacroDefId; | ||
7 | |||
8 | use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId}; | ||
9 | |||
10 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
11 | pub struct PerNs { | ||
12 | pub types: Option<(ModuleDefId, Visibility)>, | ||
13 | pub values: Option<(ModuleDefId, Visibility)>, | ||
14 | pub macros: Option<(MacroDefId, Visibility)>, | ||
15 | } | ||
16 | |||
17 | impl Default for PerNs { | ||
18 | fn default() -> Self { | ||
19 | PerNs { types: None, values: None, macros: None } | ||
20 | } | ||
21 | } | ||
22 | |||
23 | impl PerNs { | ||
24 | pub fn none() -> PerNs { | ||
25 | PerNs { types: None, values: None, macros: None } | ||
26 | } | ||
27 | |||
28 | pub fn values(t: ModuleDefId, v: Visibility) -> PerNs { | ||
29 | PerNs { types: None, values: Some((t, v)), macros: None } | ||
30 | } | ||
31 | |||
32 | pub fn types(t: ModuleDefId, v: Visibility) -> PerNs { | ||
33 | PerNs { types: Some((t, v)), values: None, macros: None } | ||
34 | } | ||
35 | |||
36 | pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs { | ||
37 | PerNs { types: Some((types, v)), values: Some((values, v)), macros: None } | ||
38 | } | ||
39 | |||
40 | pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs { | ||
41 | PerNs { types: None, values: None, macros: Some((macro_, v)) } | ||
42 | } | ||
43 | |||
44 | pub fn is_none(&self) -> bool { | ||
45 | self.types.is_none() && self.values.is_none() && self.macros.is_none() | ||
46 | } | ||
47 | |||
48 | pub fn take_types(self) -> Option<ModuleDefId> { | ||
49 | self.types.map(|it| it.0) | ||
50 | } | ||
51 | |||
52 | pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> { | ||
53 | self.types | ||
54 | } | ||
55 | |||
56 | pub fn take_values(self) -> Option<ModuleDefId> { | ||
57 | self.values.map(|it| it.0) | ||
58 | } | ||
59 | |||
60 | pub fn take_macros(self) -> Option<MacroDefId> { | ||
61 | self.macros.map(|it| it.0) | ||
62 | } | ||
63 | |||
64 | pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs { | ||
65 | PerNs { | ||
66 | types: self.types.filter(|(_, v)| f(*v)), | ||
67 | values: self.values.filter(|(_, v)| f(*v)), | ||
68 | macros: self.macros.filter(|(_, v)| f(*v)), | ||
69 | } | ||
70 | } | ||
71 | |||
72 | pub fn with_visibility(self, vis: Visibility) -> PerNs { | ||
73 | PerNs { | ||
74 | types: self.types.map(|(it, _)| (it, vis)), | ||
75 | values: self.values.map(|(it, _)| (it, vis)), | ||
76 | macros: self.macros.map(|(it, _)| (it, vis)), | ||
77 | } | ||
78 | } | ||
79 | |||
80 | pub fn or(self, other: PerNs) -> PerNs { | ||
81 | PerNs { | ||
82 | types: self.types.or(other.types), | ||
83 | values: self.values.or(other.values), | ||
84 | macros: self.macros.or(other.macros), | ||
85 | } | ||
86 | } | ||
87 | |||
88 | pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> { | ||
89 | self.types | ||
90 | .map(|it| ItemInNs::Types(it.0)) | ||
91 | .into_iter() | ||
92 | .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter()) | ||
93 | .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter()) | ||
94 | } | ||
95 | } | ||