php_parser_rs/parser/ast/
loops.rs

1use schemars::JsonSchema;
2use serde::Deserialize;
3use serde::Serialize;
4
5use crate::lexer::token::Span;
6use crate::node::Node;
7use crate::parser::ast::literals::LiteralInteger;
8use crate::parser::ast::utils::CommaSeparated;
9use crate::parser::ast::Ending;
10use crate::parser::ast::Expression;
11use crate::parser::ast::Statement;
12
13#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
14
15pub struct ForeachStatement {
16    pub foreach: Span,                      // `foreach`
17    pub left_parenthesis: Span,             // `(`
18    pub iterator: ForeachStatementIterator, // `( *expression* as & $var => $value )`
19    pub right_parenthesis: Span,            // `)`
20    pub body: ForeachStatementBody,         // `{ ... }`
21}
22
23impl Node for ForeachStatement {
24    fn children(&mut self) -> Vec<&mut dyn Node> {
25        vec![&mut self.iterator, &mut self.body]
26    }
27}
28
29#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
30#[serde(tag = "type", content = "value")]
31pub enum ForeachStatementIterator {
32    // `*expression* as &$var`
33    Value {
34        expression: Expression,  // `*expression*`
35        r#as: Span,              // `as`
36        ampersand: Option<Span>, // `&`
37        value: Expression,       // `$var`
38    },
39    // `*expression* as &$key => $value`
40    KeyAndValue {
41        expression: Expression,  // `*expression*`
42        r#as: Span,              // `as`
43        ampersand: Option<Span>, // `&`
44        key: Expression,         // `$key`
45        double_arrow: Span,      // `=>`
46        value: Expression,       // `$value`
47    },
48}
49
50impl Node for ForeachStatementIterator {
51    fn children(&mut self) -> Vec<&mut dyn Node> {
52        match self {
53            ForeachStatementIterator::Value {
54                expression, value, ..
55            } => {
56                vec![expression, value]
57            }
58            ForeachStatementIterator::KeyAndValue {
59                expression,
60                key,
61                value,
62                ..
63            } => vec![expression, key, value],
64        }
65    }
66}
67
68#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
69#[serde(tag = "type", content = "value")]
70pub enum ForeachStatementBody {
71    Statement {
72        statement: Box<Statement>,
73    },
74    Block {
75        colon: Span,                // `:`
76        statements: Vec<Statement>, // `*statements*`
77        endforeach: Span,           // `endforeach`
78        ending: Ending,             // `;` or `?>`
79    },
80}
81
82impl Node for ForeachStatementBody {
83    fn children(&mut self) -> Vec<&mut dyn Node> {
84        match self {
85            ForeachStatementBody::Statement { statement } => vec![statement.as_mut()],
86            ForeachStatementBody::Block { statements, .. } => {
87                statements.iter_mut().map(|s| s as &mut dyn Node).collect()
88            }
89        }
90    }
91}
92
93#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
94
95pub struct ForStatement {
96    pub r#for: Span,                    // `for`
97    pub left_parenthesis: Span,         // `(`
98    pub iterator: ForStatementIterator, // `*expression*; *expression*; *expression*`
99    pub right_parenthesis: Span,        // `)`
100    pub body: ForStatementBody,         // `{ ... }`
101}
102
103impl Node for ForStatement {
104    fn children(&mut self) -> Vec<&mut dyn Node> {
105        vec![&mut self.iterator, &mut self.body]
106    }
107}
108
109#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
110
111pub struct ForStatementIterator {
112    pub initializations: CommaSeparated<Expression>, // `*expression*;`
113    pub initializations_semicolon: Span,             // `;`
114    pub conditions: CommaSeparated<Expression>,      // `*expression*;`
115    pub conditions_semicolon: Span,                  // `;`
116    pub r#loop: CommaSeparated<Expression>,          // `*expression*`
117}
118
119impl Node for ForStatementIterator {
120    fn children(&mut self) -> Vec<&mut dyn Node> {
121        let mut children = vec![];
122        children.extend(
123            self.initializations
124                .inner
125                .iter_mut()
126                .map(|x| x as &mut dyn Node),
127        );
128        children.extend(self.conditions.inner.iter_mut().map(|x| x as &mut dyn Node));
129        children.extend(self.r#loop.inner.iter_mut().map(|x| x as &mut dyn Node));
130        children
131    }
132}
133
134#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
135#[serde(tag = "type", content = "value")]
136pub enum ForStatementBody {
137    Statement {
138        statement: Box<Statement>,
139    },
140    Block {
141        colon: Span,                // `:`
142        statements: Vec<Statement>, // `*statements*`
143        endfor: Span,               // `endfor`
144        ending: Ending,             // `;` or `?>`
145    },
146}
147
148impl Node for ForStatementBody {
149    fn children(&mut self) -> Vec<&mut dyn Node> {
150        match self {
151            ForStatementBody::Statement { statement } => vec![statement.as_mut()],
152            ForStatementBody::Block { statements, .. } => {
153                statements.iter_mut().map(|x| x as &mut dyn Node).collect()
154            }
155        }
156    }
157}
158
159#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
160
161pub struct DoWhileStatement {
162    pub r#do: Span,              // `do`
163    pub body: Box<Statement>,    // `{ ... }`
164    pub r#while: Span,           // `while`
165    pub left_parenthesis: Span,  // `(`
166    pub condition: Expression,   // `( *expression* )`
167    pub right_parenthesis: Span, // `)`
168    pub semicolon: Span,         // `;`
169}
170
171impl Node for DoWhileStatement {
172    fn children(&mut self) -> Vec<&mut dyn Node> {
173        vec![self.body.as_mut(), &mut self.condition]
174    }
175}
176
177#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
178
179pub struct WhileStatement {
180    pub r#while: Span,            // `while`
181    pub left_parenthesis: Span,   // `(`
182    pub condition: Expression,    // *expression*
183    pub right_parenthesis: Span,  // `)`
184    pub body: WhileStatementBody, // `{ ... }`
185}
186
187impl Node for WhileStatement {
188    fn children(&mut self) -> Vec<&mut dyn Node> {
189        vec![&mut self.condition, &mut self.body]
190    }
191}
192
193#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
194#[serde(tag = "type", content = "value")]
195pub enum WhileStatementBody {
196    Statement {
197        statement: Box<Statement>,
198    },
199    Block {
200        colon: Span,                // `:`
201        statements: Vec<Statement>, // `*statements*`
202        endwhile: Span,             // `endwhile`
203        ending: Ending,             // `;` or `?>`
204    },
205}
206
207impl Node for WhileStatementBody {
208    fn children(&mut self) -> Vec<&mut dyn Node> {
209        match self {
210            WhileStatementBody::Statement { statement } => vec![statement.as_mut()],
211            WhileStatementBody::Block { statements, .. } => {
212                statements.iter_mut().map(|s| s as &mut dyn Node).collect()
213            }
214        }
215    }
216}
217
218#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
219#[serde(tag = "type", content = "value")]
220pub enum Level {
221    Literal(LiteralInteger),
222    Parenthesized {
223        left_parenthesis: Span, // `(`
224        level: Box<Level>,
225        right_parenthesis: Span, // `)`
226    },
227}
228
229impl Node for Level {
230    fn children(&mut self) -> Vec<&mut dyn Node> {
231        match self {
232            Level::Literal(literal) => vec![literal],
233            Level::Parenthesized { level, .. } => level.children(),
234        }
235    }
236}
237
238#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
239
240pub struct BreakStatement {
241    pub r#break: Span,        // `break`
242    pub level: Option<Level>, // `3`
243    pub ending: Ending,       // `;` or `?>`
244}
245
246impl Node for BreakStatement {
247    fn children(&mut self) -> Vec<&mut dyn Node> {
248        match &mut self.level {
249            Some(level) => vec![level],
250            None => vec![],
251        }
252    }
253}
254
255#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
256
257pub struct ContinueStatement {
258    pub r#continue: Span,     // `continue`
259    pub level: Option<Level>, // `2`
260    pub ending: Ending,       // `;` or `?>`
261}
262
263impl Node for ContinueStatement {
264    fn children(&mut self) -> Vec<&mut dyn Node> {
265        match &mut self.level {
266            Some(level) => vec![level],
267            None => vec![],
268        }
269    }
270}