1use bincode::Decode;
2use bincode::Encode;
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::Serialize;
6
7use crate::tree::comment::CommentGroup;
8use crate::tree::expression::literal::LiteralInteger;
9use crate::tree::expression::Expression;
10use crate::tree::statement::block::BlockStatement;
11use crate::tree::token::Keyword;
12use crate::tree::utils::CommaSeparated;
13use crate::tree::variable::Variable;
14use crate::tree::Node;
15
16#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
17#[serde(rename_all = "snake_case")]
18pub struct ForeachStatement {
19 pub comments: CommentGroup,
20 pub foreach: Keyword,
21 pub iterator: ForeachIteratorStatement,
22 pub block: BlockStatement,
23 pub r#else: Option<Keyword>,
24 pub else_block: Option<BlockStatement>,
25}
26
27#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
28#[serde(rename_all = "snake_case")]
29pub enum ForeachIteratorStatement {
30 Value {
31 expression: Expression,
32 r#as: Keyword,
33 value: Variable,
34 },
35 ParenthesizedValue {
36 left_parenthesis: usize,
37 expression: Expression,
38 r#as: Keyword,
39 value: Variable,
40 right_parenthesis: usize,
41 },
42 KeyAndValue {
43 expression: Expression,
44 r#as: Keyword,
45 key: Variable,
46 double_arrow: usize,
47 value: Variable,
48 },
49 ParenthesizedKeyAndValue {
50 left_parenthesis: usize,
51 expression: Expression,
52 r#as: Keyword,
53 key: Variable,
54 double_arrow: usize,
55 value: Variable,
56 right_parenthesis: usize,
57 },
58}
59
60#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
61#[serde(rename_all = "snake_case")]
62pub struct ForStatement {
63 pub comments: CommentGroup,
64 pub r#for: Keyword,
65 pub iterator: ForIteratorStatement,
66 pub block: BlockStatement,
67}
68
69#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
70#[serde(rename_all = "snake_case")]
71pub enum ForIteratorStatement {
72 Standalone {
73 initializations: CommaSeparated<Expression>,
74 initializations_semicolon: usize,
75 conditions: CommaSeparated<Expression>,
76 conditions_semicolon: usize,
77 r#loop: CommaSeparated<Expression>,
78 },
79 Parenthesized {
80 left_parenthesis: usize,
81 initializations: CommaSeparated<Expression>,
82 initializations_semicolon: usize,
83 conditions: CommaSeparated<Expression>,
84 conditions_semicolon: usize,
85 r#loop: CommaSeparated<Expression>,
86 right_parenthesis: usize,
87 },
88}
89
90#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
91#[serde(rename_all = "snake_case")]
92pub struct DoWhileStatement {
93 pub comments: CommentGroup,
94 pub r#do: Keyword,
95 pub block: BlockStatement,
96 pub r#while: Keyword,
97 pub conditions: CommaSeparated<Expression>,
98 pub semicolon: usize,
99}
100
101#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
102#[serde(rename_all = "snake_case")]
103pub struct WhileStatement {
104 pub comments: CommentGroup,
105 pub r#while: Keyword,
106 pub conditions: CommaSeparated<Expression>,
107 pub block: BlockStatement,
108}
109
110#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
111#[serde(rename_all = "snake_case")]
112pub struct BreakStatement {
113 pub comments: CommentGroup,
114 pub r#break: Keyword,
115 pub level: Option<LiteralInteger>,
116 pub semicolon: usize,
117}
118
119#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
120#[serde(rename_all = "snake_case")]
121pub struct ContinueStatement {
122 pub comments: CommentGroup,
123 pub r#continue: Keyword,
124 pub level: Option<LiteralInteger>,
125 pub semicolon: usize,
126}
127
128impl ForeachIteratorStatement {
129 pub fn expression(&self) -> &Expression {
130 match &self {
131 Self::Value { expression, .. } => expression,
132 Self::ParenthesizedValue { expression, .. } => expression,
133 Self::KeyAndValue { expression, .. } => expression,
134 Self::ParenthesizedKeyAndValue { expression, .. } => expression,
135 }
136 }
137
138 pub fn key(&self) -> Option<&Variable> {
139 match &self {
140 Self::Value { .. } => None,
141 Self::ParenthesizedValue { .. } => None,
142 Self::KeyAndValue { key, .. } => Some(key),
143 Self::ParenthesizedKeyAndValue { key, .. } => Some(key),
144 }
145 }
146
147 pub fn value(&self) -> &Variable {
148 match &self {
149 Self::Value { value, .. } => value,
150 Self::ParenthesizedValue { value, .. } => value,
151 Self::KeyAndValue { value, .. } => value,
152 Self::ParenthesizedKeyAndValue { value, .. } => value,
153 }
154 }
155}
156
157impl Node for ForeachStatement {
158 fn comments(&self) -> Option<&CommentGroup> {
159 Some(&self.comments)
160 }
161
162 fn initial_position(&self) -> usize {
163 self.foreach.initial_position()
164 }
165
166 fn final_position(&self) -> usize {
167 self.block.final_position()
168 }
169
170 fn children(&self) -> Vec<&dyn Node> {
171 let mut children: Vec<&dyn Node> = vec![&self.foreach, &self.iterator, &self.block];
172
173 if let Some(r#else) = &self.r#else {
174 children.push(r#else);
175 }
176
177 if let Some(else_block) = &self.else_block {
178 children.push(else_block);
179 }
180
181 children
182 }
183
184 fn get_description(&self) -> String {
185 "foreach statement".to_string()
186 }
187}
188
189impl Node for ForeachIteratorStatement {
190 fn comments(&self) -> Option<&CommentGroup> {
191 None
192 }
193
194 fn initial_position(&self) -> usize {
195 match &self {
196 Self::Value { expression, .. } | Self::KeyAndValue { expression, .. } => {
197 expression.initial_position()
198 }
199 Self::ParenthesizedValue {
200 left_parenthesis, ..
201 }
202 | Self::ParenthesizedKeyAndValue {
203 left_parenthesis, ..
204 } => *left_parenthesis,
205 }
206 }
207
208 fn final_position(&self) -> usize {
209 match &self {
210 Self::Value { value, .. } | Self::KeyAndValue { value, .. } => value.final_position(),
211 Self::ParenthesizedValue {
212 right_parenthesis, ..
213 }
214 | Self::ParenthesizedKeyAndValue {
215 right_parenthesis, ..
216 } => right_parenthesis + 1,
217 }
218 }
219
220 fn children(&self) -> Vec<&dyn Node> {
221 match &self {
222 Self::Value {
223 expression,
224 r#as,
225 value,
226 ..
227 }
228 | Self::ParenthesizedValue {
229 expression,
230 r#as,
231 value,
232 ..
233 } => {
234 vec![expression, r#as, value]
235 }
236 Self::KeyAndValue {
237 expression,
238 r#as,
239 key,
240 value,
241 ..
242 }
243 | Self::ParenthesizedKeyAndValue {
244 expression,
245 r#as,
246 key,
247 value,
248 ..
249 } => {
250 vec![expression, r#as, key, value]
251 }
252 }
253 }
254
255 fn get_description(&self) -> String {
256 "foreach iterator".to_string()
257 }
258}
259
260impl Node for ForStatement {
261 fn comments(&self) -> Option<&CommentGroup> {
262 Some(&self.comments)
263 }
264
265 fn initial_position(&self) -> usize {
266 self.r#for.initial_position()
267 }
268
269 fn final_position(&self) -> usize {
270 self.block.final_position()
271 }
272
273 fn children(&self) -> Vec<&dyn Node> {
274 vec![&self.r#for, &self.iterator, &self.block]
275 }
276
277 fn get_description(&self) -> String {
278 "for statement".to_string()
279 }
280}
281
282impl Node for ForIteratorStatement {
283 fn comments(&self) -> Option<&CommentGroup> {
284 None
285 }
286
287 fn initial_position(&self) -> usize {
288 match &self {
289 Self::Standalone {
290 initializations,
291 initializations_semicolon,
292 ..
293 } => {
294 if let Some(expression) = initializations.inner.first() {
295 expression.initial_position()
296 } else {
297 *initializations_semicolon
298 }
299 }
300 Self::Parenthesized {
301 left_parenthesis, ..
302 } => *left_parenthesis,
303 }
304 }
305
306 fn final_position(&self) -> usize {
307 match &self {
308 Self::Standalone {
309 conditions_semicolon,
310 r#loop,
311 ..
312 } => {
313 if let Some(expression) = r#loop.inner.last() {
314 expression.final_position()
315 } else {
316 conditions_semicolon + 1
317 }
318 }
319 Self::Parenthesized {
320 right_parenthesis, ..
321 } => right_parenthesis + 1,
322 }
323 }
324
325 fn children(&self) -> Vec<&dyn Node> {
326 match &self {
327 Self::Standalone {
328 initializations,
329 conditions,
330 r#loop,
331 ..
332 }
333 | Self::Parenthesized {
334 initializations,
335 conditions,
336 r#loop,
337 ..
338 } => {
339 let mut children: Vec<&dyn Node> = vec![];
340
341 for expression in &initializations.inner {
342 children.push(expression);
343 }
344
345 for expression in &conditions.inner {
346 children.push(expression);
347 }
348
349 for expression in &r#loop.inner {
350 children.push(expression);
351 }
352
353 children
354 }
355 }
356 }
357
358 fn get_description(&self) -> String {
359 "for iterator statement".to_string()
360 }
361}
362
363impl Node for DoWhileStatement {
364 fn comments(&self) -> Option<&CommentGroup> {
365 Some(&self.comments)
366 }
367
368 fn initial_position(&self) -> usize {
369 self.r#do.initial_position()
370 }
371
372 fn final_position(&self) -> usize {
373 self.semicolon + 1
374 }
375
376 fn children(&self) -> Vec<&dyn Node> {
377 let mut children: Vec<&dyn Node> = vec![&self.r#do, &self.block, &self.r#while];
378
379 for condition in &self.conditions.inner {
380 children.push(condition);
381 }
382
383 children
384 }
385
386 fn get_description(&self) -> String {
387 "do-while statement".to_string()
388 }
389}
390
391impl Node for WhileStatement {
392 fn comments(&self) -> Option<&CommentGroup> {
393 Some(&self.comments)
394 }
395
396 fn initial_position(&self) -> usize {
397 self.r#while.initial_position()
398 }
399
400 fn final_position(&self) -> usize {
401 self.block.final_position()
402 }
403
404 fn children(&self) -> Vec<&dyn Node> {
405 let mut children: Vec<&dyn Node> = vec![&self.r#while, &self.block];
406
407 for condition in &self.conditions.inner {
408 children.push(condition);
409 }
410
411 children
412 }
413
414 fn get_description(&self) -> String {
415 "while statement".to_string()
416 }
417}
418
419impl Node for BreakStatement {
420 fn comments(&self) -> Option<&CommentGroup> {
421 Some(&self.comments)
422 }
423
424 fn initial_position(&self) -> usize {
425 self.r#break.initial_position()
426 }
427
428 fn final_position(&self) -> usize {
429 self.semicolon + 1
430 }
431
432 fn children(&self) -> Vec<&dyn Node> {
433 if let Some(level) = &self.level {
434 vec![&self.r#break, level]
435 } else {
436 vec![&self.r#break]
437 }
438 }
439
440 fn get_description(&self) -> String {
441 "break statement".to_string()
442 }
443}
444
445impl Node for ContinueStatement {
446 fn comments(&self) -> Option<&CommentGroup> {
447 Some(&self.comments)
448 }
449
450 fn initial_position(&self) -> usize {
451 self.r#continue.initial_position()
452 }
453
454 fn final_position(&self) -> usize {
455 self.semicolon + 1
456 }
457
458 fn children(&self) -> Vec<&dyn Node> {
459 if let Some(level) = &self.level {
460 vec![&self.r#continue, level]
461 } else {
462 vec![&self.r#continue]
463 }
464 }
465
466 fn get_description(&self) -> String {
467 "continue statement".to_string()
468 }
469}