diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/per_ns.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/per_ns.rs | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/crates/ra_hir/src/nameres/per_ns.rs b/crates/ra_hir/src/nameres/per_ns.rs index c40a3ff9d..d07cc08f4 100644 --- a/crates/ra_hir/src/nameres/per_ns.rs +++ b/crates/ra_hir/src/nameres/per_ns.rs | |||
@@ -1,78 +1,87 @@ | |||
1 | use crate::MacroDef; | ||
2 | |||
1 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | 3 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
2 | pub enum Namespace { | 4 | pub enum Namespace { |
3 | Types, | 5 | Types, |
4 | Values, | 6 | Values, |
7 | // Note that only type inference uses this enum, and it doesn't care about macros. | ||
8 | // Macro, | ||
5 | } | 9 | } |
6 | 10 | ||
7 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 11 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
8 | pub struct PerNs<T> { | 12 | pub struct PerNs<T> { |
9 | pub types: Option<T>, | 13 | pub types: Option<T>, |
10 | pub values: Option<T>, | 14 | pub values: Option<T>, |
15 | /// Since macros has different type, many methods simply ignore it. | ||
16 | /// We can only use special method like `get_macros` to access it. | ||
17 | pub macros: Option<MacroDef>, | ||
11 | } | 18 | } |
12 | 19 | ||
13 | impl<T> Default for PerNs<T> { | 20 | impl<T> Default for PerNs<T> { |
14 | fn default() -> Self { | 21 | fn default() -> Self { |
15 | PerNs { types: None, values: None } | 22 | PerNs { types: None, values: None, macros: None } |
16 | } | 23 | } |
17 | } | 24 | } |
18 | 25 | ||
19 | impl<T> PerNs<T> { | 26 | impl<T> PerNs<T> { |
20 | pub fn none() -> PerNs<T> { | 27 | pub fn none() -> PerNs<T> { |
21 | PerNs { types: None, values: None } | 28 | PerNs { types: None, values: None, macros: None } |
22 | } | 29 | } |
23 | 30 | ||
24 | pub fn values(t: T) -> PerNs<T> { | 31 | pub fn values(t: T) -> PerNs<T> { |
25 | PerNs { types: None, values: Some(t) } | 32 | PerNs { types: None, values: Some(t), macros: None } |
26 | } | 33 | } |
27 | 34 | ||
28 | pub fn types(t: T) -> PerNs<T> { | 35 | pub fn types(t: T) -> PerNs<T> { |
29 | PerNs { types: Some(t), values: None } | 36 | PerNs { types: Some(t), values: None, macros: None } |
30 | } | 37 | } |
31 | 38 | ||
32 | pub fn both(types: T, values: T) -> PerNs<T> { | 39 | pub fn both(types: T, values: T) -> PerNs<T> { |
33 | PerNs { types: Some(types), values: Some(values) } | 40 | PerNs { types: Some(types), values: Some(values), macros: None } |
34 | } | 41 | } |
35 | 42 | ||
36 | pub fn is_none(&self) -> bool { | 43 | pub fn macros(macro_: MacroDef) -> PerNs<T> { |
37 | self.types.is_none() && self.values.is_none() | 44 | PerNs { types: None, values: None, macros: Some(macro_) } |
38 | } | 45 | } |
39 | 46 | ||
40 | pub fn is_both(&self) -> bool { | 47 | pub fn is_none(&self) -> bool { |
41 | self.types.is_some() && self.values.is_some() | 48 | self.types.is_none() && self.values.is_none() && self.macros.is_none() |
42 | } | 49 | } |
43 | 50 | ||
44 | pub fn take(self, namespace: Namespace) -> Option<T> { | 51 | pub fn is_all(&self) -> bool { |
45 | match namespace { | 52 | self.types.is_some() && self.values.is_some() && self.macros.is_some() |
46 | Namespace::Types => self.types, | ||
47 | Namespace::Values => self.values, | ||
48 | } | ||
49 | } | 53 | } |
50 | 54 | ||
51 | pub fn take_types(self) -> Option<T> { | 55 | pub fn take_types(self) -> Option<T> { |
52 | self.take(Namespace::Types) | 56 | self.types |
53 | } | 57 | } |
54 | 58 | ||
55 | pub fn take_values(self) -> Option<T> { | 59 | pub fn take_values(self) -> Option<T> { |
56 | self.take(Namespace::Values) | 60 | self.values |
57 | } | 61 | } |
58 | 62 | ||
59 | pub fn get(&self, namespace: Namespace) -> Option<&T> { | 63 | pub fn get_macros(&self) -> Option<MacroDef> { |
60 | self.as_ref().take(namespace) | 64 | self.macros |
61 | } | 65 | } |
62 | 66 | ||
63 | pub fn as_ref(&self) -> PerNs<&T> { | 67 | pub fn only_macros(&self) -> PerNs<T> { |
64 | PerNs { types: self.types.as_ref(), values: self.values.as_ref() } | 68 | PerNs { types: None, values: None, macros: self.macros } |
65 | } | 69 | } |
66 | 70 | ||
67 | pub fn or(self, other: PerNs<T>) -> PerNs<T> { | 71 | pub fn as_ref(&self) -> PerNs<&T> { |
68 | PerNs { types: self.types.or(other.types), values: self.values.or(other.values) } | 72 | PerNs { types: self.types.as_ref(), values: self.values.as_ref(), macros: self.macros } |
69 | } | 73 | } |
70 | 74 | ||
71 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { | 75 | pub fn or(self, other: PerNs<T>) -> PerNs<T> { |
72 | PerNs { types: self.types.and_then(&f), values: self.values.and_then(&f) } | 76 | PerNs { |
77 | types: self.types.or(other.types), | ||
78 | values: self.values.or(other.values), | ||
79 | macros: self.macros.or(other.macros), | ||
80 | } | ||
73 | } | 81 | } |
74 | 82 | ||
83 | /// Map types and values. Leave macros unchanged. | ||
75 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { | 84 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { |
76 | PerNs { types: self.types.map(&f), values: self.values.map(&f) } | 85 | PerNs { types: self.types.map(&f), values: self.values.map(&f), macros: self.macros } |
77 | } | 86 | } |
78 | } | 87 | } |