1use mago_interner::ThreadedInterner;
2use serde::Deserialize;
3use serde::Serialize;
4use strum::Display;
5
6use mago_span::HasSpan;
7use mago_span::Span;
8
9use crate::ast::keyword::Keyword;
10use crate::sequence::Sequence;
11
12#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
20#[serde(tag = "type", content = "value")]
21#[repr(C, u8)]
22pub enum Modifier {
23 Static(Keyword),
24 Final(Keyword),
25 Abstract(Keyword),
26 Readonly(Keyword),
27 Public(Keyword),
28 PublicSet(Keyword),
29 Protected(Keyword),
30 ProtectedSet(Keyword),
31 Private(Keyword),
32 PrivateSet(Keyword),
33}
34
35impl Modifier {
36 pub fn get_keyword(&self) -> &Keyword {
37 match self {
38 Modifier::Static(k) => k,
39 Modifier::Final(k) => k,
40 Modifier::Abstract(k) => k,
41 Modifier::Readonly(k) => k,
42 Modifier::Public(k) => k,
43 Modifier::PublicSet(k) => k,
44 Modifier::Protected(k) => k,
45 Modifier::ProtectedSet(k) => k,
46 Modifier::Private(k) => k,
47 Modifier::PrivateSet(k) => k,
48 }
49 }
50
51 pub fn is_visibility(&self) -> bool {
53 matches!(
54 self,
55 Modifier::Public(..)
56 | Modifier::Protected(..)
57 | Modifier::Private(..)
58 | Modifier::PrivateSet(..)
59 | Modifier::ProtectedSet(..)
60 | Modifier::PublicSet(..)
61 )
62 }
63
64 pub fn is_read_visibility(&self) -> bool {
66 matches!(self, Modifier::Public(..) | Modifier::Protected(..) | Modifier::Private(..))
67 }
68
69 pub fn is_write_visibility(&self) -> bool {
71 matches!(self, Modifier::PrivateSet(..) | Modifier::ProtectedSet(..) | Modifier::PublicSet(..))
72 }
73
74 pub fn as_str<'a>(&self, interner: &'a ThreadedInterner) -> &'a str {
75 match self {
76 Modifier::Static(k) => interner.lookup(&k.value),
77 Modifier::Final(k) => interner.lookup(&k.value),
78 Modifier::Abstract(k) => interner.lookup(&k.value),
79 Modifier::Readonly(k) => interner.lookup(&k.value),
80 Modifier::Public(k) => interner.lookup(&k.value),
81 Modifier::Protected(k) => interner.lookup(&k.value),
82 Modifier::Private(k) => interner.lookup(&k.value),
83 Modifier::PrivateSet(k) => interner.lookup(&k.value),
84 Modifier::ProtectedSet(k) => interner.lookup(&k.value),
85 Modifier::PublicSet(k) => interner.lookup(&k.value),
86 }
87 }
88}
89
90impl HasSpan for Modifier {
91 fn span(&self) -> Span {
92 match self {
93 Modifier::Static(value)
94 | Modifier::Final(value)
95 | Modifier::Abstract(value)
96 | Modifier::Readonly(value)
97 | Modifier::Public(value)
98 | Modifier::Protected(value)
99 | Modifier::Private(value)
100 | Modifier::PrivateSet(value)
101 | Modifier::ProtectedSet(value)
102 | Modifier::PublicSet(value) => value.span(),
103 }
104 }
105}
106
107impl Sequence<Modifier> {
108 pub fn get_static(&self) -> Option<&Modifier> {
110 self.iter().find(|modifier| matches!(modifier, Modifier::Static(..)))
111 }
112
113 pub fn contains_static(&self) -> bool {
115 self.iter().any(|modifier| matches!(modifier, Modifier::Static(..)))
116 }
117
118 pub fn get_final(&self) -> Option<&Modifier> {
120 self.iter().find(|modifier| matches!(modifier, Modifier::Final(_)))
121 }
122
123 pub fn contains_final(&self) -> bool {
125 self.iter().any(|modifier| matches!(modifier, Modifier::Final(..)))
126 }
127
128 pub fn get_abstract(&self) -> Option<&Modifier> {
130 self.iter().find(|modifier| matches!(modifier, Modifier::Abstract(..)))
131 }
132
133 pub fn contains_abstract(&self) -> bool {
135 self.iter().any(|modifier| matches!(modifier, Modifier::Abstract(..)))
136 }
137
138 pub fn get_readonly(&self) -> Option<&Modifier> {
140 self.iter().find(|modifier| matches!(modifier, Modifier::Readonly(..)))
141 }
142
143 pub fn contains_readonly(&self) -> bool {
145 self.iter().any(|modifier| matches!(modifier, Modifier::Readonly(..)))
146 }
147
148 pub fn get_first_visibility(&self) -> Option<&Modifier> {
149 self.iter().find(|modifier| {
150 matches!(
151 modifier,
152 Modifier::Public(..)
153 | Modifier::Protected(..)
154 | Modifier::Private(..)
155 | Modifier::PrivateSet(..)
156 | Modifier::ProtectedSet(..)
157 | Modifier::PublicSet(..)
158 )
159 })
160 }
161
162 pub fn get_first_read_visibility(&self) -> Option<&Modifier> {
163 self.iter()
164 .find(|modifier| matches!(modifier, Modifier::Public(..) | Modifier::Protected(..) | Modifier::Private(..)))
165 }
166
167 pub fn get_first_write_visibility(&self) -> Option<&Modifier> {
168 self.iter().find(|modifier| {
169 matches!(modifier, Modifier::PrivateSet(..) | Modifier::ProtectedSet(..) | Modifier::PublicSet(..))
170 })
171 }
172
173 pub fn contains_visibility(&self) -> bool {
175 self.iter().any(Modifier::is_visibility)
176 }
177
178 pub fn get_public(&self) -> Option<&Modifier> {
179 self.iter().find(|modifier| matches!(modifier, Modifier::Public(..)))
180 }
181
182 pub fn contains_public(&self) -> bool {
184 self.iter().any(|modifier| matches!(modifier, Modifier::Public(..)))
185 }
186
187 pub fn get_protected(&self) -> Option<&Modifier> {
188 self.iter().find(|modifier| matches!(modifier, Modifier::Protected(..)))
189 }
190
191 pub fn contains_protected(&self) -> bool {
193 self.iter().any(|modifier| matches!(modifier, Modifier::Protected(..)))
194 }
195
196 pub fn get_private(&self) -> Option<&Modifier> {
197 self.iter().find(|modifier| matches!(modifier, Modifier::Private(..)))
198 }
199
200 pub fn contains_private(&self) -> bool {
202 self.iter().any(|modifier| matches!(modifier, Modifier::Private(..)))
203 }
204
205 pub fn get_private_set(&self) -> Option<&Modifier> {
206 self.iter().find(|modifier| matches!(modifier, Modifier::PrivateSet(..)))
207 }
208
209 pub fn contains_private_set(&self) -> bool {
210 self.iter().any(|modifier| matches!(modifier, Modifier::PrivateSet(..)))
211 }
212
213 pub fn get_protected_set(&self) -> Option<&Modifier> {
214 self.iter().find(|modifier| matches!(modifier, Modifier::ProtectedSet(..)))
215 }
216
217 pub fn contains_protected_set(&self) -> bool {
218 self.iter().any(|modifier| matches!(modifier, Modifier::ProtectedSet(..)))
219 }
220
221 pub fn get_public_set(&self) -> Option<&Modifier> {
222 self.iter().find(|modifier| matches!(modifier, Modifier::PublicSet(..)))
223 }
224
225 pub fn contains_public_set(&self) -> bool {
226 self.iter().any(|modifier| matches!(modifier, Modifier::PublicSet(..)))
227 }
228}