mago_syntax/cst/cst/loop/
for.rs1use strum::Display;
2
3use mago_span::HasSpan;
4use mago_span::Span;
5
6use crate::cst::cst::expression::Expression;
7use crate::cst::cst::keyword::Keyword;
8use crate::cst::cst::statement::Statement;
9use crate::cst::cst::terminator::Terminator;
10use crate::cst::sequence::Sequence;
11use crate::cst::sequence::TokenSeparatedSequence;
12
13#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize))]
26pub struct For<'arena> {
27 pub r#for: Keyword<'arena>,
28 pub left_parenthesis: Span,
29 pub initializations: TokenSeparatedSequence<'arena, &'arena Expression<'arena>>,
30 pub initializations_semicolon: Span,
31 pub conditions: TokenSeparatedSequence<'arena, &'arena Expression<'arena>>,
32 pub conditions_semicolon: Span,
33 pub increments: TokenSeparatedSequence<'arena, &'arena Expression<'arena>>,
34 pub right_parenthesis: Span,
35 pub body: ForBody<'arena>,
36}
37
38#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize))]
41#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
42pub enum ForBody<'arena> {
43 Statement(&'arena Statement<'arena>),
44 ColonDelimited(ForColonDelimitedBody<'arena>),
45}
46
47#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize))]
60pub struct ForColonDelimitedBody<'arena> {
61 pub colon: Span,
62 pub statements: Sequence<'arena, Statement<'arena>>,
63 pub end_for: Keyword<'arena>,
64 pub terminator: Terminator<'arena>,
65}
66
67impl<'arena> ForBody<'arena> {
68 #[inline]
69 #[must_use]
70 pub fn statements(&self) -> &[Statement<'arena>] {
71 match self {
72 ForBody::Statement(statement) => std::slice::from_ref(statement),
73 ForBody::ColonDelimited(body) => body.statements.as_slice(),
74 }
75 }
76}
77
78impl HasSpan for For<'_> {
79 fn span(&self) -> Span {
80 self.r#for.span().join(self.body.span())
81 }
82}
83
84impl HasSpan for ForBody<'_> {
85 fn span(&self) -> Span {
86 match self {
87 ForBody::Statement(statement) => statement.span(),
88 ForBody::ColonDelimited(body) => body.span(),
89 }
90 }
91}
92
93impl HasSpan for ForColonDelimitedBody<'_> {
94 fn span(&self) -> Span {
95 self.colon.join(self.terminator.span())
96 }
97}