Skip to main content

mago_syntax/cst/cst/
construct.rs

1use strum::Display;
2
3use mago_span::HasSpan;
4use mago_span::Span;
5
6use crate::cst::cst::argument::ArgumentList;
7use crate::cst::cst::expression::Expression;
8use crate::cst::cst::keyword::Keyword;
9use crate::cst::sequence::TokenSeparatedSequence;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize))]
13#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
14pub enum Construct<'arena> {
15    Isset(IssetConstruct<'arena>),
16    Empty(EmptyConstruct<'arena>),
17    Eval(EvalConstruct<'arena>),
18    Include(IncludeConstruct<'arena>),
19    IncludeOnce(IncludeOnceConstruct<'arena>),
20    Require(RequireConstruct<'arena>),
21    RequireOnce(RequireOnceConstruct<'arena>),
22    Print(PrintConstruct<'arena>),
23    Exit(ExitConstruct<'arena>),
24    Die(DieConstruct<'arena>),
25}
26
27#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize))]
29pub struct IssetConstruct<'arena> {
30    pub isset: Keyword<'arena>,
31    pub left_parenthesis: Span,
32    pub values: TokenSeparatedSequence<'arena, &'arena Expression<'arena>>,
33    pub right_parenthesis: Span,
34}
35
36#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize))]
38pub struct EmptyConstruct<'arena> {
39    pub empty: Keyword<'arena>,
40    pub left_parenthesis: Span,
41    pub value: &'arena Expression<'arena>,
42    pub right_parenthesis: Span,
43}
44
45#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize))]
47pub struct EvalConstruct<'arena> {
48    pub eval: Keyword<'arena>,
49    pub left_parenthesis: Span,
50    pub value: &'arena Expression<'arena>,
51    pub right_parenthesis: Span,
52}
53
54#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize))]
56pub struct IncludeConstruct<'arena> {
57    pub include: Keyword<'arena>,
58    pub value: &'arena Expression<'arena>,
59}
60
61#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
62#[cfg_attr(feature = "serde", derive(serde::Serialize))]
63pub struct IncludeOnceConstruct<'arena> {
64    pub include_once: Keyword<'arena>,
65    pub value: &'arena Expression<'arena>,
66}
67
68#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
69#[cfg_attr(feature = "serde", derive(serde::Serialize))]
70pub struct RequireConstruct<'arena> {
71    pub require: Keyword<'arena>,
72    pub value: &'arena Expression<'arena>,
73}
74
75#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize))]
77pub struct RequireOnceConstruct<'arena> {
78    pub require_once: Keyword<'arena>,
79    pub value: &'arena Expression<'arena>,
80}
81
82#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
83#[cfg_attr(feature = "serde", derive(serde::Serialize))]
84pub struct PrintConstruct<'arena> {
85    pub print: Keyword<'arena>,
86    pub value: &'arena Expression<'arena>,
87}
88
89#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
90#[cfg_attr(feature = "serde", derive(serde::Serialize))]
91pub struct ExitConstruct<'arena> {
92    pub exit: Keyword<'arena>,
93    pub arguments: Option<ArgumentList<'arena>>,
94}
95
96#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
97#[cfg_attr(feature = "serde", derive(serde::Serialize))]
98pub struct DieConstruct<'arena> {
99    pub die: Keyword<'arena>,
100    pub arguments: Option<ArgumentList<'arena>>,
101}
102
103impl Construct<'_> {
104    #[must_use]
105    #[inline]
106    pub const fn is_import(&self) -> bool {
107        matches!(
108            self,
109            Construct::Include(_) | Construct::IncludeOnce(_) | Construct::Require(_) | Construct::RequireOnce(_)
110        )
111    }
112
113    #[must_use]
114    #[inline]
115    pub const fn has_bounds(&self) -> bool {
116        !matches!(
117            self,
118            Construct::Include(_)
119                | Construct::IncludeOnce(_)
120                | Construct::Require(_)
121                | Construct::RequireOnce(_)
122                | Construct::Print(_)
123        )
124    }
125}
126
127impl HasSpan for Construct<'_> {
128    fn span(&self) -> Span {
129        match self {
130            Construct::Isset(c) => c.span(),
131            Construct::Empty(c) => c.span(),
132            Construct::Eval(c) => c.span(),
133            Construct::Include(c) => c.span(),
134            Construct::IncludeOnce(c) => c.span(),
135            Construct::Require(c) => c.span(),
136            Construct::RequireOnce(c) => c.span(),
137            Construct::Print(c) => c.span(),
138            Construct::Exit(c) => c.span(),
139            Construct::Die(c) => c.span(),
140        }
141    }
142}
143
144impl HasSpan for IssetConstruct<'_> {
145    fn span(&self) -> Span {
146        self.isset.span().join(self.right_parenthesis.span())
147    }
148}
149
150impl HasSpan for EmptyConstruct<'_> {
151    fn span(&self) -> Span {
152        self.empty.span().join(self.right_parenthesis)
153    }
154}
155
156impl HasSpan for EvalConstruct<'_> {
157    fn span(&self) -> Span {
158        self.eval.span().join(self.right_parenthesis)
159    }
160}
161
162impl HasSpan for IncludeConstruct<'_> {
163    fn span(&self) -> Span {
164        self.include.span().join(self.value.span())
165    }
166}
167
168impl HasSpan for IncludeOnceConstruct<'_> {
169    fn span(&self) -> Span {
170        self.include_once.span().join(self.value.span())
171    }
172}
173
174impl HasSpan for RequireConstruct<'_> {
175    fn span(&self) -> Span {
176        self.require.span().join(self.value.span())
177    }
178}
179
180impl HasSpan for RequireOnceConstruct<'_> {
181    fn span(&self) -> Span {
182        self.require_once.span().join(self.value.span())
183    }
184}
185
186impl HasSpan for PrintConstruct<'_> {
187    fn span(&self) -> Span {
188        self.print.span().join(self.value.span())
189    }
190}
191
192impl HasSpan for ExitConstruct<'_> {
193    fn span(&self) -> Span {
194        if let Some(arguments) = &self.arguments { self.exit.span().join(arguments.span()) } else { self.exit.span() }
195    }
196}
197
198impl HasSpan for DieConstruct<'_> {
199    fn span(&self) -> Span {
200        if let Some(arguments) = &self.arguments { self.die.span().join(arguments.span()) } else { self.die.span() }
201    }
202}