Skip to main content

mago_syntax/ast/ast/class_like/
member.rs

1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::Sequence;
8use crate::ast::ast::class_like::constant::ClassLikeConstant;
9use crate::ast::ast::class_like::enum_case::EnumCase;
10use crate::ast::ast::class_like::method::Method;
11use crate::ast::ast::class_like::property::Property;
12use crate::ast::ast::class_like::trait_use::TraitUse;
13use crate::ast::ast::expression::Expression;
14use crate::ast::ast::identifier::LocalIdentifier;
15use crate::ast::ast::variable::Variable;
16
17#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
18#[serde(tag = "type", content = "value")]
19pub enum ClassLikeMember<'arena> {
20    TraitUse(TraitUse<'arena>),
21    Constant(ClassLikeConstant<'arena>),
22    Property(Property<'arena>),
23    EnumCase(EnumCase<'arena>),
24    Method(Method<'arena>),
25}
26
27#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
28#[serde(tag = "type", content = "value")]
29pub enum ClassLikeMemberSelector<'arena> {
30    Identifier(LocalIdentifier<'arena>),
31    Variable(Variable<'arena>),
32    Expression(ClassLikeMemberExpressionSelector<'arena>),
33    Missing(Span),
34}
35
36#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
37#[serde(tag = "type", content = "value")]
38pub enum ClassLikeConstantSelector<'arena> {
39    Identifier(LocalIdentifier<'arena>),
40    Expression(ClassLikeMemberExpressionSelector<'arena>),
41    Missing(Span),
42}
43
44#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
45pub struct ClassLikeMemberExpressionSelector<'arena> {
46    pub left_brace: Span,
47    pub expression: &'arena Expression<'arena>,
48    pub right_brace: Span,
49}
50
51impl ClassLikeMember<'_> {
52    #[inline]
53    #[must_use]
54    pub const fn is_trait_use(&self) -> bool {
55        matches!(self, ClassLikeMember::TraitUse(_))
56    }
57
58    #[inline]
59    #[must_use]
60    pub const fn is_constant(&self) -> bool {
61        matches!(self, ClassLikeMember::Constant(_))
62    }
63
64    #[inline]
65    #[must_use]
66    pub const fn is_property(&self) -> bool {
67        matches!(self, ClassLikeMember::Property(_))
68    }
69
70    #[inline]
71    #[must_use]
72    pub const fn is_enum_case(&self) -> bool {
73        matches!(self, ClassLikeMember::EnumCase(_))
74    }
75
76    #[inline]
77    #[must_use]
78    pub const fn is_method(&self) -> bool {
79        matches!(self, ClassLikeMember::Method(_))
80    }
81}
82
83impl ClassLikeMemberSelector<'_> {
84    #[inline]
85    #[must_use]
86    pub const fn is_identifier(&self) -> bool {
87        matches!(self, ClassLikeMemberSelector::Identifier(_))
88    }
89
90    #[inline]
91    #[must_use]
92    pub const fn is_variable(&self) -> bool {
93        matches!(self, ClassLikeMemberSelector::Variable(_))
94    }
95
96    #[inline]
97    #[must_use]
98    pub const fn is_expression(&self) -> bool {
99        matches!(self, ClassLikeMemberSelector::Expression(_))
100    }
101
102    #[inline]
103    #[must_use]
104    pub const fn is_missing(&self) -> bool {
105        matches!(self, ClassLikeMemberSelector::Missing(_))
106    }
107}
108
109impl ClassLikeConstantSelector<'_> {
110    #[inline]
111    #[must_use]
112    pub const fn is_identifier(&self) -> bool {
113        matches!(self, ClassLikeConstantSelector::Identifier(_))
114    }
115
116    #[inline]
117    #[must_use]
118    pub const fn is_expression(&self) -> bool {
119        matches!(self, ClassLikeConstantSelector::Expression(_))
120    }
121
122    #[inline]
123    #[must_use]
124    pub const fn is_missing(&self) -> bool {
125        matches!(self, ClassLikeConstantSelector::Missing(_))
126    }
127}
128
129impl<'arena> Sequence<'arena, ClassLikeMember<'arena>> {
130    #[must_use]
131    pub fn contains_trait_uses(&self) -> bool {
132        self.iter().any(|member| matches!(member, ClassLikeMember::TraitUse(_)))
133    }
134
135    #[must_use]
136    pub fn contains_constants(&self) -> bool {
137        self.iter().any(|member| matches!(member, ClassLikeMember::Constant(_)))
138    }
139
140    #[must_use]
141    pub fn contains_properties(&self) -> bool {
142        self.iter().any(|member| matches!(member, ClassLikeMember::Property(_)))
143    }
144
145    #[must_use]
146    pub fn contains_enum_cases(&self) -> bool {
147        self.iter().any(|member| matches!(member, ClassLikeMember::EnumCase(_)))
148    }
149
150    #[must_use]
151    pub fn contains_methods(&self) -> bool {
152        self.iter().any(|member| matches!(member, ClassLikeMember::Method(_)))
153    }
154}
155
156impl HasSpan for ClassLikeMember<'_> {
157    fn span(&self) -> Span {
158        match self {
159            ClassLikeMember::TraitUse(trait_use) => trait_use.span(),
160            ClassLikeMember::Constant(constant) => constant.span(),
161            ClassLikeMember::Property(property) => property.span(),
162            ClassLikeMember::EnumCase(enum_case) => enum_case.span(),
163            ClassLikeMember::Method(method) => method.span(),
164        }
165    }
166}
167
168impl HasSpan for ClassLikeMemberSelector<'_> {
169    fn span(&self) -> Span {
170        match self {
171            ClassLikeMemberSelector::Identifier(i) => i.span(),
172            ClassLikeMemberSelector::Variable(v) => v.span(),
173            ClassLikeMemberSelector::Expression(e) => e.span(),
174            ClassLikeMemberSelector::Missing(span) => *span,
175        }
176    }
177}
178
179impl HasSpan for ClassLikeConstantSelector<'_> {
180    fn span(&self) -> Span {
181        match self {
182            ClassLikeConstantSelector::Identifier(i) => i.span(),
183            ClassLikeConstantSelector::Expression(e) => e.span(),
184            ClassLikeConstantSelector::Missing(span) => *span,
185        }
186    }
187}
188
189impl HasSpan for ClassLikeMemberExpressionSelector<'_> {
190    fn span(&self) -> Span {
191        self.left_brace.join(self.right_brace)
192    }
193}