Skip to main content

wdl_ast/v1/
expr.rs

1//! V1 AST representation for expressions.
2
3use rowan::NodeOrToken;
4use wdl_grammar::lexer::v1::EscapeToken;
5use wdl_grammar::lexer::v1::Logos;
6
7use super::Minus;
8use crate::AstNode;
9use crate::AstToken;
10use crate::Ident;
11use crate::SyntaxKind;
12use crate::SyntaxNode;
13use crate::SyntaxToken;
14use crate::TreeNode;
15use crate::TreeToken;
16
17/// Represents an expression.
18#[derive(Clone, Debug, PartialEq, Eq)]
19pub enum Expr<N: TreeNode = SyntaxNode> {
20    /// The expression is a literal.
21    Literal(LiteralExpr<N>),
22    /// The expression is a name reference.
23    NameRef(NameRefExpr<N>),
24    /// The expression is a parenthesized expression.
25    Parenthesized(ParenthesizedExpr<N>),
26    /// The expression is an `if` expression.
27    If(IfExpr<N>),
28    /// The expression is a "logical not" expression.
29    LogicalNot(LogicalNotExpr<N>),
30    /// The expression is a negation expression.
31    Negation(NegationExpr<N>),
32    /// The expression is a "logical or" expression.
33    LogicalOr(LogicalOrExpr<N>),
34    /// The expression is a "logical and" expression.
35    LogicalAnd(LogicalAndExpr<N>),
36    /// The expression is an equality expression.
37    Equality(EqualityExpr<N>),
38    /// The expression is an inequality expression.
39    Inequality(InequalityExpr<N>),
40    /// The expression is a "less than" expression.
41    Less(LessExpr<N>),
42    /// The expression is a "less than or equal to" expression.
43    LessEqual(LessEqualExpr<N>),
44    /// The expression is a "greater" expression.
45    Greater(GreaterExpr<N>),
46    /// The expression is a "greater than or equal to" expression.
47    GreaterEqual(GreaterEqualExpr<N>),
48    /// The expression is an addition expression.
49    Addition(AdditionExpr<N>),
50    /// The expression is a subtraction expression.
51    Subtraction(SubtractionExpr<N>),
52    /// The expression is a multiplication expression.
53    Multiplication(MultiplicationExpr<N>),
54    /// The expression is a division expression.
55    Division(DivisionExpr<N>),
56    /// The expression is a modulo expression.
57    Modulo(ModuloExpr<N>),
58    /// The expression is an exponentiation expression.
59    Exponentiation(ExponentiationExpr<N>),
60    /// The expression is a call expression.
61    Call(CallExpr<N>),
62    /// The expression is an index expression.
63    Index(IndexExpr<N>),
64    /// The expression is a member access expression.
65    Access(AccessExpr<N>),
66}
67
68impl<N: TreeNode> Expr<N> {
69    /// Attempts to get a reference to the inner [`LiteralExpr`].
70    ///
71    /// * If `self` is a [`Expr::Literal`], then a reference to the inner
72    ///   [`LiteralExpr`] is returned wrapped in [`Some`].
73    /// * Else, [`None`] is returned.
74    pub fn as_literal(&self) -> Option<&LiteralExpr<N>> {
75        match self {
76            Self::Literal(e) => Some(e),
77            _ => None,
78        }
79    }
80
81    /// Consumes `self` and attempts to return the inner [`LiteralExpr`].
82    ///
83    /// * If `self` is a [`Expr::Literal`], then the inner [`LiteralExpr`] is
84    ///   returned wrapped in [`Some`].
85    /// * Else, [`None`] is returned.
86    pub fn into_literal(self) -> Option<LiteralExpr<N>> {
87        match self {
88            Self::Literal(e) => Some(e),
89            _ => None,
90        }
91    }
92
93    /// Unwraps the expression into a literal expression.
94    ///
95    /// # Panics
96    ///
97    /// Panics if the expression is not a literal expression.
98    pub fn unwrap_literal(self) -> LiteralExpr<N> {
99        match self {
100            Self::Literal(e) => e,
101            _ => panic!("not a literal expression"),
102        }
103    }
104
105    /// Attempts to get a reference to the inner [`NameRefExpr`].
106    ///
107    /// * If `self` is a [`Expr::NameRef`], then a reference to the inner
108    ///   [`NameRefExpr`] is returned wrapped in [`Some`].
109    /// * Else, [`None`] is returned.
110    pub fn as_name_ref(&self) -> Option<&NameRefExpr<N>> {
111        match self {
112            Self::NameRef(e) => Some(e),
113            _ => None,
114        }
115    }
116
117    /// Consumes `self` and attempts to return the inner [`NameRefExpr`].
118    ///
119    /// * If `self` is a [`Expr::NameRef`], then the inner [`NameRefExpr`] is
120    ///   returned wrapped in [`Some`].
121    /// * Else, [`None`] is returned.
122    pub fn into_name_ref(self) -> Option<NameRefExpr<N>> {
123        match self {
124            Self::NameRef(e) => Some(e),
125            _ => None,
126        }
127    }
128
129    /// Unwraps the expression into a name reference.
130    ///
131    /// # Panics
132    ///
133    /// Panics if the expression is not a name reference.
134    pub fn unwrap_name_ref(self) -> NameRefExpr<N> {
135        match self {
136            Self::NameRef(e) => e,
137            _ => panic!("not a name reference"),
138        }
139    }
140
141    /// Attempts to get a reference to the inner [`ParenthesizedExpr`].
142    ///
143    /// * If `self` is a [`Expr::Parenthesized`], then a reference to the inner
144    ///   [`ParenthesizedExpr`] is returned wrapped in [`Some`].
145    /// * Else, [`None`] is returned.
146    pub fn as_parenthesized(&self) -> Option<&ParenthesizedExpr<N>> {
147        match self {
148            Self::Parenthesized(e) => Some(e),
149            _ => None,
150        }
151    }
152
153    /// Consumes `self` and attempts to return the inner [`ParenthesizedExpr`].
154    ///
155    /// * If `self` is a [`Expr::Parenthesized`], then the inner
156    ///   [`ParenthesizedExpr`] is returned wrapped in [`Some`].
157    /// * Else, [`None`] is returned.
158    pub fn into_parenthesized(self) -> Option<ParenthesizedExpr<N>> {
159        match self {
160            Self::Parenthesized(e) => Some(e),
161            _ => None,
162        }
163    }
164
165    /// Unwraps the expression into a parenthesized expression.
166    ///
167    /// # Panics
168    ///
169    /// Panics if the expression is not a parenthesized expression.
170    pub fn unwrap_parenthesized(self) -> ParenthesizedExpr<N> {
171        match self {
172            Self::Parenthesized(e) => e,
173            _ => panic!("not a parenthesized expression"),
174        }
175    }
176
177    /// Attempts to get a reference to the inner [`IfExpr`].
178    ///
179    /// * If `self` is a [`Expr::If`], then a reference to the inner [`IfExpr`]
180    ///   is returned wrapped in [`Some`].
181    /// * Else, [`None`] is returned.
182    pub fn as_if(&self) -> Option<&IfExpr<N>> {
183        match self {
184            Self::If(e) => Some(e),
185            _ => None,
186        }
187    }
188
189    /// Consumes `self` and attempts to return the inner [`IfExpr`].
190    ///
191    /// * If `self` is a [`Expr::If`], then the inner [`IfExpr`] is returned
192    ///   wrapped in [`Some`].
193    /// * Else, [`None`] is returned.
194    pub fn into_if(self) -> Option<IfExpr<N>> {
195        match self {
196            Self::If(e) => Some(e),
197            _ => None,
198        }
199    }
200
201    /// Unwraps the expression into an `if` expression.
202    ///
203    /// # Panics
204    ///
205    /// Panics if the expression is not an `if` expression.
206    pub fn unwrap_if(self) -> IfExpr<N> {
207        match self {
208            Self::If(e) => e,
209            _ => panic!("not an `if` expression"),
210        }
211    }
212
213    /// Attempts to get a reference to the inner [`LogicalNotExpr`].
214    ///
215    /// * If `self` is a [`Expr::LogicalNot`], then a reference to the inner
216    ///   [`LogicalNotExpr`] is returned wrapped in [`Some`].
217    /// * Else, [`None`] is returned.
218    pub fn as_logical_not(&self) -> Option<&LogicalNotExpr<N>> {
219        match self {
220            Self::LogicalNot(e) => Some(e),
221            _ => None,
222        }
223    }
224
225    /// Consumes `self` and attempts to return the inner [`LogicalNotExpr`].
226    ///
227    /// * If `self` is a [`Expr::LogicalNot`], then the inner [`LogicalNotExpr`]
228    ///   is returned wrapped in [`Some`].
229    /// * Else, [`None`] is returned.
230    pub fn into_logical_not(self) -> Option<LogicalNotExpr<N>> {
231        match self {
232            Self::LogicalNot(e) => Some(e),
233            _ => None,
234        }
235    }
236
237    /// Unwraps the expression into a logical `not` expression.
238    ///
239    /// # Panics
240    ///
241    /// Panics if the expression is not a logical `not` expression.
242    pub fn unwrap_logical_not(self) -> LogicalNotExpr<N> {
243        match self {
244            Self::LogicalNot(e) => e,
245            _ => panic!("not a logical `not` expression"),
246        }
247    }
248
249    /// Attempts to get a reference to the inner [`NegationExpr`].
250    ///
251    /// * If `self` is a [`Expr::Negation`], then a reference to the inner
252    ///   [`NegationExpr`] is returned wrapped in [`Some`].
253    /// * Else, [`None`] is returned.
254    pub fn as_negation(&self) -> Option<&NegationExpr<N>> {
255        match self {
256            Self::Negation(e) => Some(e),
257            _ => None,
258        }
259    }
260
261    /// Consumes `self` and attempts to return the inner [`NegationExpr`].
262    ///
263    /// * If `self` is a [`Expr::Negation`], then the inner [`NegationExpr`] is
264    ///   returned wrapped in [`Some`].
265    /// * Else, [`None`] is returned.
266    pub fn into_negation(self) -> Option<NegationExpr<N>> {
267        match self {
268            Self::Negation(e) => Some(e),
269            _ => None,
270        }
271    }
272
273    /// Unwraps the expression into a negation expression.
274    ///
275    /// # Panics
276    ///
277    /// Panics if the expression is not a negation expression.
278    pub fn unwrap_negation(self) -> NegationExpr<N> {
279        match self {
280            Self::Negation(e) => e,
281            _ => panic!("not a negation expression"),
282        }
283    }
284
285    /// Attempts to get a reference to the inner [`LogicalOrExpr`].
286    ///
287    /// * If `self` is a [`Expr::LogicalOr`], then a reference to the inner
288    ///   [`LogicalOrExpr`] is returned wrapped in [`Some`].
289    /// * Else, [`None`] is returned.
290    pub fn as_logical_or(&self) -> Option<&LogicalOrExpr<N>> {
291        match self {
292            Self::LogicalOr(e) => Some(e),
293            _ => None,
294        }
295    }
296
297    /// Consumes `self` and attempts to return the inner [`LogicalOrExpr`].
298    ///
299    /// * If `self` is a [`Expr::LogicalOr`], then the inner [`LogicalOrExpr`]
300    ///   is returned wrapped in [`Some`].
301    /// * Else, [`None`] is returned.
302    pub fn into_logical_or(self) -> Option<LogicalOrExpr<N>> {
303        match self {
304            Self::LogicalOr(e) => Some(e),
305            _ => None,
306        }
307    }
308
309    /// Unwraps the expression into a logical `or` expression.
310    ///
311    /// # Panics
312    ///
313    /// Panics if the expression is not a logical `or` expression.
314    pub fn unwrap_logical_or(self) -> LogicalOrExpr<N> {
315        match self {
316            Self::LogicalOr(e) => e,
317            _ => panic!("not a logical `or` expression"),
318        }
319    }
320
321    /// Attempts to get a reference to the inner [`LogicalAndExpr`].
322    ///
323    /// * If `self` is a [`Expr::LogicalAnd`], then a reference to the inner
324    ///   [`LogicalAndExpr`] is returned wrapped in [`Some`].
325    /// * Else, [`None`] is returned.
326    pub fn as_logical_and(&self) -> Option<&LogicalAndExpr<N>> {
327        match self {
328            Self::LogicalAnd(e) => Some(e),
329            _ => None,
330        }
331    }
332
333    /// Consumes `self` and attempts to return the inner [`LogicalAndExpr`].
334    ///
335    /// * If `self` is a [`Expr::LogicalAnd`], then the inner [`LogicalAndExpr`]
336    ///   is returned wrapped in [`Some`].
337    /// * Else, [`None`] is returned.
338    pub fn into_logical_and(self) -> Option<LogicalAndExpr<N>> {
339        match self {
340            Self::LogicalAnd(e) => Some(e),
341            _ => None,
342        }
343    }
344
345    /// Unwraps the expression into a logical `and` expression.
346    ///
347    /// # Panics
348    ///
349    /// Panics if the expression is not a logical `and` expression.
350    pub fn unwrap_logical_and(self) -> LogicalAndExpr<N> {
351        match self {
352            Self::LogicalAnd(e) => e,
353            _ => panic!("not a logical `and` expression"),
354        }
355    }
356
357    /// Attempts to get a reference to the inner [`EqualityExpr`].
358    ///
359    /// * If `self` is a [`Expr::Equality`], then a reference to the inner
360    ///   [`EqualityExpr`] is returned wrapped in [`Some`].
361    /// * Else, [`None`] is returned.
362    pub fn as_equality(&self) -> Option<&EqualityExpr<N>> {
363        match self {
364            Self::Equality(e) => Some(e),
365            _ => None,
366        }
367    }
368
369    /// Consumes `self` and attempts to return the inner [`EqualityExpr`].
370    ///
371    /// * If `self` is a [`Expr::Equality`], then the inner [`EqualityExpr`] is
372    ///   returned wrapped in [`Some`].
373    /// * Else, [`None`] is returned.
374    pub fn into_equality(self) -> Option<EqualityExpr<N>> {
375        match self {
376            Self::Equality(e) => Some(e),
377            _ => None,
378        }
379    }
380
381    /// Unwraps the expression into an equality expression.
382    ///
383    /// # Panics
384    ///
385    /// Panics if the expression is not an equality expression.
386    pub fn unwrap_equality(self) -> EqualityExpr<N> {
387        match self {
388            Self::Equality(e) => e,
389            _ => panic!("not an equality expression"),
390        }
391    }
392
393    /// Attempts to get a reference to the inner [`InequalityExpr`].
394    ///
395    /// * If `self` is a [`Expr::Inequality`], then a reference to the inner
396    ///   [`InequalityExpr`] is returned wrapped in [`Some`].
397    /// * Else, [`None`] is returned.
398    pub fn as_inequality(&self) -> Option<&InequalityExpr<N>> {
399        match self {
400            Self::Inequality(e) => Some(e),
401            _ => None,
402        }
403    }
404
405    /// Consumes `self` and attempts to return the inner [`InequalityExpr`].
406    ///
407    /// * If `self` is a [`Expr::Inequality`], then the inner [`InequalityExpr`]
408    ///   is returned wrapped in [`Some`].
409    /// * Else, [`None`] is returned.
410    pub fn into_inequality(self) -> Option<InequalityExpr<N>> {
411        match self {
412            Self::Inequality(e) => Some(e),
413            _ => None,
414        }
415    }
416
417    /// Unwraps the expression into an inequality expression.
418    ///
419    /// # Panics
420    ///
421    /// Panics if the expression is not an inequality expression.
422    pub fn unwrap_inequality(self) -> InequalityExpr<N> {
423        match self {
424            Self::Inequality(e) => e,
425            _ => panic!("not an inequality expression"),
426        }
427    }
428
429    /// Attempts to get a reference to the inner [`LessExpr`].
430    ///
431    /// * If `self` is a [`Expr::Less`], then a reference to the inner
432    ///   [`LessExpr`] is returned wrapped in [`Some`].
433    /// * Else, [`None`] is returned.
434    pub fn as_less(&self) -> Option<&LessExpr<N>> {
435        match self {
436            Self::Less(e) => Some(e),
437            _ => None,
438        }
439    }
440
441    /// Consumes `self` and attempts to return the inner [`LessExpr`].
442    ///
443    /// * If `self` is a [`Expr::Less`], then the inner [`LessExpr`] is returned
444    ///   wrapped in [`Some`].
445    /// * Else, [`None`] is returned.
446    pub fn into_less(self) -> Option<LessExpr<N>> {
447        match self {
448            Self::Less(e) => Some(e),
449            _ => None,
450        }
451    }
452
453    /// Unwraps the expression into a "less than" expression.
454    ///
455    /// # Panics
456    ///
457    /// Panics if the expression is not a "less than" expression.
458    pub fn unwrap_less(self) -> LessExpr<N> {
459        match self {
460            Self::Less(e) => e,
461            _ => panic!("not a \"less than\" expression"),
462        }
463    }
464
465    /// Attempts to get a reference to the inner [`LessEqualExpr`].
466    ///
467    /// * If `self` is a [`Expr::LessEqual`], then a reference to the inner
468    ///   [`LessEqualExpr`] is returned wrapped in [`Some`].
469    /// * Else, [`None`] is returned.
470    pub fn as_less_equal(&self) -> Option<&LessEqualExpr<N>> {
471        match self {
472            Self::LessEqual(e) => Some(e),
473            _ => None,
474        }
475    }
476
477    /// Consumes `self` and attempts to return the inner [`LessEqualExpr`].
478    ///
479    /// * If `self` is a [`Expr::LessEqual`], then the inner [`LessEqualExpr`]
480    ///   is returned wrapped in [`Some`].
481    /// * Else, [`None`] is returned.
482    pub fn into_less_equal(self) -> Option<LessEqualExpr<N>> {
483        match self {
484            Self::LessEqual(e) => Some(e),
485            _ => None,
486        }
487    }
488
489    /// Unwraps the expression into a "less than or equal to" expression.
490    ///
491    /// # Panics
492    ///
493    /// Panics if the expression is not a "less than or equal to" expression.
494    pub fn unwrap_less_equal(self) -> LessEqualExpr<N> {
495        match self {
496            Self::LessEqual(e) => e,
497            _ => panic!("not a \"less than or equal to\" expression"),
498        }
499    }
500
501    /// Attempts to get a reference to the inner [`GreaterExpr`].
502    ///
503    /// * If `self` is a [`Expr::Greater`], then a reference to the inner
504    ///   [`GreaterExpr`] is returned wrapped in [`Some`].
505    /// * Else, [`None`] is returned.
506    pub fn as_greater(&self) -> Option<&GreaterExpr<N>> {
507        match self {
508            Self::Greater(e) => Some(e),
509            _ => None,
510        }
511    }
512
513    /// Consumes `self` and attempts to return the inner [`GreaterExpr`].
514    ///
515    /// * If `self` is a [`Expr::Greater`], then the inner [`GreaterExpr`] is
516    ///   returned wrapped in [`Some`].
517    /// * Else, [`None`] is returned.
518    pub fn into_greater(self) -> Option<GreaterExpr<N>> {
519        match self {
520            Self::Greater(e) => Some(e),
521            _ => None,
522        }
523    }
524
525    /// Unwraps the expression into a "greater than" expression.
526    ///
527    /// # Panics
528    ///
529    /// Panics if the expression is not a "greater than" expression.
530    pub fn unwrap_greater(self) -> GreaterExpr<N> {
531        match self {
532            Self::Greater(e) => e,
533            _ => panic!("not a \"greater than\" expression"),
534        }
535    }
536
537    /// Attempts to get a reference to the inner [`GreaterEqualExpr`].
538    ///
539    /// * If `self` is a [`Expr::GreaterEqual`], then a reference to the inner
540    ///   [`GreaterEqualExpr`] is returned wrapped in [`Some`].
541    /// * Else, [`None`] is returned.
542    pub fn as_greater_equal(&self) -> Option<&GreaterEqualExpr<N>> {
543        match self {
544            Self::GreaterEqual(e) => Some(e),
545            _ => None,
546        }
547    }
548
549    /// Consumes `self` and attempts to return the inner [`GreaterEqualExpr`].
550    ///
551    /// * If `self` is a [`Expr::GreaterEqual`], then the inner
552    ///   [`GreaterEqualExpr`] is returned wrapped in [`Some`].
553    /// * Else, [`None`] is returned.
554    pub fn into_greater_equal(self) -> Option<GreaterEqualExpr<N>> {
555        match self {
556            Self::GreaterEqual(e) => Some(e),
557            _ => None,
558        }
559    }
560
561    /// Unwraps the expression into a "greater than or equal to" expression.
562    ///
563    /// # Panics
564    ///
565    /// Panics if the expression is not a "greater than or equal to" expression.
566    pub fn unwrap_greater_equal(self) -> GreaterEqualExpr<N> {
567        match self {
568            Self::GreaterEqual(e) => e,
569            _ => panic!("not a \"greater than or equal to\" expression"),
570        }
571    }
572
573    /// Attempts to get a reference to the inner [`AdditionExpr`].
574    ///
575    /// * If `self` is a [`Expr::Addition`], then a reference to the inner
576    ///   [`AdditionExpr`] is returned wrapped in [`Some`].
577    /// * Else, [`None`] is returned.
578    pub fn as_addition(&self) -> Option<&AdditionExpr<N>> {
579        match self {
580            Self::Addition(e) => Some(e),
581            _ => None,
582        }
583    }
584
585    /// Consumes `self` and attempts to return the inner [`AdditionExpr`].
586    ///
587    /// * If `self` is a [`Expr::Addition`], then the inner [`AdditionExpr`] is
588    ///   returned wrapped in [`Some`].
589    /// * Else, [`None`] is returned.
590    pub fn into_addition(self) -> Option<AdditionExpr<N>> {
591        match self {
592            Self::Addition(e) => Some(e),
593            _ => None,
594        }
595    }
596
597    /// Unwraps the expression into an addition expression.
598    ///
599    /// # Panics
600    ///
601    /// Panics if the expression is not an addition expression.
602    pub fn unwrap_addition(self) -> AdditionExpr<N> {
603        match self {
604            Self::Addition(e) => e,
605            _ => panic!("not an addition expression"),
606        }
607    }
608
609    /// Attempts to get a reference to the inner [`SubtractionExpr`].
610    ///
611    /// * If `self` is a [`Expr::Subtraction`], then a reference to the inner
612    ///   [`SubtractionExpr`] is returned wrapped in [`Some`].
613    /// * Else, [`None`] is returned.
614    pub fn as_subtraction(&self) -> Option<&SubtractionExpr<N>> {
615        match self {
616            Self::Subtraction(e) => Some(e),
617            _ => None,
618        }
619    }
620
621    /// Consumes `self` and attempts to return the inner [`SubtractionExpr`].
622    ///
623    /// * If `self` is a [`Expr::Subtraction`], then the inner
624    ///   [`SubtractionExpr`] is returned wrapped in [`Some`].
625    /// * Else, [`None`] is returned.
626    pub fn into_subtraction(self) -> Option<SubtractionExpr<N>> {
627        match self {
628            Self::Subtraction(e) => Some(e),
629            _ => None,
630        }
631    }
632
633    /// Unwraps the expression into a subtraction expression.
634    ///
635    /// # Panics
636    ///
637    /// Panics if the expression is not a subtraction expression.
638    pub fn unwrap_subtraction(self) -> SubtractionExpr<N> {
639        match self {
640            Self::Subtraction(e) => e,
641            _ => panic!("not a subtraction expression"),
642        }
643    }
644
645    /// Attempts to get a reference to the inner [`MultiplicationExpr`].
646    ///
647    /// * If `self` is a [`Expr::Multiplication`], then a reference to the inner
648    ///   [`MultiplicationExpr`] is returned wrapped in [`Some`].
649    /// * Else, [`None`] is returned.
650    pub fn as_multiplication(&self) -> Option<&MultiplicationExpr<N>> {
651        match self {
652            Self::Multiplication(e) => Some(e),
653            _ => None,
654        }
655    }
656
657    /// Consumes `self` and attempts to return the inner [`MultiplicationExpr`].
658    ///
659    /// * If `self` is a [`Expr::Multiplication`], then the inner
660    ///   [`MultiplicationExpr`] is returned wrapped in [`Some`].
661    /// * Else, [`None`] is returned.
662    pub fn into_multiplication(self) -> Option<MultiplicationExpr<N>> {
663        match self {
664            Self::Multiplication(e) => Some(e),
665            _ => None,
666        }
667    }
668
669    /// Unwraps the expression into a multiplication expression.
670    ///
671    /// # Panics
672    ///
673    /// Panics if the expression is not a multiplication expression.
674    pub fn unwrap_multiplication(self) -> MultiplicationExpr<N> {
675        match self {
676            Self::Multiplication(e) => e,
677            _ => panic!("not a multiplication expression"),
678        }
679    }
680
681    /// Attempts to get a reference to the inner [`DivisionExpr`].
682    ///
683    /// * If `self` is a [`Expr::Division`], then a reference to the inner
684    ///   [`DivisionExpr`] is returned wrapped in [`Some`].
685    /// * Else, [`None`] is returned.
686    pub fn as_division(&self) -> Option<&DivisionExpr<N>> {
687        match self {
688            Self::Division(e) => Some(e),
689            _ => None,
690        }
691    }
692
693    /// Consumes `self` and attempts to return the inner [`DivisionExpr`].
694    ///
695    /// * If `self` is a [`Expr::Division`], then the inner [`DivisionExpr`] is
696    ///   returned wrapped in [`Some`].
697    /// * Else, [`None`] is returned.
698    pub fn into_division(self) -> Option<DivisionExpr<N>> {
699        match self {
700            Self::Division(e) => Some(e),
701            _ => None,
702        }
703    }
704
705    /// Unwraps the expression into a division expression.
706    ///
707    /// # Panics
708    ///
709    /// Panics if the expression is not a division expression.
710    pub fn unwrap_division(self) -> DivisionExpr<N> {
711        match self {
712            Self::Division(e) => e,
713            _ => panic!("not a division expression"),
714        }
715    }
716
717    /// Attempts to get a reference to the inner [`ModuloExpr`].
718    ///
719    /// * If `self` is a [`Expr::Modulo`], then a reference to the inner
720    ///   [`ModuloExpr`] is returned wrapped in [`Some`].
721    /// * Else, [`None`] is returned.
722    pub fn as_modulo(&self) -> Option<&ModuloExpr<N>> {
723        match self {
724            Self::Modulo(e) => Some(e),
725            _ => None,
726        }
727    }
728
729    /// Consumes `self` and attempts to return the inner [`ModuloExpr`].
730    ///
731    /// * If `self` is a [`Expr::Modulo`], then the inner [`ModuloExpr`] is
732    ///   returned wrapped in [`Some`].
733    /// * Else, [`None`] is returned.
734    pub fn into_modulo(self) -> Option<ModuloExpr<N>> {
735        match self {
736            Self::Modulo(e) => Some(e),
737            _ => None,
738        }
739    }
740
741    /// Unwraps the expression into a modulo expression.
742    ///
743    /// # Panics
744    ///
745    /// Panics if the expression is not a modulo expression.
746    pub fn unwrap_modulo(self) -> ModuloExpr<N> {
747        match self {
748            Self::Modulo(e) => e,
749            _ => panic!("not a modulo expression"),
750        }
751    }
752
753    /// Attempts to get a reference to the inner [`ExponentiationExpr`].
754    ///
755    /// * If `self` is a [`Expr::Exponentiation`], then a reference to the inner
756    ///   [`ExponentiationExpr`] is returned wrapped in [`Some`].
757    /// * Else, [`None`] is returned.
758    pub fn as_exponentiation(&self) -> Option<&ExponentiationExpr<N>> {
759        match self {
760            Self::Exponentiation(e) => Some(e),
761            _ => None,
762        }
763    }
764
765    /// Consumes `self` and attempts to return the inner [`ExponentiationExpr`].
766    ///
767    /// * If `self` is a [`Expr::Exponentiation`], then the inner
768    ///   [`ExponentiationExpr`] is returned wrapped in [`Some`].
769    /// * Else, [`None`] is returned.
770    pub fn into_exponentiation(self) -> Option<ExponentiationExpr<N>> {
771        match self {
772            Self::Exponentiation(e) => Some(e),
773            _ => None,
774        }
775    }
776
777    /// Unwraps the expression into an exponentiation expression.
778    ///
779    /// # Panics
780    ///
781    /// Panics if the expression is not an exponentiation expression.
782    pub fn unwrap_exponentiation(self) -> ExponentiationExpr<N> {
783        match self {
784            Self::Exponentiation(e) => e,
785            _ => panic!("not an exponentiation expression"),
786        }
787    }
788
789    /// Attempts to get a reference to the inner [`CallExpr`].
790    ///
791    /// * If `self` is a [`Expr::Call`], then a reference to the inner
792    ///   [`CallExpr`] is returned wrapped in [`Some`].
793    /// * Else, [`None`] is returned.
794    pub fn as_call(&self) -> Option<&CallExpr<N>> {
795        match self {
796            Self::Call(e) => Some(e),
797            _ => None,
798        }
799    }
800
801    /// Consumes `self` and attempts to return the inner [`CallExpr`].
802    ///
803    /// * If `self` is a [`Expr::Call`], then the inner [`CallExpr`] is returned
804    ///   wrapped in [`Some`].
805    /// * Else, [`None`] is returned.
806    pub fn into_call(self) -> Option<CallExpr<N>> {
807        match self {
808            Self::Call(e) => Some(e),
809            _ => None,
810        }
811    }
812
813    /// Unwraps the expression into a call expression.
814    ///
815    /// # Panics
816    ///
817    /// Panics if the expression is not a call expression.
818    pub fn unwrap_call(self) -> CallExpr<N> {
819        match self {
820            Self::Call(e) => e,
821            _ => panic!("not a call expression"),
822        }
823    }
824
825    /// Attempts to get a reference to the inner [`IndexExpr`].
826    ///
827    /// * If `self` is a [`Expr::Index`], then a reference to the inner
828    ///   [`IndexExpr`] is returned wrapped in [`Some`].
829    /// * Else, [`None`] is returned.
830    pub fn as_index(&self) -> Option<&IndexExpr<N>> {
831        match self {
832            Self::Index(e) => Some(e),
833            _ => None,
834        }
835    }
836
837    /// Consumes `self` and attempts to return the inner [`IndexExpr`].
838    ///
839    /// * If `self` is a [`Expr::Index`], then the inner [`IndexExpr`] is
840    ///   returned wrapped in [`Some`].
841    /// * Else, [`None`] is returned.
842    pub fn into_index(self) -> Option<IndexExpr<N>> {
843        match self {
844            Self::Index(e) => Some(e),
845            _ => None,
846        }
847    }
848
849    /// Unwraps the expression into an index expression.
850    ///
851    /// # Panics
852    ///
853    /// Panics if the expression is not an index expression.
854    pub fn unwrap_index(self) -> IndexExpr<N> {
855        match self {
856            Self::Index(e) => e,
857            _ => panic!("not an index expression"),
858        }
859    }
860
861    /// Attempts to get a reference to the inner [`AccessExpr`].
862    ///
863    /// * If `self` is a [`Expr::Access`], then a reference to the inner
864    ///   [`AccessExpr`] is returned wrapped in [`Some`].
865    /// * Else, [`None`] is returned.
866    pub fn as_access(&self) -> Option<&AccessExpr<N>> {
867        match self {
868            Self::Access(e) => Some(e),
869            _ => None,
870        }
871    }
872
873    /// Consumes `self` and attempts to return the inner [`AccessExpr`].
874    ///
875    /// * If `self` is a [`Expr::Access`], then the inner [`AccessExpr`] is
876    ///   returned wrapped in [`Some`].
877    /// * Else, [`None`] is returned.
878    pub fn into_access(self) -> Option<AccessExpr<N>> {
879        match self {
880            Self::Access(e) => Some(e),
881            _ => None,
882        }
883    }
884
885    /// Unwraps the expression into an access expression.
886    ///
887    /// # Panics
888    ///
889    /// Panics if the expression is not an access expression.
890    pub fn unwrap_access(self) -> AccessExpr<N> {
891        match self {
892            Self::Access(e) => e,
893            _ => panic!("not an access expression"),
894        }
895    }
896
897    /// Finds the first child that can be cast to an [`Expr`].
898    pub fn child(node: &N) -> Option<Self> {
899        node.children().find_map(Self::cast)
900    }
901
902    /// Finds all children that can be cast to an [`Expr`].
903    pub fn children(node: &N) -> impl Iterator<Item = Self> + use<'_, N> {
904        node.children().filter_map(Self::cast)
905    }
906
907    /// Determines if the expression is an empty array literal or any number of
908    /// parenthesized expressions that terminate with an empty array literal.
909    pub fn is_empty_array_literal(&self) -> bool {
910        if let Self::Literal(LiteralExpr::Array(expr)) = self.clone().strip_parenthesized() {
911            return expr.elements().next().is_none();
912        }
913
914        false
915    }
916
917    /// Strip all layers of [`Expr::Parenthesized`] and return the inner
918    /// expression.
919    pub fn strip_parenthesized(mut self) -> Self {
920        while let Self::Parenthesized(inner) = self {
921            self = inner.expr();
922        }
923        self
924    }
925}
926
927impl<N: TreeNode> AstNode<N> for Expr<N> {
928    fn can_cast(kind: SyntaxKind) -> bool {
929        if LiteralExpr::<N>::can_cast(kind) {
930            return true;
931        }
932
933        matches!(
934            kind,
935            SyntaxKind::NameRefExprNode
936                | SyntaxKind::ParenthesizedExprNode
937                | SyntaxKind::IfExprNode
938                | SyntaxKind::LogicalNotExprNode
939                | SyntaxKind::NegationExprNode
940                | SyntaxKind::LogicalOrExprNode
941                | SyntaxKind::LogicalAndExprNode
942                | SyntaxKind::EqualityExprNode
943                | SyntaxKind::InequalityExprNode
944                | SyntaxKind::LessExprNode
945                | SyntaxKind::LessEqualExprNode
946                | SyntaxKind::GreaterExprNode
947                | SyntaxKind::GreaterEqualExprNode
948                | SyntaxKind::AdditionExprNode
949                | SyntaxKind::SubtractionExprNode
950                | SyntaxKind::MultiplicationExprNode
951                | SyntaxKind::DivisionExprNode
952                | SyntaxKind::ModuloExprNode
953                | SyntaxKind::ExponentiationExprNode
954                | SyntaxKind::CallExprNode
955                | SyntaxKind::IndexExprNode
956                | SyntaxKind::AccessExprNode
957        )
958    }
959
960    fn cast(inner: N) -> Option<Self> {
961        if LiteralExpr::<N>::can_cast(inner.kind()) {
962            return LiteralExpr::cast(inner).map(Self::Literal);
963        }
964
965        match inner.kind() {
966            SyntaxKind::NameRefExprNode => Some(Self::NameRef(NameRefExpr(inner))),
967            SyntaxKind::ParenthesizedExprNode => {
968                Some(Self::Parenthesized(ParenthesizedExpr(inner)))
969            }
970            SyntaxKind::IfExprNode => Some(Self::If(IfExpr(inner))),
971            SyntaxKind::LogicalNotExprNode => Some(Self::LogicalNot(LogicalNotExpr(inner))),
972            SyntaxKind::NegationExprNode => Some(Self::Negation(NegationExpr(inner))),
973            SyntaxKind::LogicalOrExprNode => Some(Self::LogicalOr(LogicalOrExpr(inner))),
974            SyntaxKind::LogicalAndExprNode => Some(Self::LogicalAnd(LogicalAndExpr(inner))),
975            SyntaxKind::EqualityExprNode => Some(Self::Equality(EqualityExpr(inner))),
976            SyntaxKind::InequalityExprNode => Some(Self::Inequality(InequalityExpr(inner))),
977            SyntaxKind::LessExprNode => Some(Self::Less(LessExpr(inner))),
978            SyntaxKind::LessEqualExprNode => Some(Self::LessEqual(LessEqualExpr(inner))),
979            SyntaxKind::GreaterExprNode => Some(Self::Greater(GreaterExpr(inner))),
980            SyntaxKind::GreaterEqualExprNode => Some(Self::GreaterEqual(GreaterEqualExpr(inner))),
981            SyntaxKind::AdditionExprNode => Some(Self::Addition(AdditionExpr(inner))),
982            SyntaxKind::SubtractionExprNode => Some(Self::Subtraction(SubtractionExpr(inner))),
983            SyntaxKind::MultiplicationExprNode => {
984                Some(Self::Multiplication(MultiplicationExpr(inner)))
985            }
986            SyntaxKind::DivisionExprNode => Some(Self::Division(DivisionExpr(inner))),
987            SyntaxKind::ModuloExprNode => Some(Self::Modulo(ModuloExpr(inner))),
988            SyntaxKind::ExponentiationExprNode => {
989                Some(Self::Exponentiation(ExponentiationExpr(inner)))
990            }
991            SyntaxKind::CallExprNode => Some(Self::Call(CallExpr(inner))),
992            SyntaxKind::IndexExprNode => Some(Self::Index(IndexExpr(inner))),
993            SyntaxKind::AccessExprNode => Some(Self::Access(AccessExpr(inner))),
994            _ => None,
995        }
996    }
997
998    fn inner(&self) -> &N {
999        match self {
1000            Self::Literal(l) => l.inner(),
1001            Self::NameRef(n) => &n.0,
1002            Self::Parenthesized(p) => &p.0,
1003            Self::If(i) => &i.0,
1004            Self::LogicalNot(n) => &n.0,
1005            Self::Negation(n) => &n.0,
1006            Self::LogicalOr(o) => &o.0,
1007            Self::LogicalAnd(a) => &a.0,
1008            Self::Equality(e) => &e.0,
1009            Self::Inequality(i) => &i.0,
1010            Self::Less(l) => &l.0,
1011            Self::LessEqual(l) => &l.0,
1012            Self::Greater(g) => &g.0,
1013            Self::GreaterEqual(g) => &g.0,
1014            Self::Addition(a) => &a.0,
1015            Self::Subtraction(s) => &s.0,
1016            Self::Multiplication(m) => &m.0,
1017            Self::Division(d) => &d.0,
1018            Self::Modulo(m) => &m.0,
1019            Self::Exponentiation(e) => &e.0,
1020            Self::Call(c) => &c.0,
1021            Self::Index(i) => &i.0,
1022            Self::Access(a) => &a.0,
1023        }
1024    }
1025}
1026
1027/// Represents a literal expression.
1028#[derive(Clone, Debug, PartialEq, Eq)]
1029pub enum LiteralExpr<N: TreeNode = SyntaxNode> {
1030    /// The literal is a `Boolean`.
1031    Boolean(LiteralBoolean<N>),
1032    /// The literal is an `Int`.
1033    Integer(LiteralInteger<N>),
1034    /// The literal is a `Float`.
1035    Float(LiteralFloat<N>),
1036    /// The literal is a `String`.
1037    String(LiteralString<N>),
1038    /// The literal is an `Array`.
1039    Array(LiteralArray<N>),
1040    /// The literal is a `Pair`.
1041    Pair(LiteralPair<N>),
1042    /// The literal is a `Map`.
1043    Map(LiteralMap<N>),
1044    /// The literal is an `Object`.
1045    Object(LiteralObject<N>),
1046    /// The literal is a struct.
1047    Struct(LiteralStruct<N>),
1048    /// The literal is a `None`.
1049    None(LiteralNone<N>),
1050    /// The literal is a `hints`.
1051    Hints(LiteralHints<N>),
1052    /// The literal is an `input`.
1053    Input(LiteralInput<N>),
1054    /// The literal is an `output`.
1055    Output(LiteralOutput<N>),
1056}
1057
1058impl<N: TreeNode> LiteralExpr<N> {
1059    /// Returns whether or not the given syntax kind can be cast to
1060    /// [`LiteralExpr`].
1061    pub fn can_cast(kind: SyntaxKind) -> bool {
1062        matches!(
1063            kind,
1064            SyntaxKind::LiteralBooleanNode
1065                | SyntaxKind::LiteralIntegerNode
1066                | SyntaxKind::LiteralFloatNode
1067                | SyntaxKind::LiteralStringNode
1068                | SyntaxKind::LiteralArrayNode
1069                | SyntaxKind::LiteralPairNode
1070                | SyntaxKind::LiteralMapNode
1071                | SyntaxKind::LiteralObjectNode
1072                | SyntaxKind::LiteralStructNode
1073                | SyntaxKind::LiteralNoneNode
1074                | SyntaxKind::LiteralHintsNode
1075                | SyntaxKind::LiteralInputNode
1076                | SyntaxKind::LiteralOutputNode
1077        )
1078    }
1079
1080    /// Casts the given node to [`LiteralExpr`].
1081    ///
1082    /// Returns `None` if the node cannot be cast.
1083    pub fn cast(inner: N) -> Option<Self> {
1084        match inner.kind() {
1085            SyntaxKind::LiteralBooleanNode => Some(Self::Boolean(
1086                LiteralBoolean::cast(inner).expect("literal boolean to cast"),
1087            )),
1088            SyntaxKind::LiteralIntegerNode => Some(Self::Integer(
1089                LiteralInteger::cast(inner).expect("literal integer to cast"),
1090            )),
1091            SyntaxKind::LiteralFloatNode => Some(Self::Float(
1092                LiteralFloat::cast(inner).expect("literal float to cast"),
1093            )),
1094            SyntaxKind::LiteralStringNode => Some(Self::String(
1095                LiteralString::cast(inner).expect("literal string to cast"),
1096            )),
1097            SyntaxKind::LiteralArrayNode => Some(Self::Array(
1098                LiteralArray::cast(inner).expect("literal array to cast"),
1099            )),
1100            SyntaxKind::LiteralPairNode => Some(Self::Pair(
1101                LiteralPair::cast(inner).expect("literal pair to cast"),
1102            )),
1103            SyntaxKind::LiteralMapNode => Some(Self::Map(
1104                LiteralMap::cast(inner).expect("literal map to case"),
1105            )),
1106            SyntaxKind::LiteralObjectNode => Some(Self::Object(
1107                LiteralObject::cast(inner).expect("literal object to cast"),
1108            )),
1109            SyntaxKind::LiteralStructNode => Some(Self::Struct(
1110                LiteralStruct::cast(inner).expect("literal struct to cast"),
1111            )),
1112            SyntaxKind::LiteralNoneNode => Some(Self::None(
1113                LiteralNone::cast(inner).expect("literal none to cast"),
1114            )),
1115            SyntaxKind::LiteralHintsNode => Some(Self::Hints(
1116                LiteralHints::cast(inner).expect("literal hints to cast"),
1117            )),
1118            SyntaxKind::LiteralInputNode => Some(Self::Input(
1119                LiteralInput::cast(inner).expect("literal input to cast"),
1120            )),
1121            SyntaxKind::LiteralOutputNode => Some(Self::Output(
1122                LiteralOutput::cast(inner).expect("literal output to cast"),
1123            )),
1124            _ => None,
1125        }
1126    }
1127
1128    /// Gets a reference to the inner node.
1129    pub fn inner(&self) -> &N {
1130        match self {
1131            Self::Boolean(e) => e.inner(),
1132            Self::Integer(e) => e.inner(),
1133            Self::Float(e) => e.inner(),
1134            Self::String(e) => e.inner(),
1135            Self::Array(e) => e.inner(),
1136            Self::Pair(e) => e.inner(),
1137            Self::Map(e) => e.inner(),
1138            Self::Object(e) => e.inner(),
1139            Self::Struct(e) => e.inner(),
1140            Self::None(e) => e.inner(),
1141            Self::Hints(e) => e.inner(),
1142            Self::Input(e) => e.inner(),
1143            Self::Output(e) => e.inner(),
1144        }
1145    }
1146
1147    /// Attempts to get a reference to the inner [`LiteralBoolean`].
1148    ///
1149    /// * If `self` is a [`LiteralExpr::Boolean`], then a reference to the inner
1150    ///   [`LiteralBoolean`] is returned wrapped in [`Some`].
1151    /// * Else, [`None`] is returned.
1152    pub fn as_boolean(&self) -> Option<&LiteralBoolean<N>> {
1153        match self {
1154            Self::Boolean(e) => Some(e),
1155            _ => None,
1156        }
1157    }
1158
1159    /// Consumes `self` and attempts to return the inner [`LiteralBoolean`].
1160    ///
1161    /// * If `self` is a [`LiteralExpr::Boolean`], then the inner
1162    ///   [`LiteralBoolean`] is returned wrapped in [`Some`].
1163    /// * Else, [`None`] is returned.
1164    pub fn into_boolean(self) -> Option<LiteralBoolean<N>> {
1165        match self {
1166            Self::Boolean(e) => Some(e),
1167            _ => None,
1168        }
1169    }
1170
1171    /// Unwraps the expression into a literal boolean.
1172    ///
1173    /// # Panics
1174    ///
1175    /// Panics if the expression is not a literal boolean.
1176    pub fn unwrap_boolean(self) -> LiteralBoolean<N> {
1177        match self {
1178            Self::Boolean(e) => e,
1179            _ => panic!("not a literal boolean"),
1180        }
1181    }
1182
1183    /// Attempts to get a reference to the inner [`LiteralInteger`].
1184    ///
1185    /// * If `self` is a [`LiteralExpr::Integer`], then a reference to the inner
1186    ///   [`LiteralInteger`] is returned wrapped in [`Some`].
1187    /// * Else, [`None`] is returned.
1188    pub fn as_integer(&self) -> Option<&LiteralInteger<N>> {
1189        match self {
1190            Self::Integer(e) => Some(e),
1191            _ => None,
1192        }
1193    }
1194
1195    /// Consumes `self` and attempts to return the inner [`LiteralInteger`].
1196    ///
1197    /// * If `self` is a [`LiteralExpr::Integer`], then the inner
1198    ///   [`LiteralInteger`] is returned wrapped in [`Some`].
1199    /// * Else, [`None`] is returned.
1200    pub fn into_integer(self) -> Option<LiteralInteger<N>> {
1201        match self {
1202            Self::Integer(e) => Some(e),
1203            _ => None,
1204        }
1205    }
1206
1207    /// Unwraps the expression into a literal integer.
1208    ///
1209    /// # Panics
1210    ///
1211    /// Panics if the expression is not a literal integer.
1212    pub fn unwrap_integer(self) -> LiteralInteger<N> {
1213        match self {
1214            Self::Integer(e) => e,
1215            _ => panic!("not a literal integer"),
1216        }
1217    }
1218
1219    /// Attempts to get a reference to the inner [`LiteralFloat`].
1220    ///
1221    /// * If `self` is a [`LiteralExpr::Float`], then a reference to the inner
1222    ///   [`LiteralFloat`] is returned wrapped in [`Some`].
1223    /// * Else, [`None`] is returned.
1224    pub fn as_float(&self) -> Option<&LiteralFloat<N>> {
1225        match self {
1226            Self::Float(e) => Some(e),
1227            _ => None,
1228        }
1229    }
1230
1231    /// Consumes `self` and attempts to return the inner [`LiteralFloat`].
1232    ///
1233    /// * If `self` is a [`LiteralExpr::Float`], then the inner [`LiteralFloat`]
1234    ///   is returned wrapped in [`Some`].
1235    /// * Else, [`None`] is returned.
1236    pub fn into_float(self) -> Option<LiteralFloat<N>> {
1237        match self {
1238            Self::Float(e) => Some(e),
1239            _ => None,
1240        }
1241    }
1242
1243    /// Unwraps the expression into a literal float.
1244    ///
1245    /// # Panics
1246    ///
1247    /// Panics if the expression is not a literal float.
1248    pub fn unwrap_float(self) -> LiteralFloat<N> {
1249        match self {
1250            Self::Float(e) => e,
1251            _ => panic!("not a literal float"),
1252        }
1253    }
1254
1255    /// Attempts to get a reference to the inner [`LiteralString`].
1256    ///
1257    /// * If `self` is a [`LiteralExpr::String`], then a reference to the inner
1258    ///   [`LiteralString`] is returned wrapped in [`Some`].
1259    /// * Else, [`None`] is returned.
1260    pub fn as_string(&self) -> Option<&LiteralString<N>> {
1261        match self {
1262            Self::String(e) => Some(e),
1263            _ => None,
1264        }
1265    }
1266
1267    /// Consumes `self` and attempts to return the inner [`LiteralString`].
1268    ///
1269    /// * If `self` is a [`LiteralExpr::String`], then the inner
1270    ///   [`LiteralString`] is returned wrapped in [`Some`].
1271    /// * Else, [`None`] is returned.
1272    pub fn into_string(self) -> Option<LiteralString<N>> {
1273        match self {
1274            Self::String(e) => Some(e),
1275            _ => None,
1276        }
1277    }
1278
1279    /// Unwraps the expression into a literal string.
1280    ///
1281    /// # Panics
1282    ///
1283    /// Panics if the expression is not a literal string.
1284    pub fn unwrap_string(self) -> LiteralString<N> {
1285        match self {
1286            Self::String(e) => e,
1287            _ => panic!("not a literal string"),
1288        }
1289    }
1290
1291    /// Attempts to get a reference to the inner [`LiteralArray`].
1292    ///
1293    /// * If `self` is a [`LiteralExpr::Array`], then a reference to the inner
1294    ///   [`LiteralArray`] is returned wrapped in [`Some`].
1295    /// * Else, [`None`] is returned.
1296    pub fn as_array(&self) -> Option<&LiteralArray<N>> {
1297        match self {
1298            Self::Array(e) => Some(e),
1299            _ => None,
1300        }
1301    }
1302
1303    /// Consumes `self` and attempts to return the inner [`LiteralArray`].
1304    ///
1305    /// * If `self` is a [`LiteralExpr::Array`], then the inner [`LiteralArray`]
1306    ///   is returned wrapped in [`Some`].
1307    /// * Else, [`None`] is returned.
1308    pub fn into_array(self) -> Option<LiteralArray<N>> {
1309        match self {
1310            Self::Array(e) => Some(e),
1311            _ => None,
1312        }
1313    }
1314
1315    /// Unwraps the expression into a literal array.
1316    ///
1317    /// # Panics
1318    ///
1319    /// Panics if the expression is not a literal array.
1320    pub fn unwrap_array(self) -> LiteralArray<N> {
1321        match self {
1322            Self::Array(e) => e,
1323            _ => panic!("not a literal array"),
1324        }
1325    }
1326
1327    /// Attempts to get a reference to the inner [`LiteralPair`].
1328    ///
1329    /// * If `self` is a [`LiteralExpr::Pair`], then a reference to the inner
1330    ///   [`LiteralPair`] is returned wrapped in [`Some`].
1331    /// * Else, [`None`] is returned.
1332    pub fn as_pair(&self) -> Option<&LiteralPair<N>> {
1333        match self {
1334            Self::Pair(e) => Some(e),
1335            _ => None,
1336        }
1337    }
1338
1339    /// Consumes `self` and attempts to return the inner [`LiteralPair`].
1340    ///
1341    /// * If `self` is a [`LiteralExpr::Pair`], then the inner [`LiteralPair`]
1342    ///   is returned wrapped in [`Some`].
1343    /// * Else, [`None`] is returned.
1344    pub fn into_pair(self) -> Option<LiteralPair<N>> {
1345        match self {
1346            Self::Pair(e) => Some(e),
1347            _ => None,
1348        }
1349    }
1350
1351    /// Unwraps the expression into a literal pair.
1352    ///
1353    /// # Panics
1354    ///
1355    /// Panics if the expression is not a literal pair.
1356    pub fn unwrap_pair(self) -> LiteralPair<N> {
1357        match self {
1358            Self::Pair(e) => e,
1359            _ => panic!("not a literal pair"),
1360        }
1361    }
1362
1363    /// Attempts to get a reference to the inner [`LiteralMap`].
1364    ///
1365    /// * If `self` is a [`LiteralExpr::Map`], then a reference to the inner
1366    ///   [`LiteralMap`] is returned wrapped in [`Some`].
1367    /// * Else, [`None`] is returned.
1368    pub fn as_map(&self) -> Option<&LiteralMap<N>> {
1369        match self {
1370            Self::Map(e) => Some(e),
1371            _ => None,
1372        }
1373    }
1374
1375    /// Consumes `self` and attempts to return the inner [`LiteralMap`].
1376    ///
1377    /// * If `self` is a [`LiteralExpr::Map`], then the inner [`LiteralMap`] is
1378    ///   returned wrapped in [`Some`].
1379    /// * Else, [`None`] is returned.
1380    pub fn into_map(self) -> Option<LiteralMap<N>> {
1381        match self {
1382            Self::Map(e) => Some(e),
1383            _ => None,
1384        }
1385    }
1386
1387    /// Unwraps the expression into a literal map.
1388    ///
1389    /// # Panics
1390    ///
1391    /// Panics if the expression is not a literal map.
1392    pub fn unwrap_map(self) -> LiteralMap<N> {
1393        match self {
1394            Self::Map(e) => e,
1395            _ => panic!("not a literal map"),
1396        }
1397    }
1398
1399    /// Attempts to get a reference to the inner [`LiteralObject`].
1400    ///
1401    /// * If `self` is a [`LiteralExpr::Object`], then a reference to the inner
1402    ///   [`LiteralObject`] is returned wrapped in [`Some`].
1403    /// * Else, [`None`] is returned.
1404    pub fn as_object(&self) -> Option<&LiteralObject<N>> {
1405        match self {
1406            Self::Object(e) => Some(e),
1407            _ => None,
1408        }
1409    }
1410
1411    /// Consumes `self` and attempts to return the inner [`LiteralObject`].
1412    ///
1413    /// * If `self` is a [`LiteralExpr::Object`], then the inner
1414    ///   [`LiteralObject`] is returned wrapped in [`Some`].
1415    /// * Else, [`None`] is returned.
1416    pub fn into_object(self) -> Option<LiteralObject<N>> {
1417        match self {
1418            Self::Object(e) => Some(e),
1419            _ => None,
1420        }
1421    }
1422
1423    /// Unwraps the expression into a literal object.
1424    ///
1425    /// # Panics
1426    ///
1427    /// Panics if the expression is not a literal object.
1428    pub fn unwrap_object(self) -> LiteralObject<N> {
1429        match self {
1430            Self::Object(e) => e,
1431            _ => panic!("not a literal object"),
1432        }
1433    }
1434
1435    /// Attempts to get a reference to the inner [`LiteralStruct`].
1436    ///
1437    /// * If `self` is a [`LiteralExpr::Struct`], then a reference to the inner
1438    ///   [`LiteralStruct`] is returned wrapped in [`Some`].
1439    /// * Else, [`None`] is returned.
1440    pub fn as_struct(&self) -> Option<&LiteralStruct<N>> {
1441        match self {
1442            Self::Struct(e) => Some(e),
1443            _ => None,
1444        }
1445    }
1446
1447    /// Consumes `self` and attempts to return the inner [`LiteralStruct`].
1448    ///
1449    /// * If `self` is a [`LiteralExpr::Struct`], then the inner
1450    ///   [`LiteralStruct`] is returned wrapped in [`Some`].
1451    /// * Else, [`None`] is returned.
1452    pub fn into_struct(self) -> Option<LiteralStruct<N>> {
1453        match self {
1454            Self::Struct(e) => Some(e),
1455            _ => None,
1456        }
1457    }
1458
1459    /// Unwraps the expression into a literal struct.
1460    ///
1461    /// # Panics
1462    ///
1463    /// Panics if the expression is not a literal struct.
1464    pub fn unwrap_struct(self) -> LiteralStruct<N> {
1465        match self {
1466            Self::Struct(e) => e,
1467            _ => panic!("not a literal struct"),
1468        }
1469    }
1470
1471    /// Attempts to get a reference to the inner [`LiteralNone`].
1472    ///
1473    /// * If `self` is a [`LiteralExpr::None`], then a reference to the inner
1474    ///   [`LiteralNone`] is returned wrapped in [`Some`].
1475    /// * Else, [`None`] is returned.
1476    pub fn as_none(&self) -> Option<&LiteralNone<N>> {
1477        match self {
1478            Self::None(e) => Some(e),
1479            _ => None,
1480        }
1481    }
1482
1483    /// Consumes `self` and attempts to return the inner [`LiteralNone`].
1484    ///
1485    /// * If `self` is a [`LiteralExpr::None`], then the inner [`LiteralNone`]
1486    ///   is returned wrapped in [`Some`].
1487    /// * Else, [`None`] is returned.
1488    pub fn into_none(self) -> Option<LiteralNone<N>> {
1489        match self {
1490            Self::None(e) => Some(e),
1491            _ => None,
1492        }
1493    }
1494
1495    /// Unwraps the expression into a literal `None`.
1496    ///
1497    /// # Panics
1498    ///
1499    /// Panics if the expression is not a literal `None`.
1500    pub fn unwrap_none(self) -> LiteralNone<N> {
1501        match self {
1502            Self::None(e) => e,
1503            _ => panic!("not a literal `None`"),
1504        }
1505    }
1506
1507    /// Attempts to get a reference to the inner [`LiteralHints`].
1508    ///
1509    /// * If `self` is a [`LiteralExpr::Hints`], then a reference to the inner
1510    ///   [`LiteralHints`] is returned wrapped in [`Some`].
1511    /// * Else, [`None`] is returned.
1512    pub fn as_hints(&self) -> Option<&LiteralHints<N>> {
1513        match self {
1514            Self::Hints(e) => Some(e),
1515            _ => None,
1516        }
1517    }
1518
1519    /// Consumes `self` and attempts to return the inner [`LiteralHints`].
1520    ///
1521    /// * If `self` is a [`LiteralExpr::Hints`], then the inner [`LiteralHints`]
1522    ///   is returned wrapped in [`Some`].
1523    /// * Else, [`None`] is returned.
1524    pub fn into_hints(self) -> Option<LiteralHints<N>> {
1525        match self {
1526            Self::Hints(e) => Some(e),
1527            _ => None,
1528        }
1529    }
1530
1531    /// Unwraps the expression into a literal `hints`.
1532    ///
1533    /// # Panics
1534    ///
1535    /// Panics if the expression is not a literal `hints`.
1536    pub fn unwrap_hints(self) -> LiteralHints<N> {
1537        match self {
1538            Self::Hints(e) => e,
1539            _ => panic!("not a literal `hints`"),
1540        }
1541    }
1542
1543    /// Attempts to get a reference to the inner [`LiteralInput`].
1544    ///
1545    /// * If `self` is a [`LiteralExpr::Input`], then a reference to the inner
1546    ///   [`LiteralInput`] is returned wrapped in [`Some`].
1547    /// * Else, [`None`] is returned.
1548    pub fn as_input(&self) -> Option<&LiteralInput<N>> {
1549        match self {
1550            Self::Input(e) => Some(e),
1551            _ => None,
1552        }
1553    }
1554
1555    /// Consumes `self` and attempts to return the inner [`LiteralInput`].
1556    ///
1557    /// * If `self` is a [`LiteralExpr::Input`], then the inner [`LiteralInput`]
1558    ///   is returned wrapped in [`Some`].
1559    /// * Else, [`None`] is returned.
1560    pub fn into_input(self) -> Option<LiteralInput<N>> {
1561        match self {
1562            Self::Input(e) => Some(e),
1563            _ => None,
1564        }
1565    }
1566
1567    /// Unwraps the expression into a literal `input`.
1568    ///
1569    /// # Panics
1570    ///
1571    /// Panics if the expression is not a literal `input`.
1572    pub fn unwrap_input(self) -> LiteralInput<N> {
1573        match self {
1574            Self::Input(e) => e,
1575            _ => panic!("not a literal `input`"),
1576        }
1577    }
1578
1579    /// Attempts to get a reference to the inner [`LiteralOutput`].
1580    ///
1581    /// * If `self` is a [`LiteralExpr::Output`], then a reference to the inner
1582    ///   [`LiteralOutput`] is returned wrapped in [`Some`].
1583    /// * Else, [`None`] is returned.
1584    pub fn as_output(&self) -> Option<&LiteralOutput<N>> {
1585        match self {
1586            Self::Output(e) => Some(e),
1587            _ => None,
1588        }
1589    }
1590
1591    /// Consumes `self` and attempts to return the inner [`LiteralOutput`].
1592    ///
1593    /// * If `self` is a [`LiteralExpr::Output`], then the inner
1594    ///   [`LiteralOutput`] is returned wrapped in [`Some`].
1595    /// * Else, [`None`] is returned.
1596    pub fn into_output(self) -> Option<LiteralOutput<N>> {
1597        match self {
1598            Self::Output(e) => Some(e),
1599            _ => None,
1600        }
1601    }
1602
1603    /// Unwraps the expression into a literal `output`.
1604    ///
1605    /// # Panics
1606    ///
1607    /// Panics if the expression is not a literal `output`.
1608    pub fn unwrap_output(self) -> LiteralOutput<N> {
1609        match self {
1610            Self::Output(e) => e,
1611            _ => panic!("not a literal `output`"),
1612        }
1613    }
1614
1615    /// Finds the first child that can be cast to a [`LiteralExpr`].
1616    pub fn child(node: &N) -> Option<Self> {
1617        node.children().find_map(Self::cast)
1618    }
1619
1620    /// Finds all children that can be cast to a [`LiteralExpr`].
1621    pub fn children(node: &N) -> impl Iterator<Item = Self> + use<'_, N> {
1622        node.children().filter_map(Self::cast)
1623    }
1624}
1625
1626/// Represents a literal boolean.
1627#[derive(Clone, Debug, PartialEq, Eq)]
1628pub struct LiteralBoolean<N: TreeNode = SyntaxNode>(pub(super) N);
1629
1630impl<N: TreeNode> LiteralBoolean<N> {
1631    /// Gets the value of the literal boolean.
1632    pub fn value(&self) -> bool {
1633        self.0
1634            .children_with_tokens()
1635            .find_map(|c| {
1636                c.into_token().and_then(|t| match t.kind() {
1637                    SyntaxKind::TrueKeyword => Some(true),
1638                    SyntaxKind::FalseKeyword => Some(false),
1639                    _ => None,
1640                })
1641            })
1642            .expect("`true` or `false` keyword should be present")
1643    }
1644}
1645
1646impl<N: TreeNode> AstNode<N> for LiteralBoolean<N> {
1647    fn can_cast(kind: SyntaxKind) -> bool {
1648        kind == SyntaxKind::LiteralBooleanNode
1649    }
1650
1651    fn cast(inner: N) -> Option<Self> {
1652        match inner.kind() {
1653            SyntaxKind::LiteralBooleanNode => Some(Self(inner)),
1654            _ => None,
1655        }
1656    }
1657
1658    fn inner(&self) -> &N {
1659        &self.0
1660    }
1661}
1662
1663/// Represents an integer token.
1664#[derive(Clone, Debug, PartialEq, Eq)]
1665pub struct Integer<T: TreeToken = SyntaxToken>(T);
1666
1667impl<T: TreeToken> AstToken<T> for Integer<T> {
1668    fn can_cast(kind: SyntaxKind) -> bool {
1669        kind == SyntaxKind::Integer
1670    }
1671
1672    fn cast(inner: T) -> Option<Self> {
1673        match inner.kind() {
1674            SyntaxKind::Integer => Some(Self(inner)),
1675            _ => None,
1676        }
1677    }
1678
1679    fn inner(&self) -> &T {
1680        &self.0
1681    }
1682}
1683
1684/// Represents a literal integer.
1685#[derive(Clone, Debug, PartialEq, Eq)]
1686pub struct LiteralInteger<N: TreeNode = SyntaxNode>(pub(super) N);
1687
1688impl<N: TreeNode> LiteralInteger<N> {
1689    /// Gets the minus token for the literal integer.
1690    ///
1691    /// A minus token *only* occurs in metadata sections, where
1692    /// expressions are not allowed and a prefix `-` is included
1693    /// in the literal integer itself.
1694    ///
1695    /// Otherwise, a prefix `-` would be a negation expression and not
1696    /// part of the literal integer.
1697    pub fn minus(&self) -> Option<Minus<N::Token>> {
1698        self.token()
1699    }
1700
1701    /// Gets the integer token for the literal.
1702    pub fn integer(&self) -> Integer<N::Token> {
1703        self.token().expect("should have integer token")
1704    }
1705
1706    /// Gets the value of the literal integer.
1707    ///
1708    /// Returns `None` if the value is out of range.
1709    pub fn value(&self) -> Option<i64> {
1710        let value = self.as_u64()?;
1711
1712        // If there's a minus sign present, negate the value; this may
1713        // only occur in metadata sections
1714        if self.minus().is_some() {
1715            if value == (i64::MAX as u64) + 1 {
1716                return Some(i64::MIN);
1717            }
1718
1719            return Some(-(value as i64));
1720        }
1721
1722        if value == (i64::MAX as u64) + 1 {
1723            return None;
1724        }
1725
1726        Some(value as i64)
1727    }
1728
1729    /// Gets the negated value of the literal integer.
1730    ///
1731    /// Returns `None` if the resulting negation would overflow.
1732    ///
1733    /// This is used as part of negation expressions.
1734    pub fn negate(&self) -> Option<i64> {
1735        let value = self.as_u64()?;
1736
1737        // Check for "double" negation
1738        if self.minus().is_some() {
1739            // Can't negate i64::MIN as that would overflow
1740            if value == (i64::MAX as u64) + 1 {
1741                return None;
1742            }
1743
1744            return Some(value as i64);
1745        }
1746
1747        if value == (i64::MAX as u64) + 1 {
1748            return Some(i64::MIN);
1749        }
1750
1751        Some(-(value as i64))
1752    }
1753
1754    /// Gets the unsigned representation of the literal integer.
1755    ///
1756    /// This returns `None` if the integer is out of range for a 64-bit signed
1757    /// integer, excluding `i64::MAX + 1` to allow for negation.
1758    fn as_u64(&self) -> Option<u64> {
1759        let token = self.integer();
1760        let text = token.text();
1761        let i = if text == "0" {
1762            0
1763        } else if text.starts_with("0x") || text.starts_with("0X") {
1764            u64::from_str_radix(&text[2..], 16).ok()?
1765        } else if text.starts_with('0') {
1766            u64::from_str_radix(text, 8).ok()?
1767        } else {
1768            text.parse::<u64>().ok()?
1769        };
1770
1771        // Allow 1 more than the maximum to account for negation
1772        if i > (i64::MAX as u64) + 1 {
1773            None
1774        } else {
1775            Some(i)
1776        }
1777    }
1778}
1779
1780impl<N: TreeNode> AstNode<N> for LiteralInteger<N> {
1781    fn can_cast(kind: SyntaxKind) -> bool {
1782        kind == SyntaxKind::LiteralIntegerNode
1783    }
1784
1785    fn cast(inner: N) -> Option<Self> {
1786        match inner.kind() {
1787            SyntaxKind::LiteralIntegerNode => Some(Self(inner)),
1788            _ => None,
1789        }
1790    }
1791
1792    fn inner(&self) -> &N {
1793        &self.0
1794    }
1795}
1796
1797/// Represents a float token.
1798#[derive(Clone, Debug, PartialEq, Eq)]
1799pub struct Float<T: TreeToken = SyntaxToken>(T);
1800
1801impl<T: TreeToken> AstToken<T> for Float<T> {
1802    fn can_cast(kind: SyntaxKind) -> bool {
1803        kind == SyntaxKind::Float
1804    }
1805
1806    fn cast(inner: T) -> Option<Self> {
1807        match inner.kind() {
1808            SyntaxKind::Float => Some(Self(inner)),
1809            _ => None,
1810        }
1811    }
1812
1813    fn inner(&self) -> &T {
1814        &self.0
1815    }
1816}
1817
1818/// Represents a literal float.
1819#[derive(Clone, Debug, PartialEq, Eq)]
1820pub struct LiteralFloat<N: TreeNode = SyntaxNode>(pub(crate) N);
1821
1822impl<N: TreeNode> LiteralFloat<N> {
1823    /// Gets the minus token for the literal float.
1824    ///
1825    /// A minus token *only* occurs in metadata sections, where
1826    /// expressions are not allowed and a prefix `-` is included
1827    /// in the literal float itself.
1828    ///
1829    /// Otherwise, a prefix `-` would be a negation expression and not
1830    /// part of the literal float.
1831    pub fn minus(&self) -> Option<Minus<N::Token>> {
1832        self.token()
1833    }
1834
1835    /// Gets the float token for the literal.
1836    pub fn float(&self) -> Float<N::Token> {
1837        self.token().expect("should have float token")
1838    }
1839
1840    /// Gets the value of the literal float.
1841    ///
1842    /// Returns `None` if the literal value is not in range.
1843    pub fn value(&self) -> Option<f64> {
1844        self.float()
1845            .text()
1846            .parse()
1847            .ok()
1848            .filter(|f: &f64| !f.is_infinite())
1849    }
1850}
1851
1852impl<N: TreeNode> AstNode<N> for LiteralFloat<N> {
1853    fn can_cast(kind: SyntaxKind) -> bool {
1854        kind == SyntaxKind::LiteralFloatNode
1855    }
1856
1857    fn cast(inner: N) -> Option<Self> {
1858        match inner.kind() {
1859            SyntaxKind::LiteralFloatNode => Some(Self(inner)),
1860            _ => None,
1861        }
1862    }
1863
1864    fn inner(&self) -> &N {
1865        &self.0
1866    }
1867}
1868
1869/// Represents the kind of a literal string.
1870#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1871pub enum LiteralStringKind {
1872    /// The string is a single quoted string.
1873    SingleQuoted,
1874    /// The string is a double quoted string.
1875    DoubleQuoted,
1876    /// The string is a multi-line string.
1877    Multiline,
1878}
1879
1880/// Represents a multi-line string that's been stripped of leading whitespace
1881/// and it's line continuations parsed. Placeholders are not changed and are
1882/// copied as-is.
1883#[derive(Clone, Debug, PartialEq, Eq)]
1884pub enum StrippedStringPart<N: TreeNode = SyntaxNode> {
1885    /// A textual part of the string.
1886    Text(String),
1887    /// A placeholder encountered in the string.
1888    Placeholder(Placeholder<N>),
1889}
1890
1891/// Unescapes a multiline string.
1892///
1893/// This unescapes both line continuations and `\>` sequences.
1894fn unescape_multiline_string(s: &str) -> String {
1895    let mut result = String::new();
1896    let mut chars = s.chars().peekable();
1897    while let Some(c) = chars.next() {
1898        match c {
1899            '\\' => match chars.peek() {
1900                Some('\r') => {
1901                    chars.next();
1902                    if chars.peek() == Some(&'\n') {
1903                        chars.next();
1904                        while let Some(&next) = chars.peek() {
1905                            if next == ' ' || next == '\t' {
1906                                chars.next();
1907                                continue;
1908                            }
1909
1910                            break;
1911                        }
1912                    } else {
1913                        result.push_str("\\\r");
1914                    }
1915                }
1916                Some('\n') => {
1917                    chars.next();
1918                    while let Some(&next) = chars.peek() {
1919                        if next == ' ' || next == '\t' {
1920                            chars.next();
1921                            continue;
1922                        }
1923
1924                        break;
1925                    }
1926                }
1927                Some('\\') | Some('>') | Some('~') | Some('$') => {
1928                    result.push(chars.next().unwrap());
1929                }
1930                _ => {
1931                    result.push('\\');
1932                }
1933            },
1934            _ => {
1935                result.push(c);
1936            }
1937        }
1938    }
1939    result
1940}
1941
1942/// Represents text of a [`LiteralString`] that contains no placeholders.
1943#[derive(Clone, Debug, PartialEq, Eq)]
1944pub enum LiteralStringText<T: TreeToken = SyntaxToken> {
1945    /// The entire string literal is represented with a single token.
1946    Token(StringText<T>),
1947    /// The string literal is empty.
1948    Empty,
1949}
1950
1951impl<T: TreeToken> LiteralStringText<T> {
1952    /// Gets the text of the literal string.
1953    pub fn text(&self) -> &str {
1954        match self {
1955            Self::Token(token) => token.text(),
1956            Self::Empty => "",
1957        }
1958    }
1959
1960    /// Unescapes the literal string text to the given buffer.
1961    ///
1962    /// If the string text contains invalid escape sequences, they are left
1963    /// as-is.
1964    pub fn unescape_to(&self, buffer: &mut String) {
1965        if let Self::Token(token) = self {
1966            token.unescape_to(buffer);
1967        }
1968    }
1969}
1970
1971/// Represents a literal string.
1972#[derive(Clone, Debug, PartialEq, Eq)]
1973pub struct LiteralString<N: TreeNode = SyntaxNode>(pub(super) N);
1974
1975impl<N: TreeNode> LiteralString<N> {
1976    /// Gets the kind of the string literal.
1977    pub fn kind(&self) -> LiteralStringKind {
1978        self.0
1979            .children_with_tokens()
1980            .find_map(|c| {
1981                c.into_token().and_then(|t| match t.kind() {
1982                    SyntaxKind::SingleQuote => Some(LiteralStringKind::SingleQuoted),
1983                    SyntaxKind::DoubleQuote => Some(LiteralStringKind::DoubleQuoted),
1984                    SyntaxKind::OpenHeredoc => Some(LiteralStringKind::Multiline),
1985                    _ => None,
1986                })
1987            })
1988            .expect("string is missing opening token")
1989    }
1990
1991    /// Determines if the literal is the empty string.
1992    pub fn is_empty(&self) -> bool {
1993        self.0
1994            .children_with_tokens()
1995            .filter_map(StringPart::cast)
1996            .next()
1997            .is_none()
1998    }
1999
2000    /// Gets the parts of the string.
2001    ///
2002    /// A part may be literal text or an interpolated expression.
2003    pub fn parts(&self) -> impl Iterator<Item = StringPart<N>> + use<'_, N> {
2004        self.0.children_with_tokens().filter_map(StringPart::cast)
2005    }
2006
2007    /// Gets the string text as [`LiteralStringText`] if the string is not
2008    /// interpolated (i.e. has no placeholders).
2009    pub fn text(&self) -> Option<LiteralStringText<N::Token>> {
2010        let mut parts = self.parts();
2011        match parts.next() {
2012            Some(StringPart::Text(part)) if parts.next().is_none() => {
2013                Some(LiteralStringText::Token(part))
2014            }
2015            Some(_) => None,
2016            None => Some(LiteralStringText::Empty),
2017        }
2018    }
2019
2020    /// Strips leading whitespace from a multi-line string.
2021    ///
2022    /// This function will remove leading and trailing whitespace and handle
2023    /// unescaping the string.
2024    ///
2025    /// Returns `None` if not a multi-line string.
2026    pub fn strip_whitespace(&self) -> Option<Vec<StrippedStringPart<N>>> {
2027        if self.kind() != LiteralStringKind::Multiline {
2028            return None;
2029        }
2030
2031        // Unescape each line
2032        let mut result = Vec::new();
2033        for part in self.parts() {
2034            match part {
2035                StringPart::Text(text) => {
2036                    result.push(StrippedStringPart::Text(unescape_multiline_string(
2037                        text.text(),
2038                    )));
2039                }
2040                StringPart::Placeholder(placeholder) => {
2041                    result.push(StrippedStringPart::Placeholder(placeholder));
2042                }
2043            }
2044        }
2045
2046        // Trim the first line
2047        let mut whole_first_line_trimmed = false;
2048        if let Some(StrippedStringPart::Text(text)) = result.first_mut() {
2049            let end_of_first_line = text.find('\n').map(|p| p + 1).unwrap_or(text.len());
2050            let line = &text[..end_of_first_line];
2051            let len = line.len() - line.trim_start().len();
2052            whole_first_line_trimmed = len == line.len();
2053            text.replace_range(..len, "");
2054        }
2055
2056        // Trim the last line
2057        if let Some(StrippedStringPart::Text(text)) = result.last_mut() {
2058            if let Some(index) = text.rfind(|c| !matches!(c, ' ' | '\t')) {
2059                text.truncate(index + 1);
2060            } else {
2061                text.clear();
2062            }
2063
2064            if text.ends_with('\n') {
2065                text.pop();
2066            }
2067
2068            if text.ends_with('\r') {
2069                text.pop();
2070            }
2071        }
2072
2073        // Now that the string has been unescaped and the first and last lines trimmed,
2074        // we can detect any leading whitespace and trim it.
2075        let mut leading_whitespace = usize::MAX;
2076        let mut parsing_leading_whitespace = true;
2077        let mut iter = result.iter().peekable();
2078        while let Some(part) = iter.next() {
2079            match part {
2080                StrippedStringPart::Text(text) => {
2081                    for (i, line) in text.lines().enumerate() {
2082                        if i > 0 {
2083                            parsing_leading_whitespace = true;
2084                        }
2085
2086                        if parsing_leading_whitespace {
2087                            let mut ws_count = 0;
2088                            for c in line.chars() {
2089                                if c == ' ' || c == '\t' {
2090                                    ws_count += 1;
2091                                } else {
2092                                    break;
2093                                }
2094                            }
2095
2096                            // Don't include blank lines in determining leading whitespace, unless
2097                            // the next part is a placeholder
2098                            if ws_count == line.len()
2099                                && iter
2100                                    .peek()
2101                                    .map(|p| !matches!(p, StrippedStringPart::Placeholder(_)))
2102                                    .unwrap_or(true)
2103                            {
2104                                continue;
2105                            }
2106
2107                            leading_whitespace = leading_whitespace.min(ws_count);
2108                        }
2109                    }
2110                }
2111                StrippedStringPart::Placeholder(_) => {
2112                    parsing_leading_whitespace = false;
2113                }
2114            }
2115        }
2116
2117        // Finally, strip the leading whitespace on each line
2118        // This is done in place using the `replace_range` method; the method will
2119        // internally do moves without allocations
2120        let mut strip_leading_whitespace = whole_first_line_trimmed;
2121        for part in &mut result {
2122            match part {
2123                StrippedStringPart::Text(text) => {
2124                    let mut offset = 0;
2125                    while let Some(next) = text[offset..].find('\n') {
2126                        let next = next + offset;
2127                        if offset > 0 {
2128                            strip_leading_whitespace = true;
2129                        }
2130
2131                        if !strip_leading_whitespace {
2132                            offset = next + 1;
2133                            continue;
2134                        }
2135
2136                        let line = &text[offset..next];
2137                        let line = line.strip_suffix('\r').unwrap_or(line);
2138                        let len = line.len().min(leading_whitespace);
2139                        text.replace_range(offset..offset + len, "");
2140                        offset = next + 1 - len;
2141                    }
2142
2143                    // Replace any remaining text
2144                    if strip_leading_whitespace || offset > 0 {
2145                        let line = &text[offset..];
2146                        let line = line.strip_suffix('\r').unwrap_or(line);
2147                        let len = line.len().min(leading_whitespace);
2148                        text.replace_range(offset..offset + len, "");
2149                    }
2150                }
2151                StrippedStringPart::Placeholder(_) => {
2152                    strip_leading_whitespace = false;
2153                }
2154            }
2155        }
2156
2157        Some(result)
2158    }
2159}
2160
2161impl<N: TreeNode> AstNode<N> for LiteralString<N> {
2162    fn can_cast(kind: SyntaxKind) -> bool {
2163        kind == SyntaxKind::LiteralStringNode
2164    }
2165
2166    fn cast(inner: N) -> Option<Self> {
2167        match inner.kind() {
2168            SyntaxKind::LiteralStringNode => Some(Self(inner)),
2169            _ => None,
2170        }
2171    }
2172
2173    fn inner(&self) -> &N {
2174        &self.0
2175    }
2176}
2177
2178/// Represents a part of a string.
2179#[derive(Clone, Debug, PartialEq, Eq)]
2180pub enum StringPart<N: TreeNode = SyntaxNode> {
2181    /// A textual part of the string.
2182    Text(StringText<N::Token>),
2183    /// A placeholder encountered in the string.
2184    Placeholder(Placeholder<N>),
2185}
2186
2187impl<N: TreeNode> StringPart<N> {
2188    /// Unwraps the string part into text.
2189    ///
2190    /// # Panics
2191    ///
2192    /// Panics if the string part is not text.
2193    pub fn unwrap_text(self) -> StringText<N::Token> {
2194        match self {
2195            Self::Text(text) => text,
2196            _ => panic!("not string text"),
2197        }
2198    }
2199
2200    /// Unwraps the string part into a placeholder.
2201    ///
2202    /// # Panics
2203    ///
2204    /// Panics if the string part is not a placeholder.
2205    pub fn unwrap_placeholder(self) -> Placeholder<N> {
2206        match self {
2207            Self::Placeholder(p) => p,
2208            _ => panic!("not a placeholder"),
2209        }
2210    }
2211
2212    /// Casts the given syntax element to a string part.
2213    fn cast(element: NodeOrToken<N, N::Token>) -> Option<Self> {
2214        match element {
2215            NodeOrToken::Node(n) => Some(Self::Placeholder(Placeholder::cast(n)?)),
2216            NodeOrToken::Token(t) => Some(Self::Text(StringText::cast(t)?)),
2217        }
2218    }
2219}
2220
2221/// Represents a textual part of a string.
2222#[derive(Clone, Debug, PartialEq, Eq)]
2223pub struct StringText<T: TreeToken = SyntaxToken>(T);
2224
2225impl<T: TreeToken> StringText<T> {
2226    /// Unescapes the string text to the given buffer.
2227    ///
2228    /// If the string text contains invalid escape sequences, they are left
2229    /// as-is.
2230    pub fn unescape_to(&self, buffer: &mut String) {
2231        let text = self.0.text();
2232        let lexer = EscapeToken::lexer(text).spanned();
2233        for (token, span) in lexer {
2234            match token.expect("should lex") {
2235                EscapeToken::Valid => {
2236                    match &text[span] {
2237                        r"\\" => buffer.push('\\'),
2238                        r"\n" => buffer.push('\n'),
2239                        r"\r" => buffer.push('\r'),
2240                        r"\t" => buffer.push('\t'),
2241                        r"\'" => buffer.push('\''),
2242                        r#"\""# => buffer.push('"'),
2243                        r"\~" => buffer.push('~'),
2244                        r"\$" => buffer.push('$'),
2245                        _ => unreachable!("unexpected escape token"),
2246                    }
2247                    continue;
2248                }
2249                EscapeToken::ValidOctal => {
2250                    if let Some(c) = char::from_u32(
2251                        u32::from_str_radix(&text[span.start + 1..span.end], 8)
2252                            .expect("should be a valid octal number"),
2253                    ) {
2254                        buffer.push(c);
2255                        continue;
2256                    }
2257                }
2258                EscapeToken::ValidHex => {
2259                    buffer.push(
2260                        u8::from_str_radix(&text[span.start + 2..span.end], 16)
2261                            .expect("should be a valid hex number") as char,
2262                    );
2263                    continue;
2264                }
2265                EscapeToken::ValidUnicode => {
2266                    if let Some(c) = char::from_u32(
2267                        u32::from_str_radix(&text[span.start + 2..span.end], 16)
2268                            .expect("should be a valid hex number"),
2269                    ) {
2270                        buffer.push(c);
2271                        continue;
2272                    }
2273                }
2274                _ => {
2275                    // Write the token to the buffer below
2276                }
2277            }
2278
2279            buffer.push_str(&text[span]);
2280        }
2281    }
2282}
2283
2284impl<T: TreeToken> AstToken<T> for StringText<T> {
2285    fn can_cast(kind: SyntaxKind) -> bool {
2286        kind == SyntaxKind::LiteralStringText
2287    }
2288
2289    fn cast(inner: T) -> Option<Self> {
2290        match inner.kind() {
2291            SyntaxKind::LiteralStringText => Some(Self(inner)),
2292            _ => None,
2293        }
2294    }
2295
2296    fn inner(&self) -> &T {
2297        &self.0
2298    }
2299}
2300
2301/// Represents a placeholder in a string or command.
2302#[derive(Clone, Debug, PartialEq, Eq)]
2303pub struct Placeholder<N: TreeNode = SyntaxNode>(N);
2304
2305impl<N: TreeNode> Placeholder<N> {
2306    /// Returns whether or not placeholder has a tilde (`~`) opening.
2307    ///
2308    /// If this method returns false, the opening was a dollar sign (`$`).
2309    pub fn has_tilde(&self) -> bool {
2310        self.0
2311            .children_with_tokens()
2312            .find_map(|c| {
2313                c.into_token().and_then(|t| match t.kind() {
2314                    SyntaxKind::PlaceholderOpen => Some(t.text().starts_with('~')),
2315                    _ => None,
2316                })
2317            })
2318            .expect("should have a placeholder open token")
2319    }
2320
2321    /// Returns the placeholder open token (`${` or `~{`).
2322    pub fn open(&self) -> N::Token {
2323        self.0
2324            .children_with_tokens()
2325            .find_map(|c| {
2326                c.into_token()
2327                    .and_then(|t| (t.kind() == SyntaxKind::PlaceholderOpen).then_some(t))
2328            })
2329            .expect("should have a placeholder open token")
2330    }
2331
2332    /// Returns the placeholder close token (`}`).
2333    pub fn close(&self) -> N::Token {
2334        self.0
2335            .children_with_tokens()
2336            .find_map(|c| {
2337                c.into_token()
2338                    .and_then(|t| (t.kind() == SyntaxKind::CloseBrace).then_some(t))
2339            })
2340            .expect("should have a close brace token")
2341    }
2342
2343    /// Gets the option for the placeholder.
2344    pub fn option(&self) -> Option<PlaceholderOption<N>> {
2345        self.child()
2346    }
2347
2348    /// Gets the placeholder expression.
2349    pub fn expr(&self) -> Expr<N> {
2350        Expr::child(&self.0).expect("placeholder should have an expression")
2351    }
2352}
2353
2354impl<N: TreeNode> AstNode<N> for Placeholder<N> {
2355    fn can_cast(kind: SyntaxKind) -> bool {
2356        kind == SyntaxKind::PlaceholderNode
2357    }
2358
2359    fn cast(inner: N) -> Option<Self> {
2360        match inner.kind() {
2361            SyntaxKind::PlaceholderNode => Some(Self(inner)),
2362            _ => None,
2363        }
2364    }
2365
2366    fn inner(&self) -> &N {
2367        &self.0
2368    }
2369}
2370
2371/// Represents a placeholder option.
2372#[derive(Clone, Debug, PartialEq, Eq)]
2373pub enum PlaceholderOption<N: TreeNode = SyntaxNode> {
2374    /// A `sep` option for specifying a delimiter for formatting arrays.
2375    Sep(SepOption<N>),
2376    /// A `default` option for substituting a default value for an undefined
2377    /// expression.
2378    Default(DefaultOption<N>),
2379    /// A `true/false` option for substituting a value depending on whether a
2380    /// boolean expression is true or false.
2381    TrueFalse(TrueFalseOption<N>),
2382}
2383
2384impl<N: TreeNode> PlaceholderOption<N> {
2385    /// Attempts to get a reference to the inner [`SepOption`].
2386    ///
2387    /// * If `self` is a [`PlaceholderOption::Sep`], then a reference to the
2388    ///   inner [`SepOption`] is returned wrapped in [`Some`].
2389    /// * Else, [`None`] is returned.
2390    pub fn as_sep(&self) -> Option<&SepOption<N>> {
2391        match self {
2392            Self::Sep(o) => Some(o),
2393            _ => None,
2394        }
2395    }
2396
2397    /// Consumes `self` and attempts to return the inner [`SepOption`].
2398    ///
2399    /// * If `self` is a [`PlaceholderOption::Sep`], then the inner
2400    ///   [`SepOption`] is returned wrapped in [`Some`].
2401    /// * Else, [`None`] is returned.
2402    pub fn into_sep(self) -> Option<SepOption<N>> {
2403        match self {
2404            Self::Sep(o) => Some(o),
2405            _ => None,
2406        }
2407    }
2408
2409    /// Unwraps the option into a separator option.
2410    ///
2411    /// # Panics
2412    ///
2413    /// Panics if the option is not a separator option.
2414    pub fn unwrap_sep(self) -> SepOption<N> {
2415        match self {
2416            Self::Sep(o) => o,
2417            _ => panic!("not a separator option"),
2418        }
2419    }
2420
2421    /// Attempts to get a reference to the inner [`DefaultOption`].
2422    ///
2423    /// * If `self` is a [`PlaceholderOption::Default`], then a reference to the
2424    ///   inner [`DefaultOption`] is returned wrapped in [`Some`].
2425    /// * Else, [`None`] is returned.
2426    pub fn as_default(&self) -> Option<&DefaultOption<N>> {
2427        match self {
2428            Self::Default(o) => Some(o),
2429            _ => None,
2430        }
2431    }
2432
2433    /// Consumes `self` and attempts to return the inner [`DefaultOption`].
2434    ///
2435    /// * If `self` is a [`PlaceholderOption::Default`], then the inner
2436    ///   [`DefaultOption`] is returned wrapped in [`Some`].
2437    /// * Else, [`None`] is returned.
2438    pub fn into_default(self) -> Option<DefaultOption<N>> {
2439        match self {
2440            Self::Default(o) => Some(o),
2441            _ => None,
2442        }
2443    }
2444
2445    /// Unwraps the option into a default option.
2446    ///
2447    /// # Panics
2448    ///
2449    /// Panics if the option is not a default option.
2450    pub fn unwrap_default(self) -> DefaultOption<N> {
2451        match self {
2452            Self::Default(o) => o,
2453            _ => panic!("not a default option"),
2454        }
2455    }
2456
2457    /// Attempts to get a reference to the inner [`TrueFalseOption`].
2458    ///
2459    /// * If `self` is a [`PlaceholderOption::TrueFalse`], then a reference to
2460    ///   the inner [`TrueFalseOption`] is returned wrapped in [`Some`].
2461    /// * Else, [`None`] is returned.
2462    pub fn as_true_false(&self) -> Option<&TrueFalseOption<N>> {
2463        match self {
2464            Self::TrueFalse(o) => Some(o),
2465            _ => None,
2466        }
2467    }
2468
2469    /// Consumes `self` and attempts to return the inner [`TrueFalseOption`].
2470    ///
2471    /// * If `self` is a [`PlaceholderOption::TrueFalse`], then the inner
2472    ///   [`TrueFalseOption`] is returned wrapped in [`Some`].
2473    /// * Else, [`None`] is returned.
2474    pub fn into_true_false(self) -> Option<TrueFalseOption<N>> {
2475        match self {
2476            Self::TrueFalse(o) => Some(o),
2477            _ => None,
2478        }
2479    }
2480
2481    /// Unwraps the option into a true/false option.
2482    ///
2483    /// # Panics
2484    ///
2485    /// Panics if the option is not a true/false option.
2486    pub fn unwrap_true_false(self) -> TrueFalseOption<N> {
2487        match self {
2488            Self::TrueFalse(o) => o,
2489            _ => panic!("not a true/false option"),
2490        }
2491    }
2492
2493    /// Finds the first child that can be cast to a [`PlaceholderOption`].
2494    pub fn child(node: &N) -> Option<Self> {
2495        node.children().find_map(Self::cast)
2496    }
2497
2498    /// Finds all children that can be cast to a [`PlaceholderOption`].
2499    pub fn children(node: &N) -> impl Iterator<Item = Self> + use<'_, N> {
2500        node.children().filter_map(Self::cast)
2501    }
2502}
2503
2504impl<N: TreeNode> AstNode<N> for PlaceholderOption<N> {
2505    fn can_cast(kind: SyntaxKind) -> bool {
2506        matches!(
2507            kind,
2508            SyntaxKind::PlaceholderSepOptionNode
2509                | SyntaxKind::PlaceholderDefaultOptionNode
2510                | SyntaxKind::PlaceholderTrueFalseOptionNode
2511        )
2512    }
2513
2514    fn cast(inner: N) -> Option<Self> {
2515        match inner.kind() {
2516            SyntaxKind::PlaceholderSepOptionNode => Some(Self::Sep(SepOption(inner))),
2517            SyntaxKind::PlaceholderDefaultOptionNode => Some(Self::Default(DefaultOption(inner))),
2518            SyntaxKind::PlaceholderTrueFalseOptionNode => {
2519                Some(Self::TrueFalse(TrueFalseOption(inner)))
2520            }
2521            _ => None,
2522        }
2523    }
2524
2525    fn inner(&self) -> &N {
2526        match self {
2527            Self::Sep(s) => &s.0,
2528            Self::Default(d) => &d.0,
2529            Self::TrueFalse(tf) => &tf.0,
2530        }
2531    }
2532}
2533
2534/// Represents a `sep` option for a placeholder.
2535#[derive(Clone, Debug, PartialEq, Eq)]
2536pub struct SepOption<N: TreeNode = SyntaxNode>(N);
2537
2538impl<N: TreeNode> SepOption<N> {
2539    /// Gets the separator to use for formatting an array.
2540    pub fn separator(&self) -> LiteralString<N> {
2541        self.child()
2542            .expect("sep option should have a string literal")
2543    }
2544}
2545
2546impl<N: TreeNode> AstNode<N> for SepOption<N> {
2547    fn can_cast(kind: SyntaxKind) -> bool {
2548        kind == SyntaxKind::PlaceholderSepOptionNode
2549    }
2550
2551    fn cast(inner: N) -> Option<Self> {
2552        match inner.kind() {
2553            SyntaxKind::PlaceholderSepOptionNode => Some(Self(inner)),
2554            _ => None,
2555        }
2556    }
2557
2558    fn inner(&self) -> &N {
2559        &self.0
2560    }
2561}
2562
2563/// Represents a `default` option for a placeholder.
2564#[derive(Clone, Debug, PartialEq, Eq)]
2565pub struct DefaultOption<N: TreeNode = SyntaxNode>(N);
2566
2567impl<N: TreeNode> DefaultOption<N> {
2568    /// Gets the value to use for an undefined expression.
2569    pub fn value(&self) -> LiteralString<N> {
2570        self.child()
2571            .expect("default option should have a string literal")
2572    }
2573}
2574
2575impl<N: TreeNode> AstNode<N> for DefaultOption<N> {
2576    fn can_cast(kind: SyntaxKind) -> bool {
2577        kind == SyntaxKind::PlaceholderDefaultOptionNode
2578    }
2579
2580    fn cast(inner: N) -> Option<Self> {
2581        match inner.kind() {
2582            SyntaxKind::PlaceholderDefaultOptionNode => Some(Self(inner)),
2583            _ => None,
2584        }
2585    }
2586
2587    fn inner(&self) -> &N {
2588        &self.0
2589    }
2590}
2591
2592/// Represents a `true/false` option for a placeholder.
2593#[derive(Clone, Debug, PartialEq, Eq)]
2594pub struct TrueFalseOption<N: TreeNode = SyntaxNode>(N);
2595
2596impl<N: TreeNode> TrueFalseOption<N> {
2597    /// Gets the `true` and `false` values to use for a placeholder
2598    /// expression that evaluates to a boolean.
2599    ///
2600    /// The first value returned is the `true` value and the second
2601    /// value is the `false` value.
2602    pub fn values(&self) -> (LiteralString<N>, LiteralString<N>) {
2603        let mut true_value = None;
2604        let mut false_value = None;
2605        let mut found = None;
2606        let mut children = self.0.children_with_tokens();
2607        for child in children.by_ref() {
2608            match child {
2609                NodeOrToken::Token(t) if t.kind() == SyntaxKind::TrueKeyword => {
2610                    found = Some(true);
2611                }
2612                NodeOrToken::Token(t) if t.kind() == SyntaxKind::FalseKeyword => {
2613                    found = Some(false);
2614                }
2615                NodeOrToken::Node(n) if LiteralString::<N>::can_cast(n.kind()) => {
2616                    if found.expect("should have found true or false") {
2617                        assert!(true_value.is_none(), "multiple true values present");
2618                        true_value = Some(LiteralString(n));
2619                    } else {
2620                        assert!(false_value.is_none(), "multiple false values present");
2621                        false_value = Some(LiteralString(n));
2622                    }
2623
2624                    if true_value.is_some() && false_value.is_some() {
2625                        break;
2626                    }
2627                }
2628                _ => continue,
2629            }
2630        }
2631
2632        (
2633            true_value.expect("expected a true value to be present"),
2634            false_value.expect("expected a false value to be present`"),
2635        )
2636    }
2637}
2638
2639impl<N: TreeNode> AstNode<N> for TrueFalseOption<N> {
2640    fn can_cast(kind: SyntaxKind) -> bool {
2641        kind == SyntaxKind::PlaceholderTrueFalseOptionNode
2642    }
2643
2644    fn cast(inner: N) -> Option<Self> {
2645        match inner.kind() {
2646            SyntaxKind::PlaceholderTrueFalseOptionNode => Some(Self(inner)),
2647            _ => None,
2648        }
2649    }
2650
2651    fn inner(&self) -> &N {
2652        &self.0
2653    }
2654}
2655
2656/// Represents a literal array.
2657#[derive(Clone, Debug, PartialEq, Eq)]
2658pub struct LiteralArray<N: TreeNode = SyntaxNode>(N);
2659
2660impl<N: TreeNode> LiteralArray<N> {
2661    /// Gets the elements of the literal array.
2662    pub fn elements(&self) -> impl Iterator<Item = Expr<N>> + use<'_, N> {
2663        Expr::children(&self.0)
2664    }
2665}
2666
2667impl<N: TreeNode> AstNode<N> for LiteralArray<N> {
2668    fn can_cast(kind: SyntaxKind) -> bool {
2669        kind == SyntaxKind::LiteralArrayNode
2670    }
2671
2672    fn cast(inner: N) -> Option<Self> {
2673        match inner.kind() {
2674            SyntaxKind::LiteralArrayNode => Some(Self(inner)),
2675            _ => None,
2676        }
2677    }
2678
2679    fn inner(&self) -> &N {
2680        &self.0
2681    }
2682}
2683
2684/// Represents a literal pair.
2685#[derive(Clone, Debug, PartialEq, Eq)]
2686pub struct LiteralPair<N: TreeNode = SyntaxNode>(N);
2687
2688impl<N: TreeNode> LiteralPair<N> {
2689    /// Gets the first and second expressions in the literal pair.
2690    pub fn exprs(&self) -> (Expr<N>, Expr<N>) {
2691        let mut children = self.0.children().filter_map(Expr::cast);
2692        let left = children.next().expect("pair should have a left expression");
2693        let right = children
2694            .next()
2695            .expect("pair should have a right expression");
2696        (left, right)
2697    }
2698}
2699
2700impl<N: TreeNode> AstNode<N> for LiteralPair<N> {
2701    fn can_cast(kind: SyntaxKind) -> bool {
2702        kind == SyntaxKind::LiteralPairNode
2703    }
2704
2705    fn cast(inner: N) -> Option<Self> {
2706        match inner.kind() {
2707            SyntaxKind::LiteralPairNode => Some(Self(inner)),
2708            _ => None,
2709        }
2710    }
2711
2712    fn inner(&self) -> &N {
2713        &self.0
2714    }
2715}
2716
2717/// Represents a literal map.
2718#[derive(Clone, Debug, PartialEq, Eq)]
2719pub struct LiteralMap<N: TreeNode = SyntaxNode>(N);
2720
2721impl<N: TreeNode> LiteralMap<N> {
2722    /// Gets the items of the literal map.
2723    pub fn items(&self) -> impl Iterator<Item = LiteralMapItem<N>> + use<'_, N> {
2724        self.children()
2725    }
2726}
2727
2728impl<N: TreeNode> AstNode<N> for LiteralMap<N> {
2729    fn can_cast(kind: SyntaxKind) -> bool {
2730        kind == SyntaxKind::LiteralMapNode
2731    }
2732
2733    fn cast(inner: N) -> Option<Self> {
2734        match inner.kind() {
2735            SyntaxKind::LiteralMapNode => Some(Self(inner)),
2736            _ => None,
2737        }
2738    }
2739
2740    fn inner(&self) -> &N {
2741        &self.0
2742    }
2743}
2744
2745/// Represents a literal map item.
2746#[derive(Clone, Debug, PartialEq, Eq)]
2747pub struct LiteralMapItem<N: TreeNode = SyntaxNode>(N);
2748
2749impl<N: TreeNode> LiteralMapItem<N> {
2750    /// Gets the key and the value of the item.
2751    pub fn key_value(&self) -> (Expr<N>, Expr<N>) {
2752        let mut children = Expr::children(&self.0);
2753        let key = children.next().expect("expected a key expression");
2754        let value = children.next().expect("expected a value expression");
2755        (key, value)
2756    }
2757}
2758
2759impl<N: TreeNode> AstNode<N> for LiteralMapItem<N> {
2760    fn can_cast(kind: SyntaxKind) -> bool {
2761        kind == SyntaxKind::LiteralMapItemNode
2762    }
2763
2764    fn cast(inner: N) -> Option<Self> {
2765        match inner.kind() {
2766            SyntaxKind::LiteralMapItemNode => Some(Self(inner)),
2767            _ => None,
2768        }
2769    }
2770
2771    fn inner(&self) -> &N {
2772        &self.0
2773    }
2774}
2775
2776/// Represents a literal object.
2777#[derive(Clone, Debug, PartialEq, Eq)]
2778pub struct LiteralObject<N: TreeNode = SyntaxNode>(N);
2779
2780impl<N: TreeNode> LiteralObject<N> {
2781    /// Gets the items of the literal object.
2782    pub fn items(&self) -> impl Iterator<Item = LiteralObjectItem<N>> + use<'_, N> {
2783        self.children()
2784    }
2785}
2786
2787impl<N: TreeNode> AstNode<N> for LiteralObject<N> {
2788    fn can_cast(kind: SyntaxKind) -> bool {
2789        kind == SyntaxKind::LiteralObjectNode
2790    }
2791
2792    fn cast(inner: N) -> Option<Self> {
2793        match inner.kind() {
2794            SyntaxKind::LiteralObjectNode => Some(Self(inner)),
2795            _ => None,
2796        }
2797    }
2798
2799    fn inner(&self) -> &N {
2800        &self.0
2801    }
2802}
2803
2804/// Gets the name and value of a object or struct literal item.
2805fn name_value<N: TreeNode, T: AstNode<N>>(parent: &T) -> (Ident<N::Token>, Expr<N>) {
2806    let key = parent.token().expect("expected a key token");
2807    let value = Expr::child(parent.inner()).expect("expected a value expression");
2808    (key, value)
2809}
2810
2811/// Represents a literal object item.
2812#[derive(Clone, Debug, PartialEq, Eq)]
2813pub struct LiteralObjectItem<N: TreeNode = SyntaxNode>(N);
2814
2815impl<N: TreeNode> LiteralObjectItem<N> {
2816    /// Gets the name and the value of the item.
2817    pub fn name_value(&self) -> (Ident<N::Token>, Expr<N>) {
2818        name_value(self)
2819    }
2820}
2821
2822impl<N: TreeNode> AstNode<N> for LiteralObjectItem<N> {
2823    fn can_cast(kind: SyntaxKind) -> bool {
2824        kind == SyntaxKind::LiteralObjectItemNode
2825    }
2826
2827    fn cast(inner: N) -> Option<Self> {
2828        match inner.kind() {
2829            SyntaxKind::LiteralObjectItemNode => Some(Self(inner)),
2830            _ => None,
2831        }
2832    }
2833
2834    fn inner(&self) -> &N {
2835        &self.0
2836    }
2837}
2838
2839/// Represents a literal struct.
2840#[derive(Clone, Debug, PartialEq, Eq)]
2841pub struct LiteralStruct<N: TreeNode = SyntaxNode>(N);
2842
2843impl<N: TreeNode> LiteralStruct<N> {
2844    /// Gets the name of the struct.
2845    pub fn name(&self) -> Ident<N::Token> {
2846        self.token().expect("expected the struct to have a name")
2847    }
2848
2849    /// Gets the items of the literal struct.
2850    pub fn items(&self) -> impl Iterator<Item = LiteralStructItem<N>> + use<'_, N> {
2851        self.children()
2852    }
2853}
2854
2855impl<N: TreeNode> AstNode<N> for LiteralStruct<N> {
2856    fn can_cast(kind: SyntaxKind) -> bool {
2857        kind == SyntaxKind::LiteralStructNode
2858    }
2859
2860    fn cast(inner: N) -> Option<Self> {
2861        match inner.kind() {
2862            SyntaxKind::LiteralStructNode => Some(Self(inner)),
2863            _ => None,
2864        }
2865    }
2866
2867    fn inner(&self) -> &N {
2868        &self.0
2869    }
2870}
2871
2872/// Represents a literal struct item.
2873#[derive(Clone, Debug, PartialEq, Eq)]
2874pub struct LiteralStructItem<N: TreeNode = SyntaxNode>(N);
2875
2876impl<N: TreeNode> LiteralStructItem<N> {
2877    /// Gets the name and the value of the item.
2878    pub fn name_value(&self) -> (Ident<N::Token>, Expr<N>) {
2879        name_value(self)
2880    }
2881}
2882
2883impl<N: TreeNode> AstNode<N> for LiteralStructItem<N> {
2884    fn can_cast(kind: SyntaxKind) -> bool {
2885        kind == SyntaxKind::LiteralStructItemNode
2886    }
2887
2888    fn cast(inner: N) -> Option<Self> {
2889        match inner.kind() {
2890            SyntaxKind::LiteralStructItemNode => Some(Self(inner)),
2891            _ => None,
2892        }
2893    }
2894
2895    fn inner(&self) -> &N {
2896        &self.0
2897    }
2898}
2899
2900/// Represents a literal `None`.
2901#[derive(Clone, Debug, PartialEq, Eq)]
2902pub struct LiteralNone<N: TreeNode = SyntaxNode>(N);
2903
2904impl<N: TreeNode> AstNode<N> for LiteralNone<N> {
2905    fn can_cast(kind: SyntaxKind) -> bool {
2906        kind == SyntaxKind::LiteralNoneNode
2907    }
2908
2909    fn cast(inner: N) -> Option<Self> {
2910        match inner.kind() {
2911            SyntaxKind::LiteralNoneNode => Some(Self(inner)),
2912            _ => None,
2913        }
2914    }
2915
2916    fn inner(&self) -> &N {
2917        &self.0
2918    }
2919}
2920
2921/// Represents a literal `hints`.
2922#[derive(Clone, Debug, PartialEq, Eq)]
2923pub struct LiteralHints<N: TreeNode = SyntaxNode>(N);
2924
2925impl<N: TreeNode> LiteralHints<N> {
2926    /// Gets the items of the literal hints.
2927    pub fn items(&self) -> impl Iterator<Item = LiteralHintsItem<N>> + use<'_, N> {
2928        self.children()
2929    }
2930}
2931
2932impl<N: TreeNode> AstNode<N> for LiteralHints<N> {
2933    fn can_cast(kind: SyntaxKind) -> bool {
2934        kind == SyntaxKind::LiteralHintsNode
2935    }
2936
2937    fn cast(inner: N) -> Option<Self> {
2938        match inner.kind() {
2939            SyntaxKind::LiteralHintsNode => Some(Self(inner)),
2940            _ => None,
2941        }
2942    }
2943
2944    fn inner(&self) -> &N {
2945        &self.0
2946    }
2947}
2948
2949/// Represents a literal hints item.
2950#[derive(Clone, Debug, PartialEq, Eq)]
2951pub struct LiteralHintsItem<N: TreeNode = SyntaxNode>(N);
2952
2953impl<N: TreeNode> LiteralHintsItem<N> {
2954    /// Gets the name of the hints item.
2955    pub fn name(&self) -> Ident<N::Token> {
2956        self.token().expect("expected an item name")
2957    }
2958
2959    /// Gets the expression of the hints item.
2960    pub fn expr(&self) -> Expr<N> {
2961        Expr::child(&self.0).expect("expected an item expression")
2962    }
2963}
2964
2965impl<N: TreeNode> AstNode<N> for LiteralHintsItem<N> {
2966    fn can_cast(kind: SyntaxKind) -> bool {
2967        kind == SyntaxKind::LiteralHintsItemNode
2968    }
2969
2970    fn cast(inner: N) -> Option<Self> {
2971        match inner.kind() {
2972            SyntaxKind::LiteralHintsItemNode => Some(Self(inner)),
2973            _ => None,
2974        }
2975    }
2976
2977    fn inner(&self) -> &N {
2978        &self.0
2979    }
2980}
2981
2982/// Represents a literal `input`.
2983#[derive(Clone, Debug, PartialEq, Eq)]
2984pub struct LiteralInput<N: TreeNode = SyntaxNode>(N);
2985
2986impl<N: TreeNode> LiteralInput<N> {
2987    /// Gets the items of the literal input.
2988    pub fn items(&self) -> impl Iterator<Item = LiteralInputItem<N>> + use<'_, N> {
2989        self.children()
2990    }
2991}
2992
2993impl<N: TreeNode> AstNode<N> for LiteralInput<N> {
2994    fn can_cast(kind: SyntaxKind) -> bool {
2995        kind == SyntaxKind::LiteralInputNode
2996    }
2997
2998    fn cast(inner: N) -> Option<Self> {
2999        match inner.kind() {
3000            SyntaxKind::LiteralInputNode => Some(Self(inner)),
3001            _ => None,
3002        }
3003    }
3004
3005    fn inner(&self) -> &N {
3006        &self.0
3007    }
3008}
3009
3010/// Represents a literal input item.
3011#[derive(Clone, Debug, PartialEq, Eq)]
3012pub struct LiteralInputItem<N: TreeNode = SyntaxNode>(N);
3013
3014impl<N: TreeNode> LiteralInputItem<N> {
3015    /// Gets the names of the input item.
3016    ///
3017    /// More than one name indicates a struct member path.
3018    pub fn names(&self) -> impl Iterator<Item = Ident<N::Token>> + use<'_, N> {
3019        self.0
3020            .children_with_tokens()
3021            .filter_map(NodeOrToken::into_token)
3022            .filter_map(Ident::cast)
3023    }
3024
3025    /// Gets the expression of the input item.
3026    pub fn expr(&self) -> Expr<N> {
3027        Expr::child(&self.0).expect("expected an item expression")
3028    }
3029}
3030
3031impl<N: TreeNode> AstNode<N> for LiteralInputItem<N> {
3032    fn can_cast(kind: SyntaxKind) -> bool {
3033        kind == SyntaxKind::LiteralInputItemNode
3034    }
3035
3036    fn cast(inner: N) -> Option<Self> {
3037        match inner.kind() {
3038            SyntaxKind::LiteralInputItemNode => Some(Self(inner)),
3039            _ => None,
3040        }
3041    }
3042
3043    fn inner(&self) -> &N {
3044        &self.0
3045    }
3046}
3047
3048/// Represents a literal `output`.
3049#[derive(Clone, Debug, PartialEq, Eq)]
3050pub struct LiteralOutput<N: TreeNode = SyntaxNode>(N);
3051
3052impl<N: TreeNode> LiteralOutput<N> {
3053    /// Gets the items of the literal output.
3054    pub fn items(&self) -> impl Iterator<Item = LiteralOutputItem<N>> + use<'_, N> {
3055        self.children()
3056    }
3057}
3058
3059impl<N: TreeNode> AstNode<N> for LiteralOutput<N> {
3060    fn can_cast(kind: SyntaxKind) -> bool {
3061        kind == SyntaxKind::LiteralOutputNode
3062    }
3063
3064    fn cast(inner: N) -> Option<Self> {
3065        match inner.kind() {
3066            SyntaxKind::LiteralOutputNode => Some(Self(inner)),
3067            _ => None,
3068        }
3069    }
3070
3071    fn inner(&self) -> &N {
3072        &self.0
3073    }
3074}
3075
3076/// Represents a literal output item.
3077#[derive(Clone, Debug, PartialEq, Eq)]
3078pub struct LiteralOutputItem<N: TreeNode = SyntaxNode>(N);
3079
3080impl<N: TreeNode> LiteralOutputItem<N> {
3081    /// Gets the names of the output item.
3082    ///
3083    /// More than one name indicates a struct member path.
3084    pub fn names(&self) -> impl Iterator<Item = Ident<N::Token>> + use<'_, N> {
3085        self.0
3086            .children_with_tokens()
3087            .filter_map(NodeOrToken::into_token)
3088            .filter_map(Ident::cast)
3089    }
3090
3091    /// Gets the expression of the output item.
3092    pub fn expr(&self) -> Expr<N> {
3093        Expr::child(&self.0).expect("expected an item expression")
3094    }
3095}
3096
3097impl<N: TreeNode> AstNode<N> for LiteralOutputItem<N> {
3098    fn can_cast(kind: SyntaxKind) -> bool {
3099        kind == SyntaxKind::LiteralOutputItemNode
3100    }
3101
3102    fn cast(inner: N) -> Option<Self> {
3103        match inner.kind() {
3104            SyntaxKind::LiteralOutputItemNode => Some(Self(inner)),
3105            _ => None,
3106        }
3107    }
3108
3109    fn inner(&self) -> &N {
3110        &self.0
3111    }
3112}
3113
3114/// Represents a name reference expression.
3115#[derive(Clone, Debug, PartialEq, Eq)]
3116pub struct NameRefExpr<N: TreeNode = SyntaxNode>(N);
3117
3118impl<N: TreeNode> NameRefExpr<N> {
3119    /// Gets the name being referenced.
3120    pub fn name(&self) -> Ident<N::Token> {
3121        self.token().expect("expected a name")
3122    }
3123}
3124
3125impl<N: TreeNode> AstNode<N> for NameRefExpr<N> {
3126    fn can_cast(kind: SyntaxKind) -> bool {
3127        kind == SyntaxKind::NameRefExprNode
3128    }
3129
3130    fn cast(inner: N) -> Option<Self> {
3131        match inner.kind() {
3132            SyntaxKind::NameRefExprNode => Some(Self(inner)),
3133            _ => None,
3134        }
3135    }
3136
3137    fn inner(&self) -> &N {
3138        &self.0
3139    }
3140}
3141
3142/// Represents a parenthesized expression.
3143#[derive(Clone, Debug, PartialEq, Eq)]
3144pub struct ParenthesizedExpr<N: TreeNode = SyntaxNode>(N);
3145
3146impl<N: TreeNode> ParenthesizedExpr<N> {
3147    /// Gets the inner expression.
3148    pub fn expr(&self) -> Expr<N> {
3149        Expr::child(&self.0).expect("expected an inner expression")
3150    }
3151}
3152
3153impl<N: TreeNode> AstNode<N> for ParenthesizedExpr<N> {
3154    fn can_cast(kind: SyntaxKind) -> bool {
3155        kind == SyntaxKind::ParenthesizedExprNode
3156    }
3157
3158    fn cast(inner: N) -> Option<Self> {
3159        match inner.kind() {
3160            SyntaxKind::ParenthesizedExprNode => Some(Self(inner)),
3161            _ => None,
3162        }
3163    }
3164
3165    fn inner(&self) -> &N {
3166        &self.0
3167    }
3168}
3169
3170/// Represents an `if` expression.
3171#[derive(Clone, Debug, PartialEq, Eq)]
3172pub struct IfExpr<N: TreeNode = SyntaxNode>(N);
3173
3174impl<N: TreeNode> IfExpr<N> {
3175    /// Gets the three expressions of the `if` expression
3176    ///
3177    /// The first expression is the conditional.
3178    /// The second expression is the `true` expression.
3179    /// The third expression is the `false` expression.
3180    pub fn exprs(&self) -> (Expr<N>, Expr<N>, Expr<N>) {
3181        let mut children = Expr::children(&self.0);
3182        let conditional = children
3183            .next()
3184            .expect("should have a conditional expression");
3185        let true_expr = children.next().expect("should have a `true` expression");
3186        let false_expr = children.next().expect("should have a `false` expression");
3187        (conditional, true_expr, false_expr)
3188    }
3189}
3190
3191impl<N: TreeNode> AstNode<N> for IfExpr<N> {
3192    fn can_cast(kind: SyntaxKind) -> bool {
3193        kind == SyntaxKind::IfExprNode
3194    }
3195
3196    fn cast(inner: N) -> Option<Self> {
3197        match inner.kind() {
3198            SyntaxKind::IfExprNode => Some(Self(inner)),
3199            _ => None,
3200        }
3201    }
3202
3203    fn inner(&self) -> &N {
3204        &self.0
3205    }
3206}
3207
3208/// Used to declare a prefix expression.
3209macro_rules! prefix_expression {
3210    ($name:ident, $kind:ident, $desc:literal) => {
3211        #[doc = concat!("Represents a ", $desc, " expression.")]
3212        #[derive(Clone, Debug, PartialEq, Eq)]
3213        pub struct $name<N: TreeNode = SyntaxNode>(N);
3214
3215        impl<N: TreeNode> $name<N> {
3216            /// Gets the operand expression.
3217            pub fn operand(&self) -> Expr<N> {
3218                Expr::child(&self.0).expect("expected an operand expression")
3219            }
3220        }
3221
3222        impl<N: TreeNode> AstNode<N> for $name<N> {
3223            fn can_cast(kind: SyntaxKind) -> bool {
3224                kind == SyntaxKind::$kind
3225            }
3226
3227            fn cast(inner: N) -> Option<Self> {
3228                match inner.kind() {
3229                    SyntaxKind::$kind => Some(Self(inner)),
3230                    _ => None,
3231                }
3232            }
3233
3234            fn inner(&self) -> &N {
3235                &self.0
3236            }
3237        }
3238    };
3239}
3240
3241/// Used to declare an infix expression.
3242macro_rules! infix_expression {
3243    ($name:ident, $kind:ident, $desc:literal) => {
3244        #[doc = concat!("Represents a ", $desc, " expression.")]
3245        #[derive(Clone, Debug, PartialEq, Eq)]
3246        pub struct $name<N: TreeNode = SyntaxNode>(N);
3247
3248        impl<N: TreeNode> $name<N> {
3249            /// Gets the operands of the expression.
3250            pub fn operands(&self) -> (Expr<N>, Expr<N>) {
3251                let mut children = Expr::children(&self.0);
3252                let lhs = children.next().expect("expected a lhs expression");
3253                let rhs = children.next().expect("expected a rhs expression");
3254                (lhs, rhs)
3255            }
3256        }
3257
3258        impl<N: TreeNode> AstNode<N> for $name<N> {
3259            fn can_cast(kind: SyntaxKind) -> bool {
3260                kind == SyntaxKind::$kind
3261            }
3262
3263            fn cast(inner: N) -> Option<Self> {
3264                match inner.kind() {
3265                    SyntaxKind::$kind => Some(Self(inner)),
3266                    _ => None,
3267                }
3268            }
3269
3270            fn inner(&self) -> &N {
3271                &self.0
3272            }
3273        }
3274    };
3275}
3276
3277prefix_expression!(LogicalNotExpr, LogicalNotExprNode, "logical `not`");
3278prefix_expression!(NegationExpr, NegationExprNode, "negation");
3279infix_expression!(LogicalOrExpr, LogicalOrExprNode, "logical `or`");
3280infix_expression!(LogicalAndExpr, LogicalAndExprNode, "logical `and`");
3281infix_expression!(EqualityExpr, EqualityExprNode, "equality");
3282infix_expression!(InequalityExpr, InequalityExprNode, "inequality");
3283infix_expression!(LessExpr, LessExprNode, "less than");
3284infix_expression!(LessEqualExpr, LessEqualExprNode, "less than or equal to");
3285infix_expression!(GreaterExpr, GreaterExprNode, "greater than");
3286infix_expression!(
3287    GreaterEqualExpr,
3288    GreaterEqualExprNode,
3289    "greater than or equal to"
3290);
3291infix_expression!(AdditionExpr, AdditionExprNode, "addition");
3292infix_expression!(SubtractionExpr, SubtractionExprNode, "substitution");
3293infix_expression!(MultiplicationExpr, MultiplicationExprNode, "multiplication");
3294infix_expression!(DivisionExpr, DivisionExprNode, "division");
3295infix_expression!(ModuloExpr, ModuloExprNode, "modulo");
3296infix_expression!(ExponentiationExpr, ExponentiationExprNode, "exponentiation");
3297
3298/// Represents a call expression.
3299#[derive(Clone, Debug, PartialEq, Eq)]
3300pub struct CallExpr<N: TreeNode = SyntaxNode>(N);
3301
3302impl<N: TreeNode> CallExpr<N> {
3303    /// Gets the call target expression.
3304    pub fn target(&self) -> Ident<N::Token> {
3305        self.token().expect("expected a target identifier")
3306    }
3307
3308    /// Gets the call arguments.
3309    pub fn arguments(&self) -> impl Iterator<Item = Expr<N>> + use<'_, N> {
3310        Expr::children(&self.0)
3311    }
3312}
3313
3314impl<N: TreeNode> AstNode<N> for CallExpr<N> {
3315    fn can_cast(kind: SyntaxKind) -> bool {
3316        kind == SyntaxKind::CallExprNode
3317    }
3318
3319    fn cast(inner: N) -> Option<Self> {
3320        match inner.kind() {
3321            SyntaxKind::CallExprNode => Some(Self(inner)),
3322            _ => None,
3323        }
3324    }
3325
3326    fn inner(&self) -> &N {
3327        &self.0
3328    }
3329}
3330
3331/// Represents an index expression.
3332#[derive(Clone, Debug, PartialEq, Eq)]
3333pub struct IndexExpr<N: TreeNode = SyntaxNode>(N);
3334
3335impl<N: TreeNode> IndexExpr<N> {
3336    /// Gets the operand and the index expressions.
3337    ///
3338    /// The first is the operand expression.
3339    /// The second is the index expression.
3340    pub fn operands(&self) -> (Expr<N>, Expr<N>) {
3341        let mut children = Expr::children(&self.0);
3342        let operand = children.next().expect("expected an operand expression");
3343        let index = children.next().expect("expected an index expression");
3344        (operand, index)
3345    }
3346}
3347
3348impl<N: TreeNode> AstNode<N> for IndexExpr<N> {
3349    fn can_cast(kind: SyntaxKind) -> bool {
3350        kind == SyntaxKind::IndexExprNode
3351    }
3352
3353    fn cast(inner: N) -> Option<Self> {
3354        match inner.kind() {
3355            SyntaxKind::IndexExprNode => Some(Self(inner)),
3356            _ => None,
3357        }
3358    }
3359
3360    fn inner(&self) -> &N {
3361        &self.0
3362    }
3363}
3364
3365/// Represents an access expression.
3366#[derive(Clone, Debug, PartialEq, Eq)]
3367pub struct AccessExpr<N: TreeNode = SyntaxNode>(N);
3368
3369impl<N: TreeNode> AccessExpr<N> {
3370    /// Gets the operand and the name of the access.
3371    ///
3372    /// The first is the operand expression.
3373    /// The second is the member name.
3374    pub fn operands(&self) -> (Expr<N>, Ident<N::Token>) {
3375        let operand = Expr::child(&self.0).expect("expected an operand expression");
3376        let name = Ident::cast(self.0.last_token().expect("expected a last token"))
3377            .expect("expected an ident token");
3378        (operand, name)
3379    }
3380
3381    /// Whether this is an access on the `task` variable.
3382    pub fn is_task_access(&self) -> bool {
3383        let (target, _) = self.operands();
3384        if let Expr::NameRef(expr) = target.strip_parenthesized()
3385            && expr.name().text() == "task"
3386        {
3387            return true;
3388        }
3389
3390        false
3391    }
3392}
3393
3394impl<N: TreeNode> AstNode<N> for AccessExpr<N> {
3395    fn can_cast(kind: SyntaxKind) -> bool {
3396        kind == SyntaxKind::AccessExprNode
3397    }
3398
3399    fn cast(inner: N) -> Option<Self> {
3400        match inner.kind() {
3401            SyntaxKind::AccessExprNode => Some(Self(inner)),
3402            _ => None,
3403        }
3404    }
3405
3406    fn inner(&self) -> &N {
3407        &self.0
3408    }
3409}
3410
3411#[cfg(test)]
3412mod test {
3413    use approx::assert_relative_eq;
3414    use pretty_assertions::assert_eq;
3415
3416    use super::*;
3417    use crate::Document;
3418
3419    #[test]
3420    fn literal_booleans() {
3421        let (document, diagnostics) = Document::parse(
3422            r#"
3423version 1.1
3424
3425task test {
3426    Boolean a = true
3427    Boolean b = false
3428}
3429"#,
3430            None,
3431        );
3432
3433        assert!(diagnostics.is_empty());
3434        let ast = document.ast();
3435        let ast = ast.as_v1().expect("should be a V1 AST");
3436        let tasks: Vec<_> = ast.tasks().collect();
3437        assert_eq!(tasks.len(), 1);
3438        assert_eq!(tasks[0].name().text(), "test");
3439
3440        // Task declarations
3441        let decls: Vec<_> = tasks[0].declarations().collect();
3442        assert_eq!(decls.len(), 2);
3443
3444        // First declaration
3445        assert_eq!(decls[0].ty().to_string(), "Boolean");
3446        assert_eq!(decls[0].name().text(), "a");
3447        assert!(decls[0].expr().unwrap_literal().unwrap_boolean().value());
3448
3449        // Second declaration
3450        assert_eq!(decls[1].ty().to_string(), "Boolean");
3451        assert_eq!(decls[1].name().text(), "b");
3452        assert!(!decls[1].expr().unwrap_literal().unwrap_boolean().value());
3453    }
3454
3455    #[test]
3456    fn literal_integer() {
3457        let (document, diagnostics) = Document::parse(
3458            r#"
3459version 1.1
3460
3461task test {
3462    Int a = 0
3463    Int b = 1234
3464    Int c = 01234
3465    Int d = 0x1234
3466    Int e = 0XF
3467    Int f = 9223372036854775807
3468    Int g = 9223372036854775808
3469    Int h = 9223372036854775809
3470}
3471"#,
3472            None,
3473        );
3474
3475        assert!(diagnostics.is_empty());
3476        let ast = document.ast();
3477        let ast = ast.as_v1().expect("should be a V1 AST");
3478        let tasks: Vec<_> = ast.tasks().collect();
3479        assert_eq!(tasks.len(), 1);
3480        assert_eq!(tasks[0].name().text(), "test");
3481
3482        // Task declarations
3483        let decls: Vec<_> = tasks[0].declarations().collect();
3484        assert_eq!(decls.len(), 8);
3485
3486        // First declaration
3487        assert_eq!(decls[0].ty().to_string(), "Int");
3488        assert_eq!(decls[0].name().text(), "a");
3489        assert_eq!(
3490            decls[0]
3491                .expr()
3492                .unwrap_literal()
3493                .unwrap_integer()
3494                .value()
3495                .unwrap(),
3496            0
3497        );
3498
3499        // Second declaration
3500        assert_eq!(decls[1].ty().to_string(), "Int");
3501        assert_eq!(decls[1].name().text(), "b");
3502        assert_eq!(
3503            decls[1]
3504                .expr()
3505                .unwrap_literal()
3506                .unwrap_integer()
3507                .value()
3508                .unwrap(),
3509            1234
3510        );
3511
3512        // Third declaration
3513        assert_eq!(decls[2].ty().to_string(), "Int");
3514        assert_eq!(decls[2].name().text(), "c");
3515        assert_eq!(
3516            decls[2]
3517                .expr()
3518                .unwrap_literal()
3519                .unwrap_integer()
3520                .value()
3521                .unwrap(),
3522            668
3523        );
3524
3525        // Fourth declaration
3526        assert_eq!(decls[3].ty().to_string(), "Int");
3527        assert_eq!(decls[3].name().text(), "d");
3528        assert_eq!(
3529            decls[3]
3530                .expr()
3531                .unwrap_literal()
3532                .unwrap_integer()
3533                .value()
3534                .unwrap(),
3535            4660
3536        );
3537
3538        // Fifth declaration
3539        assert_eq!(decls[4].ty().to_string(), "Int");
3540        assert_eq!(decls[4].name().text(), "e");
3541        assert_eq!(
3542            decls[4]
3543                .expr()
3544                .unwrap_literal()
3545                .unwrap_integer()
3546                .value()
3547                .unwrap(),
3548            15
3549        );
3550
3551        // Sixth declaration
3552        assert_eq!(decls[5].ty().to_string(), "Int");
3553        assert_eq!(decls[5].name().text(), "f");
3554        assert_eq!(
3555            decls[5]
3556                .expr()
3557                .unwrap_literal()
3558                .unwrap_integer()
3559                .value()
3560                .unwrap(),
3561            9223372036854775807
3562        );
3563
3564        // Seventh declaration
3565        assert_eq!(decls[6].ty().to_string(), "Int");
3566        assert_eq!(decls[6].name().text(), "g");
3567        assert!(
3568            decls[6]
3569                .expr()
3570                .unwrap_literal()
3571                .unwrap_integer()
3572                .value()
3573                .is_none(),
3574        );
3575
3576        // Eighth declaration
3577        assert_eq!(decls[7].ty().to_string(), "Int");
3578        assert_eq!(decls[7].name().text(), "h");
3579        assert!(
3580            decls[7]
3581                .expr()
3582                .unwrap_literal()
3583                .unwrap_integer()
3584                .value()
3585                .is_none()
3586        );
3587    }
3588
3589    #[test]
3590    fn literal_float() {
3591        let (document, diagnostics) = Document::parse(
3592            r#"
3593version 1.1
3594
3595task test {
3596    Float a = 0.
3597    Float b = 0.0
3598    Float c = 1234.1234
3599    Float d = 123e123
3600    Float e = 0.1234
3601    Float f = 10.
3602    Float g = .2
3603    Float h = 1234.1234e1234
3604}
3605"#,
3606            None,
3607        );
3608
3609        assert!(diagnostics.is_empty());
3610        let ast = document.ast();
3611        let ast = ast.as_v1().expect("should be a V1 AST");
3612        let tasks: Vec<_> = ast.tasks().collect();
3613        assert_eq!(tasks.len(), 1);
3614        assert_eq!(tasks[0].name().text(), "test");
3615
3616        // Task declarations
3617        let decls: Vec<_> = tasks[0].declarations().collect();
3618        assert_eq!(decls.len(), 8);
3619
3620        // First declaration
3621        assert_eq!(decls[0].ty().to_string(), "Float");
3622        assert_eq!(decls[0].name().text(), "a");
3623        assert_relative_eq!(
3624            decls[0]
3625                .expr()
3626                .unwrap_literal()
3627                .unwrap_float()
3628                .value()
3629                .unwrap(),
3630            0.0
3631        );
3632
3633        // Second declaration
3634        assert_eq!(decls[1].ty().to_string(), "Float");
3635        assert_eq!(decls[1].name().text(), "b");
3636        assert_relative_eq!(
3637            decls[1]
3638                .expr()
3639                .unwrap_literal()
3640                .unwrap_float()
3641                .value()
3642                .unwrap(),
3643            0.0
3644        );
3645
3646        // Third declaration
3647        assert_eq!(decls[2].ty().to_string(), "Float");
3648        assert_eq!(decls[2].name().text(), "c");
3649        assert_relative_eq!(
3650            decls[2]
3651                .expr()
3652                .unwrap_literal()
3653                .unwrap_float()
3654                .value()
3655                .unwrap(),
3656            1234.1234
3657        );
3658
3659        // Fourth declaration
3660        assert_eq!(decls[3].ty().to_string(), "Float");
3661        assert_eq!(decls[3].name().text(), "d");
3662        assert_relative_eq!(
3663            decls[3]
3664                .expr()
3665                .unwrap_literal()
3666                .unwrap_float()
3667                .value()
3668                .unwrap(),
3669            123e+123
3670        );
3671
3672        // Fifth declaration
3673        assert_eq!(decls[4].ty().to_string(), "Float");
3674        assert_eq!(decls[4].name().text(), "e");
3675        assert_relative_eq!(
3676            decls[4]
3677                .expr()
3678                .unwrap_literal()
3679                .unwrap_float()
3680                .value()
3681                .unwrap(),
3682            0.1234
3683        );
3684
3685        // Sixth declaration
3686        assert_eq!(decls[5].ty().to_string(), "Float");
3687        assert_eq!(decls[5].name().text(), "f");
3688        assert_relative_eq!(
3689            decls[5]
3690                .expr()
3691                .unwrap_literal()
3692                .unwrap_float()
3693                .value()
3694                .unwrap(),
3695            10.0
3696        );
3697
3698        // Seventh declaration
3699        assert_eq!(decls[6].ty().to_string(), "Float");
3700        assert_eq!(decls[6].name().text(), "g");
3701        assert_relative_eq!(
3702            decls[6]
3703                .expr()
3704                .unwrap_literal()
3705                .unwrap_float()
3706                .value()
3707                .unwrap(),
3708            0.2
3709        );
3710
3711        // Eighth declaration
3712        assert_eq!(decls[7].ty().to_string(), "Float");
3713        assert_eq!(decls[7].name().text(), "h");
3714        assert!(
3715            decls[7]
3716                .expr()
3717                .unwrap_literal()
3718                .unwrap_float()
3719                .value()
3720                .is_none()
3721        );
3722    }
3723
3724    #[test]
3725    fn literal_string() {
3726        let (document, diagnostics) = Document::parse(
3727            r#"
3728version 1.1
3729
3730task test {
3731    String a = "hello"
3732    String b = 'world'
3733    String c = "Hello, ${name}!"
3734    String d = 'String~{'ception'}!'
3735    String e = <<< this is
3736    a multiline \
3737    string!
3738    ${first}
3739    ${second}
3740    >>>
3741}
3742"#,
3743            None,
3744        );
3745
3746        assert!(diagnostics.is_empty());
3747        let ast = document.ast();
3748        let ast = ast.as_v1().expect("should be a V1 AST");
3749        let tasks: Vec<_> = ast.tasks().collect();
3750        assert_eq!(tasks.len(), 1);
3751        assert_eq!(tasks[0].name().text(), "test");
3752
3753        // Task declarations
3754        let decls: Vec<_> = tasks[0].declarations().collect();
3755        assert_eq!(decls.len(), 5);
3756
3757        // First declaration
3758        assert_eq!(decls[0].ty().to_string(), "String");
3759        assert_eq!(decls[0].name().text(), "a");
3760        let s = decls[0].expr().unwrap_literal().unwrap_string();
3761        assert_eq!(s.kind(), LiteralStringKind::DoubleQuoted);
3762        assert_eq!(s.text().unwrap().text(), "hello");
3763
3764        // Second declaration
3765        assert_eq!(decls[1].ty().to_string(), "String");
3766        assert_eq!(decls[1].name().text(), "b");
3767        let s = decls[1].expr().unwrap_literal().unwrap_string();
3768        assert_eq!(s.kind(), LiteralStringKind::SingleQuoted);
3769        assert_eq!(s.text().unwrap().text(), "world");
3770
3771        // Third declaration
3772        assert_eq!(decls[2].ty().to_string(), "String");
3773        assert_eq!(decls[2].name().text(), "c");
3774        let s = decls[2].expr().unwrap_literal().unwrap_string();
3775        assert_eq!(s.kind(), LiteralStringKind::DoubleQuoted);
3776        let parts: Vec<_> = s.parts().collect();
3777        assert_eq!(parts.len(), 3);
3778        assert_eq!(parts[0].clone().unwrap_text().text(), "Hello, ");
3779        let placeholder = parts[1].clone().unwrap_placeholder();
3780        assert!(!placeholder.has_tilde());
3781        assert_eq!(placeholder.open().text(), "${");
3782        assert_eq!(placeholder.close().text(), "}");
3783        assert_eq!(placeholder.expr().unwrap_name_ref().name().text(), "name");
3784        assert_eq!(parts[2].clone().unwrap_text().text(), "!");
3785
3786        // Fourth declaration
3787        assert_eq!(decls[3].ty().to_string(), "String");
3788        assert_eq!(decls[3].name().text(), "d");
3789        let s = decls[3].expr().unwrap_literal().unwrap_string();
3790        assert_eq!(s.kind(), LiteralStringKind::SingleQuoted);
3791        let parts: Vec<_> = s.parts().collect();
3792        assert_eq!(parts.len(), 3);
3793        assert_eq!(parts[0].clone().unwrap_text().text(), "String");
3794        let placeholder = parts[1].clone().unwrap_placeholder();
3795        assert!(placeholder.has_tilde());
3796        assert_eq!(placeholder.open().text(), "~{");
3797        assert_eq!(placeholder.close().text(), "}");
3798        assert_eq!(
3799            placeholder
3800                .expr()
3801                .unwrap_literal()
3802                .unwrap_string()
3803                .text()
3804                .unwrap()
3805                .text(),
3806            "ception"
3807        );
3808        assert_eq!(parts[2].clone().unwrap_text().text(), "!");
3809
3810        // Fifth declaration
3811        assert_eq!(decls[4].ty().to_string(), "String");
3812        assert_eq!(decls[4].name().text(), "e");
3813        let s = decls[4].expr().unwrap_literal().unwrap_string();
3814        assert_eq!(s.kind(), LiteralStringKind::Multiline);
3815        let parts: Vec<_> = s.parts().collect();
3816        assert_eq!(parts.len(), 5);
3817        assert_eq!(
3818            parts[0].clone().unwrap_text().text(),
3819            " this is\n    a multiline \\\n    string!\n    "
3820        );
3821        let placeholder = parts[1].clone().unwrap_placeholder();
3822        assert!(!placeholder.has_tilde());
3823        assert_eq!(placeholder.expr().unwrap_name_ref().name().text(), "first");
3824        assert_eq!(parts[2].clone().unwrap_text().text(), "\n    ");
3825        let placeholder = parts[3].clone().unwrap_placeholder();
3826        assert!(!placeholder.has_tilde());
3827        assert_eq!(placeholder.expr().unwrap_name_ref().name().text(), "second");
3828        assert_eq!(parts[4].clone().unwrap_text().text(), "\n    ");
3829    }
3830
3831    #[test]
3832    fn literal_string_text() {
3833        let (document, diagnostics) = Document::parse(
3834            r#"
3835version 1.0
3836
3837task test {
3838    String no_placeholders = "test"
3839    String empty = ""
3840    String placeholder = "~{empty}"
3841}
3842"#,
3843            None,
3844        );
3845
3846        assert!(diagnostics.is_empty());
3847        let ast = document.ast();
3848        let ast = ast.as_v1().expect("should be a V1 AST");
3849        let tasks: Vec<_> = ast.tasks().collect();
3850        assert_eq!(tasks.len(), 1);
3851        assert_eq!(tasks[0].name().text(), "test");
3852
3853        // Task declarations
3854        let decls: Vec<_> = tasks[0].declarations().collect();
3855        assert_eq!(decls.len(), 3);
3856
3857        // First declaration
3858        assert_eq!(decls[0].ty().to_string(), "String");
3859        assert_eq!(decls[0].name().text(), "no_placeholders");
3860        let literal_string = decls[0].expr().unwrap_literal().unwrap_string();
3861        let text = literal_string.text();
3862        assert!(text.is_some());
3863        let text = text.unwrap();
3864        assert_eq!(text.text(), "test");
3865
3866        // Second declaration
3867        assert_eq!(decls[1].ty().to_string(), "String");
3868        assert_eq!(decls[1].name().text(), "empty");
3869        let literal_string = decls[1].expr().unwrap_literal().unwrap_string();
3870        let text = literal_string.text();
3871        assert!(text.is_some());
3872        let text = text.unwrap();
3873        assert_eq!(text.text(), "");
3874
3875        // Third declaration
3876        assert_eq!(decls[2].ty().to_string(), "String");
3877        assert_eq!(decls[2].name().text(), "placeholder");
3878        let literal_string = decls[2].expr().unwrap_literal().unwrap_string();
3879        let text = literal_string.text();
3880        assert!(text.is_none());
3881    }
3882
3883    #[test]
3884    fn literal_array() {
3885        let (document, diagnostics) = Document::parse(
3886            r#"
3887version 1.1
3888
3889task test {
3890    Array[Int] a = [1, 2, 3]
3891    Array[String] b = ["hello", "world", "!"]
3892    Array[Array[Int]] c = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3893}
3894"#,
3895            None,
3896        );
3897
3898        assert!(diagnostics.is_empty());
3899        let ast = document.ast();
3900        let ast = ast.as_v1().expect("should be a V1 AST");
3901        let tasks: Vec<_> = ast.tasks().collect();
3902        assert_eq!(tasks.len(), 1);
3903        assert_eq!(tasks[0].name().text(), "test");
3904
3905        // Task declarations
3906        let decls: Vec<_> = tasks[0].declarations().collect();
3907        assert_eq!(decls.len(), 3);
3908
3909        // First declaration
3910        assert_eq!(decls[0].ty().to_string(), "Array[Int]");
3911        assert_eq!(decls[0].name().text(), "a");
3912        let a = decls[0].expr().unwrap_literal().unwrap_array();
3913        let elements: Vec<_> = a.elements().collect();
3914        assert_eq!(elements.len(), 3);
3915        assert_eq!(
3916            elements[0]
3917                .clone()
3918                .unwrap_literal()
3919                .unwrap_integer()
3920                .value()
3921                .unwrap(),
3922            1
3923        );
3924        assert_eq!(
3925            elements[1]
3926                .clone()
3927                .unwrap_literal()
3928                .unwrap_integer()
3929                .value()
3930                .unwrap(),
3931            2
3932        );
3933        assert_eq!(
3934            elements[2]
3935                .clone()
3936                .unwrap_literal()
3937                .unwrap_integer()
3938                .value()
3939                .unwrap(),
3940            3
3941        );
3942
3943        // Second declaration
3944        assert_eq!(decls[1].ty().to_string(), "Array[String]");
3945        assert_eq!(decls[1].name().text(), "b");
3946        let a = decls[1].expr().unwrap_literal().unwrap_array();
3947        let elements: Vec<_> = a.elements().collect();
3948        assert_eq!(elements.len(), 3);
3949        assert_eq!(
3950            elements[0]
3951                .clone()
3952                .unwrap_literal()
3953                .unwrap_string()
3954                .text()
3955                .unwrap()
3956                .text(),
3957            "hello"
3958        );
3959        assert_eq!(
3960            elements[1]
3961                .clone()
3962                .unwrap_literal()
3963                .unwrap_string()
3964                .text()
3965                .unwrap()
3966                .text(),
3967            "world"
3968        );
3969        assert_eq!(
3970            elements[2]
3971                .clone()
3972                .unwrap_literal()
3973                .unwrap_string()
3974                .text()
3975                .unwrap()
3976                .text(),
3977            "!"
3978        );
3979
3980        // Third declaration
3981        assert_eq!(decls[2].ty().to_string(), "Array[Array[Int]]");
3982        assert_eq!(decls[2].name().text(), "c");
3983        let a = decls[2].expr().unwrap_literal().unwrap_array();
3984        let elements: Vec<_> = a.elements().collect();
3985        assert_eq!(elements.len(), 3);
3986        let sub: Vec<_> = elements[0]
3987            .clone()
3988            .unwrap_literal()
3989            .unwrap_array()
3990            .elements()
3991            .collect();
3992        assert_eq!(sub.len(), 3);
3993        assert_eq!(
3994            sub[0]
3995                .clone()
3996                .unwrap_literal()
3997                .unwrap_integer()
3998                .value()
3999                .unwrap(),
4000            1
4001        );
4002        assert_eq!(
4003            sub[1]
4004                .clone()
4005                .unwrap_literal()
4006                .unwrap_integer()
4007                .value()
4008                .unwrap(),
4009            2
4010        );
4011        assert_eq!(
4012            sub[2]
4013                .clone()
4014                .unwrap_literal()
4015                .unwrap_integer()
4016                .value()
4017                .unwrap(),
4018            3
4019        );
4020        let sub: Vec<_> = elements[1]
4021            .clone()
4022            .unwrap_literal()
4023            .unwrap_array()
4024            .elements()
4025            .collect();
4026        assert_eq!(sub.len(), 3);
4027        assert_eq!(
4028            sub[0]
4029                .clone()
4030                .unwrap_literal()
4031                .unwrap_integer()
4032                .value()
4033                .unwrap(),
4034            4
4035        );
4036        assert_eq!(
4037            sub[1]
4038                .clone()
4039                .unwrap_literal()
4040                .unwrap_integer()
4041                .value()
4042                .unwrap(),
4043            5
4044        );
4045        assert_eq!(
4046            sub[2]
4047                .clone()
4048                .unwrap_literal()
4049                .unwrap_integer()
4050                .value()
4051                .unwrap(),
4052            6
4053        );
4054        let sub: Vec<_> = elements[2]
4055            .clone()
4056            .unwrap_literal()
4057            .unwrap_array()
4058            .elements()
4059            .collect();
4060        assert_eq!(sub.len(), 3);
4061        assert_eq!(
4062            sub[0]
4063                .clone()
4064                .unwrap_literal()
4065                .unwrap_integer()
4066                .value()
4067                .unwrap(),
4068            7
4069        );
4070        assert_eq!(
4071            sub[1]
4072                .clone()
4073                .unwrap_literal()
4074                .unwrap_integer()
4075                .value()
4076                .unwrap(),
4077            8
4078        );
4079        assert_eq!(
4080            sub[2]
4081                .clone()
4082                .unwrap_literal()
4083                .unwrap_integer()
4084                .value()
4085                .unwrap(),
4086            9
4087        );
4088    }
4089
4090    #[test]
4091    fn literal_pair() {
4092        let (document, diagnostics) = Document::parse(
4093            r#"
4094version 1.1
4095
4096task test {
4097    Pair[Int, Int] a = (1000, 0x1000)
4098    Pair[String, Int] b = ("0x1000", 1000)
4099    Array[Pair[Int, String]] c = [(1, "hello"), (2, 'world'), (3, "!")]
4100}
4101"#,
4102            None,
4103        );
4104
4105        assert!(diagnostics.is_empty());
4106        let ast = document.ast();
4107        let ast = ast.as_v1().expect("should be a V1 AST");
4108        let tasks: Vec<_> = ast.tasks().collect();
4109        assert_eq!(tasks.len(), 1);
4110        assert_eq!(tasks[0].name().text(), "test");
4111
4112        // Task declarations
4113        let decls: Vec<_> = tasks[0].declarations().collect();
4114        assert_eq!(decls.len(), 3);
4115
4116        // First declaration
4117        assert_eq!(decls[0].ty().to_string(), "Pair[Int, Int]");
4118        assert_eq!(decls[0].name().text(), "a");
4119        let p = decls[0].expr().unwrap_literal().unwrap_pair();
4120        let (left, right) = p.exprs();
4121        assert_eq!(
4122            left.clone()
4123                .unwrap_literal()
4124                .unwrap_integer()
4125                .value()
4126                .unwrap(),
4127            1000
4128        );
4129        assert_eq!(
4130            right
4131                .clone()
4132                .unwrap_literal()
4133                .unwrap_integer()
4134                .value()
4135                .unwrap(),
4136            0x1000
4137        );
4138
4139        // Second declaration
4140        assert_eq!(decls[1].ty().to_string(), "Pair[String, Int]");
4141        assert_eq!(decls[1].name().text(), "b");
4142        let p = decls[1].expr().unwrap_literal().unwrap_pair();
4143        let (left, right) = p.exprs();
4144        assert_eq!(
4145            left.clone()
4146                .unwrap_literal()
4147                .unwrap_string()
4148                .text()
4149                .unwrap()
4150                .text(),
4151            "0x1000"
4152        );
4153        assert_eq!(
4154            right
4155                .clone()
4156                .unwrap_literal()
4157                .unwrap_integer()
4158                .value()
4159                .unwrap(),
4160            1000
4161        );
4162
4163        // Third declaration
4164        assert_eq!(decls[2].ty().to_string(), "Array[Pair[Int, String]]");
4165        assert_eq!(decls[2].name().text(), "c");
4166        let a = decls[2].expr().unwrap_literal().unwrap_array();
4167        let elements: Vec<_> = a.elements().collect();
4168        assert_eq!(elements.len(), 3);
4169        let p = elements[0].clone().unwrap_literal().unwrap_pair();
4170        let (left, right) = p.exprs();
4171        assert_eq!(
4172            left.clone()
4173                .unwrap_literal()
4174                .unwrap_integer()
4175                .value()
4176                .unwrap(),
4177            1
4178        );
4179        assert_eq!(
4180            right
4181                .clone()
4182                .unwrap_literal()
4183                .unwrap_string()
4184                .text()
4185                .unwrap()
4186                .text(),
4187            "hello"
4188        );
4189        let p = elements[1].clone().unwrap_literal().unwrap_pair();
4190        let (left, right) = p.exprs();
4191        assert_eq!(
4192            left.clone()
4193                .unwrap_literal()
4194                .unwrap_integer()
4195                .value()
4196                .unwrap(),
4197            2
4198        );
4199        assert_eq!(
4200            right
4201                .clone()
4202                .unwrap_literal()
4203                .unwrap_string()
4204                .text()
4205                .unwrap()
4206                .text(),
4207            "world"
4208        );
4209        let p = elements[2].clone().unwrap_literal().unwrap_pair();
4210        let (left, right) = p.exprs();
4211        assert_eq!(
4212            left.clone()
4213                .unwrap_literal()
4214                .unwrap_integer()
4215                .value()
4216                .unwrap(),
4217            3
4218        );
4219        assert_eq!(
4220            right
4221                .clone()
4222                .unwrap_literal()
4223                .unwrap_string()
4224                .text()
4225                .unwrap()
4226                .text(),
4227            "!"
4228        );
4229    }
4230
4231    #[test]
4232    fn literal_map() {
4233        let (document, diagnostics) = Document::parse(
4234            r#"
4235version 1.1
4236
4237task test {
4238    Map[Int, Int] a = {}
4239    Map[String, String] b = { "foo": "bar", "bar": "baz" }
4240}
4241"#,
4242            None,
4243        );
4244
4245        assert!(diagnostics.is_empty());
4246        let ast = document.ast();
4247        let ast = ast.as_v1().expect("should be a V1 AST");
4248        let tasks: Vec<_> = ast.tasks().collect();
4249        assert_eq!(tasks.len(), 1);
4250        assert_eq!(tasks[0].name().text(), "test");
4251
4252        // Task declarations
4253        let decls: Vec<_> = tasks[0].declarations().collect();
4254        assert_eq!(decls.len(), 2);
4255
4256        // First declaration
4257        assert_eq!(decls[0].ty().to_string(), "Map[Int, Int]");
4258        assert_eq!(decls[0].name().text(), "a");
4259        let m = decls[0].expr().unwrap_literal().unwrap_map();
4260        let items: Vec<_> = m.items().collect();
4261        assert_eq!(items.len(), 0);
4262
4263        // Second declaration
4264        assert_eq!(decls[1].ty().to_string(), "Map[String, String]");
4265        assert_eq!(decls[1].name().text(), "b");
4266        let m = decls[1].expr().unwrap_literal().unwrap_map();
4267        let items: Vec<_> = m.items().collect();
4268        assert_eq!(items.len(), 2);
4269        let (key, value) = items[0].key_value();
4270        assert_eq!(
4271            key.unwrap_literal().unwrap_string().text().unwrap().text(),
4272            "foo"
4273        );
4274        assert_eq!(
4275            value
4276                .unwrap_literal()
4277                .unwrap_string()
4278                .text()
4279                .unwrap()
4280                .text(),
4281            "bar"
4282        );
4283        let (key, value) = items[1].key_value();
4284        assert_eq!(
4285            key.unwrap_literal().unwrap_string().text().unwrap().text(),
4286            "bar"
4287        );
4288        assert_eq!(
4289            value
4290                .unwrap_literal()
4291                .unwrap_string()
4292                .text()
4293                .unwrap()
4294                .text(),
4295            "baz"
4296        );
4297    }
4298
4299    #[test]
4300    fn literal_object() {
4301        let (document, diagnostics) = Document::parse(
4302            r#"
4303version 1.1
4304
4305task test {
4306    Object a = object {}
4307    Object b = object { foo: "bar", bar: 1, baz: [1, 2, 3] }
4308}
4309"#,
4310            None,
4311        );
4312
4313        assert!(diagnostics.is_empty());
4314        let ast = document.ast();
4315        let ast = ast.as_v1().expect("should be a V1 AST");
4316        let tasks: Vec<_> = ast.tasks().collect();
4317        assert_eq!(tasks.len(), 1);
4318        assert_eq!(tasks[0].name().text(), "test");
4319
4320        // Task declarations
4321        let decls: Vec<_> = tasks[0].declarations().collect();
4322        assert_eq!(decls.len(), 2);
4323
4324        // First declaration
4325        assert_eq!(decls[0].ty().to_string(), "Object");
4326        assert_eq!(decls[0].name().text(), "a");
4327        let o = decls[0].expr().unwrap_literal().unwrap_object();
4328        let items: Vec<_> = o.items().collect();
4329        assert_eq!(items.len(), 0);
4330
4331        // Second declaration
4332        assert_eq!(decls[1].ty().to_string(), "Object");
4333        assert_eq!(decls[1].name().text(), "b");
4334        let o = decls[1].expr().unwrap_literal().unwrap_object();
4335        let items: Vec<_> = o.items().collect();
4336        assert_eq!(items.len(), 3);
4337        let (name, value) = items[0].name_value();
4338        assert_eq!(name.text(), "foo");
4339        assert_eq!(
4340            value
4341                .unwrap_literal()
4342                .unwrap_string()
4343                .text()
4344                .unwrap()
4345                .text(),
4346            "bar"
4347        );
4348        let (name, value) = items[1].name_value();
4349        assert_eq!(name.text(), "bar");
4350        assert_eq!(value.unwrap_literal().unwrap_integer().value().unwrap(), 1);
4351        let (name, value) = items[2].name_value();
4352        assert_eq!(name.text(), "baz");
4353        let elements: Vec<_> = value.unwrap_literal().unwrap_array().elements().collect();
4354        assert_eq!(elements.len(), 3);
4355        assert_eq!(
4356            elements[0]
4357                .clone()
4358                .unwrap_literal()
4359                .unwrap_integer()
4360                .value()
4361                .unwrap(),
4362            1
4363        );
4364        assert_eq!(
4365            elements[1]
4366                .clone()
4367                .unwrap_literal()
4368                .unwrap_integer()
4369                .value()
4370                .unwrap(),
4371            2
4372        );
4373        assert_eq!(
4374            elements[2]
4375                .clone()
4376                .unwrap_literal()
4377                .unwrap_integer()
4378                .value()
4379                .unwrap(),
4380            3
4381        );
4382    }
4383
4384    #[test]
4385    fn literal_struct() {
4386        let (document, diagnostics) = Document::parse(
4387            r#"
4388version 1.1
4389
4390task test {
4391    Foo a = Foo { foo: "bar" }
4392    Bar b = Bar { bar: 1, baz: [1, 2, 3] }
4393}
4394"#,
4395            None,
4396        );
4397
4398        assert!(diagnostics.is_empty());
4399        let ast = document.ast();
4400        let ast = ast.as_v1().expect("should be a V1 AST");
4401        let tasks: Vec<_> = ast.tasks().collect();
4402        assert_eq!(tasks.len(), 1);
4403        assert_eq!(tasks[0].name().text(), "test");
4404
4405        // Task declarations
4406        let decls: Vec<_> = tasks[0].declarations().collect();
4407        assert_eq!(decls.len(), 2);
4408
4409        // First declaration
4410        assert_eq!(decls[0].ty().to_string(), "Foo");
4411        assert_eq!(decls[0].name().text(), "a");
4412        let s = decls[0].expr().unwrap_literal().unwrap_struct();
4413        assert_eq!(s.name().text(), "Foo");
4414        let items: Vec<_> = s.items().collect();
4415        assert_eq!(items.len(), 1);
4416        let (name, value) = items[0].name_value();
4417        assert_eq!(name.text(), "foo");
4418        assert_eq!(
4419            value
4420                .unwrap_literal()
4421                .unwrap_string()
4422                .text()
4423                .unwrap()
4424                .text(),
4425            "bar"
4426        );
4427
4428        // Second declaration
4429        assert_eq!(decls[1].ty().to_string(), "Bar");
4430        assert_eq!(decls[1].name().text(), "b");
4431        let s = decls[1].expr().unwrap_literal().unwrap_struct();
4432        assert_eq!(s.name().text(), "Bar");
4433        let items: Vec<_> = s.items().collect();
4434        assert_eq!(items.len(), 2);
4435        let (name, value) = items[0].name_value();
4436        assert_eq!(name.text(), "bar");
4437        assert_eq!(value.unwrap_literal().unwrap_integer().value().unwrap(), 1);
4438        let (name, value) = items[1].name_value();
4439        assert_eq!(name.text(), "baz");
4440        let elements: Vec<_> = value.unwrap_literal().unwrap_array().elements().collect();
4441        assert_eq!(elements.len(), 3);
4442        assert_eq!(
4443            elements[0]
4444                .clone()
4445                .unwrap_literal()
4446                .unwrap_integer()
4447                .value()
4448                .unwrap(),
4449            1
4450        );
4451        assert_eq!(
4452            elements[1]
4453                .clone()
4454                .unwrap_literal()
4455                .unwrap_integer()
4456                .value()
4457                .unwrap(),
4458            2
4459        );
4460        assert_eq!(
4461            elements[2]
4462                .clone()
4463                .unwrap_literal()
4464                .unwrap_integer()
4465                .value()
4466                .unwrap(),
4467            3
4468        );
4469    }
4470
4471    #[test]
4472    fn literal_none() {
4473        let (document, diagnostics) = Document::parse(
4474            r#"
4475version 1.1
4476
4477task test {
4478    Int? a = None
4479    Boolean b = a == None
4480}
4481"#,
4482            None,
4483        );
4484
4485        assert!(diagnostics.is_empty());
4486        let ast = document.ast();
4487        let ast = ast.as_v1().expect("should be a V1 AST");
4488        let tasks: Vec<_> = ast.tasks().collect();
4489        assert_eq!(tasks.len(), 1);
4490        assert_eq!(tasks[0].name().text(), "test");
4491
4492        // Task declarations
4493        let decls: Vec<_> = tasks[0].declarations().collect();
4494        assert_eq!(decls.len(), 2);
4495
4496        // First declaration
4497        assert_eq!(decls[0].ty().to_string(), "Int?");
4498        assert_eq!(decls[0].name().text(), "a");
4499        decls[0].expr().unwrap_literal().unwrap_none();
4500
4501        // Second declaration
4502        assert_eq!(decls[1].ty().to_string(), "Boolean");
4503        assert_eq!(decls[1].name().text(), "b");
4504        let (lhs, rhs) = decls[1].expr().unwrap_equality().operands();
4505        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
4506        rhs.unwrap_literal().unwrap_none();
4507    }
4508
4509    #[test]
4510    fn literal_hints() {
4511        let (document, diagnostics) = Document::parse(
4512            r#"
4513version 1.2
4514
4515task test {
4516    hints {
4517        foo: hints {
4518            bar: "bar",
4519            baz: "baz"
4520        }
4521        bar: "bar"
4522        baz: hints {
4523            a: 1,
4524            b: 10.0,
4525            c: {
4526                "foo": "bar",
4527            }
4528        }
4529    }
4530}
4531"#,
4532            None,
4533        );
4534
4535        assert!(diagnostics.is_empty());
4536        let ast = document.ast();
4537        let ast = ast.as_v1().expect("should be a V1 AST");
4538        let tasks: Vec<_> = ast.tasks().collect();
4539        assert_eq!(tasks.len(), 1);
4540        assert_eq!(tasks[0].name().text(), "test");
4541
4542        // Task hints
4543        let hints = tasks[0].hints().expect("should have a hints section");
4544        let items: Vec<_> = hints.items().collect();
4545        assert_eq!(items.len(), 3);
4546
4547        // First hints item
4548        assert_eq!(items[0].name().text(), "foo");
4549        let inner: Vec<_> = items[0]
4550            .expr()
4551            .unwrap_literal()
4552            .unwrap_hints()
4553            .items()
4554            .collect();
4555        assert_eq!(inner.len(), 2);
4556        assert_eq!(inner[0].name().text(), "bar");
4557        assert_eq!(
4558            inner[0]
4559                .expr()
4560                .unwrap_literal()
4561                .unwrap_string()
4562                .text()
4563                .unwrap()
4564                .text(),
4565            "bar"
4566        );
4567        assert_eq!(inner[1].name().text(), "baz");
4568        assert_eq!(
4569            inner[1]
4570                .expr()
4571                .unwrap_literal()
4572                .unwrap_string()
4573                .text()
4574                .unwrap()
4575                .text(),
4576            "baz"
4577        );
4578
4579        // Second hints item
4580        assert_eq!(items[1].name().text(), "bar");
4581        assert_eq!(
4582            items[1]
4583                .expr()
4584                .unwrap_literal()
4585                .unwrap_string()
4586                .text()
4587                .unwrap()
4588                .text(),
4589            "bar"
4590        );
4591
4592        // Third hints item
4593        assert_eq!(items[2].name().text(), "baz");
4594        let inner: Vec<_> = items[2]
4595            .expr()
4596            .unwrap_literal()
4597            .unwrap_hints()
4598            .items()
4599            .collect();
4600        assert_eq!(inner.len(), 3);
4601        assert_eq!(inner[0].name().text(), "a");
4602        assert_eq!(
4603            inner[0]
4604                .expr()
4605                .unwrap_literal()
4606                .unwrap_integer()
4607                .value()
4608                .unwrap(),
4609            1
4610        );
4611        assert_eq!(inner[1].name().text(), "b");
4612        assert_relative_eq!(
4613            inner[1]
4614                .expr()
4615                .unwrap_literal()
4616                .unwrap_float()
4617                .value()
4618                .unwrap(),
4619            10.0
4620        );
4621        assert_eq!(inner[2].name().text(), "c");
4622        let map: Vec<_> = inner[2]
4623            .expr()
4624            .unwrap_literal()
4625            .unwrap_map()
4626            .items()
4627            .collect();
4628        assert_eq!(map.len(), 1);
4629        let (k, v) = map[0].key_value();
4630        assert_eq!(
4631            k.unwrap_literal().unwrap_string().text().unwrap().text(),
4632            "foo"
4633        );
4634        assert_eq!(
4635            v.unwrap_literal().unwrap_string().text().unwrap().text(),
4636            "bar"
4637        );
4638    }
4639
4640    #[test]
4641    fn literal_input() {
4642        let (document, diagnostics) = Document::parse(
4643            r#"
4644version 1.2
4645
4646task test {
4647    hints {
4648        inputs: input {
4649            a: hints {
4650                foo: "bar"
4651            },
4652            b.c.d: hints {
4653                bar: "baz"
4654            }
4655        }
4656    }
4657}
4658"#,
4659            None,
4660        );
4661
4662        assert!(diagnostics.is_empty());
4663        let ast = document.ast();
4664        let ast = ast.as_v1().expect("should be a V1 AST");
4665        let tasks: Vec<_> = ast.tasks().collect();
4666        assert_eq!(tasks.len(), 1);
4667        assert_eq!(tasks[0].name().text(), "test");
4668
4669        // Task hints
4670        let hints = tasks[0].hints().expect("task should have hints section");
4671        let items: Vec<_> = hints.items().collect();
4672        assert_eq!(items.len(), 1);
4673
4674        // First hints item
4675        assert_eq!(items[0].name().text(), "inputs");
4676        let input: Vec<_> = items[0]
4677            .expr()
4678            .unwrap_literal()
4679            .unwrap_input()
4680            .items()
4681            .collect();
4682        assert_eq!(input.len(), 2);
4683        assert_eq!(
4684            input[0]
4685                .names()
4686                .map(|i| i.text().to_string())
4687                .collect::<Vec<_>>(),
4688            ["a"]
4689        );
4690        let inner: Vec<_> = input[0]
4691            .expr()
4692            .unwrap_literal()
4693            .unwrap_hints()
4694            .items()
4695            .collect();
4696        assert_eq!(inner.len(), 1);
4697        assert_eq!(inner[0].name().text(), "foo");
4698        assert_eq!(
4699            inner[0]
4700                .expr()
4701                .unwrap_literal()
4702                .unwrap_string()
4703                .text()
4704                .unwrap()
4705                .text(),
4706            "bar"
4707        );
4708        assert_eq!(
4709            input[1]
4710                .names()
4711                .map(|i| i.text().to_string())
4712                .collect::<Vec<_>>(),
4713            ["b", "c", "d"]
4714        );
4715        let inner: Vec<_> = input[1]
4716            .expr()
4717            .unwrap_literal()
4718            .unwrap_hints()
4719            .items()
4720            .collect();
4721        assert_eq!(inner.len(), 1);
4722        assert_eq!(inner[0].name().text(), "bar");
4723        assert_eq!(
4724            inner[0]
4725                .expr()
4726                .unwrap_literal()
4727                .unwrap_string()
4728                .text()
4729                .unwrap()
4730                .text(),
4731            "baz"
4732        );
4733    }
4734
4735    #[test]
4736    fn literal_output() {
4737        let (document, diagnostics) = Document::parse(
4738            r#"
4739version 1.2
4740
4741task test {
4742    hints {
4743        outputs: output {
4744            a: hints {
4745                foo: "bar"
4746            },
4747            b.c.d: hints {
4748                bar: "baz"
4749            }
4750        }
4751    }
4752}
4753"#,
4754            None,
4755        );
4756
4757        assert!(diagnostics.is_empty());
4758        let ast = document.ast();
4759        let ast = ast.as_v1().expect("should be a V1 AST");
4760        let tasks: Vec<_> = ast.tasks().collect();
4761        assert_eq!(tasks.len(), 1);
4762        assert_eq!(tasks[0].name().text(), "test");
4763
4764        // Task hints
4765        let hints = tasks[0].hints().expect("task should have a hints section");
4766        let items: Vec<_> = hints.items().collect();
4767        assert_eq!(items.len(), 1);
4768
4769        // First hints item
4770        assert_eq!(items[0].name().text(), "outputs");
4771        let output: Vec<_> = items[0]
4772            .expr()
4773            .unwrap_literal()
4774            .unwrap_output()
4775            .items()
4776            .collect();
4777        assert_eq!(output.len(), 2);
4778        assert_eq!(
4779            output[0]
4780                .names()
4781                .map(|i| i.text().to_string())
4782                .collect::<Vec<_>>(),
4783            ["a"]
4784        );
4785        let inner: Vec<_> = output[0]
4786            .expr()
4787            .unwrap_literal()
4788            .unwrap_hints()
4789            .items()
4790            .collect();
4791        assert_eq!(inner.len(), 1);
4792        assert_eq!(inner[0].name().text(), "foo");
4793        assert_eq!(
4794            inner[0]
4795                .expr()
4796                .unwrap_literal()
4797                .unwrap_string()
4798                .text()
4799                .unwrap()
4800                .text(),
4801            "bar"
4802        );
4803        assert_eq!(
4804            output[1]
4805                .names()
4806                .map(|i| i.text().to_string())
4807                .collect::<Vec<_>>(),
4808            ["b", "c", "d"]
4809        );
4810        let inner: Vec<_> = output[1]
4811            .expr()
4812            .unwrap_literal()
4813            .unwrap_hints()
4814            .items()
4815            .collect();
4816        assert_eq!(inner.len(), 1);
4817        assert_eq!(inner[0].name().text(), "bar");
4818        assert_eq!(
4819            inner[0]
4820                .expr()
4821                .unwrap_literal()
4822                .unwrap_string()
4823                .text()
4824                .unwrap()
4825                .text(),
4826            "baz"
4827        );
4828    }
4829
4830    #[test]
4831    fn name_ref() {
4832        let (document, diagnostics) = Document::parse(
4833            r#"
4834version 1.1
4835
4836task test {
4837    Int a = 0
4838    Int b = a
4839}
4840"#,
4841            None,
4842        );
4843
4844        assert!(diagnostics.is_empty());
4845        let ast = document.ast();
4846        let ast = ast.as_v1().expect("should be a V1 AST");
4847        let tasks: Vec<_> = ast.tasks().collect();
4848        assert_eq!(tasks.len(), 1);
4849        assert_eq!(tasks[0].name().text(), "test");
4850
4851        // Task declarations
4852        let decls: Vec<_> = tasks[0].declarations().collect();
4853        assert_eq!(decls.len(), 2);
4854
4855        // First declaration
4856        assert_eq!(decls[0].ty().to_string(), "Int");
4857        assert_eq!(decls[0].name().text(), "a");
4858        assert_eq!(
4859            decls[0]
4860                .expr()
4861                .unwrap_literal()
4862                .unwrap_integer()
4863                .value()
4864                .unwrap(),
4865            0
4866        );
4867
4868        // Second declaration
4869        assert_eq!(decls[1].ty().to_string(), "Int");
4870        assert_eq!(decls[1].name().text(), "b");
4871        assert_eq!(decls[1].expr().unwrap_name_ref().name().text(), "a");
4872    }
4873
4874    #[test]
4875    fn parenthesized() {
4876        let (document, diagnostics) = Document::parse(
4877            r#"
4878version 1.1
4879
4880task test {
4881    Int a = (0)
4882    Int b = (10 - (5 + 5))
4883}
4884"#,
4885            None,
4886        );
4887
4888        assert!(diagnostics.is_empty());
4889        let ast = document.ast();
4890        let ast = ast.as_v1().expect("should be a V1 AST");
4891        let tasks: Vec<_> = ast.tasks().collect();
4892        assert_eq!(tasks.len(), 1);
4893        assert_eq!(tasks[0].name().text(), "test");
4894
4895        // Task declarations
4896        let decls: Vec<_> = tasks[0].declarations().collect();
4897        assert_eq!(decls.len(), 2);
4898
4899        // First declaration
4900        assert_eq!(decls[0].ty().to_string(), "Int");
4901        assert_eq!(decls[0].name().text(), "a");
4902        assert_eq!(
4903            decls[0]
4904                .expr()
4905                .unwrap_parenthesized()
4906                .expr()
4907                .unwrap_literal()
4908                .unwrap_integer()
4909                .value()
4910                .unwrap(),
4911            0
4912        );
4913
4914        // Second declaration
4915        assert_eq!(decls[1].ty().to_string(), "Int");
4916        assert_eq!(decls[1].name().text(), "b");
4917        let (lhs, rhs) = decls[1]
4918            .expr()
4919            .unwrap_parenthesized()
4920            .expr()
4921            .unwrap_subtraction()
4922            .operands();
4923        assert_eq!(lhs.unwrap_literal().unwrap_integer().value().unwrap(), 10);
4924        let (lhs, rhs) = rhs
4925            .unwrap_parenthesized()
4926            .expr()
4927            .unwrap_addition()
4928            .operands();
4929        assert_eq!(lhs.unwrap_literal().unwrap_integer().value().unwrap(), 5);
4930        assert_eq!(rhs.unwrap_literal().unwrap_integer().value().unwrap(), 5);
4931    }
4932
4933    #[test]
4934    fn if_expr() {
4935        let (document, diagnostics) = Document::parse(
4936            r#"
4937version 1.1
4938
4939task test {
4940    Int a = if true then 1 else 0
4941    String b = if a > 0 then "yes" else "no"
4942}
4943"#,
4944            None,
4945        );
4946
4947        assert!(diagnostics.is_empty());
4948        let ast = document.ast();
4949        let ast = ast.as_v1().expect("should be a V1 AST");
4950        let tasks: Vec<_> = ast.tasks().collect();
4951        assert_eq!(tasks.len(), 1);
4952        assert_eq!(tasks[0].name().text(), "test");
4953
4954        // Task declarations
4955        let decls: Vec<_> = tasks[0].declarations().collect();
4956        assert_eq!(decls.len(), 2);
4957
4958        // First declaration
4959        assert_eq!(decls[0].ty().to_string(), "Int");
4960        assert_eq!(decls[0].name().text(), "a");
4961        let (c, t, f) = decls[0].expr().unwrap_if().exprs();
4962        assert!(c.unwrap_literal().unwrap_boolean().value());
4963        assert_eq!(t.unwrap_literal().unwrap_integer().value().unwrap(), 1);
4964        assert_eq!(f.unwrap_literal().unwrap_integer().value().unwrap(), 0);
4965
4966        // Second declaration
4967        assert_eq!(decls[1].ty().to_string(), "String");
4968        assert_eq!(decls[1].name().text(), "b");
4969        let (c, t, f) = decls[1].expr().unwrap_if().exprs();
4970        let (lhs, rhs) = c.unwrap_greater().operands();
4971        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
4972        assert_eq!(rhs.unwrap_literal().unwrap_integer().value().unwrap(), 0);
4973        assert_eq!(
4974            t.unwrap_literal().unwrap_string().text().unwrap().text(),
4975            "yes"
4976        );
4977        assert_eq!(
4978            f.unwrap_literal().unwrap_string().text().unwrap().text(),
4979            "no"
4980        );
4981    }
4982
4983    #[test]
4984    fn logical_not() {
4985        let (document, diagnostics) = Document::parse(
4986            r#"
4987version 1.1
4988
4989task test {
4990    Boolean a = !true
4991    Boolean b = !!!a
4992}
4993"#,
4994            None,
4995        );
4996
4997        assert!(diagnostics.is_empty());
4998        let ast = document.ast();
4999        let ast = ast.as_v1().expect("should be a V1 AST");
5000        let tasks: Vec<_> = ast.tasks().collect();
5001        assert_eq!(tasks.len(), 1);
5002        assert_eq!(tasks[0].name().text(), "test");
5003
5004        // Task declarations
5005        let decls: Vec<_> = tasks[0].declarations().collect();
5006        assert_eq!(decls.len(), 2);
5007
5008        // First declaration
5009        assert_eq!(decls[0].ty().to_string(), "Boolean");
5010        assert_eq!(decls[0].name().text(), "a");
5011        assert!(
5012            decls[0]
5013                .expr()
5014                .unwrap_logical_not()
5015                .operand()
5016                .unwrap_literal()
5017                .unwrap_boolean()
5018                .value()
5019        );
5020
5021        // Second declaration
5022        assert_eq!(decls[1].ty().to_string(), "Boolean");
5023        assert_eq!(decls[1].name().text(), "b");
5024        assert_eq!(
5025            decls[1]
5026                .expr()
5027                .unwrap_logical_not()
5028                .operand()
5029                .unwrap_logical_not()
5030                .operand()
5031                .unwrap_logical_not()
5032                .operand()
5033                .unwrap_name_ref()
5034                .name()
5035                .text(),
5036            "a"
5037        );
5038    }
5039
5040    #[test]
5041    fn negation() {
5042        let (document, diagnostics) = Document::parse(
5043            r#"
5044version 1.1
5045
5046task test {
5047    Int a = -1
5048    Int b = ---a
5049}
5050"#,
5051            None,
5052        );
5053
5054        assert!(diagnostics.is_empty());
5055        let ast = document.ast();
5056        let ast = ast.as_v1().expect("should be a V1 AST");
5057        let tasks: Vec<_> = ast.tasks().collect();
5058        assert_eq!(tasks.len(), 1);
5059        assert_eq!(tasks[0].name().text(), "test");
5060
5061        // Task declarations
5062        let decls: Vec<_> = tasks[0].declarations().collect();
5063        assert_eq!(decls.len(), 2);
5064
5065        // First declaration
5066        assert_eq!(decls[0].ty().to_string(), "Int");
5067        assert_eq!(decls[0].name().text(), "a");
5068        assert_eq!(
5069            decls[0]
5070                .expr()
5071                .unwrap_negation()
5072                .operand()
5073                .unwrap_literal()
5074                .unwrap_integer()
5075                .value()
5076                .unwrap(),
5077            1
5078        );
5079
5080        // Second declaration
5081        assert_eq!(decls[1].ty().to_string(), "Int");
5082        assert_eq!(decls[1].name().text(), "b");
5083        assert_eq!(
5084            decls[1]
5085                .expr()
5086                .unwrap_negation()
5087                .operand()
5088                .unwrap_negation()
5089                .operand()
5090                .unwrap_negation()
5091                .operand()
5092                .unwrap_name_ref()
5093                .name()
5094                .text(),
5095            "a"
5096        );
5097    }
5098
5099    #[test]
5100    fn logical_or() {
5101        let (document, diagnostics) = Document::parse(
5102            r#"
5103version 1.1
5104
5105task test {
5106    Boolean a = false
5107    Boolean b = true
5108    Boolean c = a || b
5109}
5110"#,
5111            None,
5112        );
5113
5114        assert!(diagnostics.is_empty());
5115        let ast = document.ast();
5116        let ast = ast.as_v1().expect("should be a V1 AST");
5117        let tasks: Vec<_> = ast.tasks().collect();
5118        assert_eq!(tasks.len(), 1);
5119        assert_eq!(tasks[0].name().text(), "test");
5120
5121        // Task declarations
5122        let decls: Vec<_> = tasks[0].declarations().collect();
5123        assert_eq!(decls.len(), 3);
5124
5125        // First declaration
5126        assert_eq!(decls[0].ty().to_string(), "Boolean");
5127        assert_eq!(decls[0].name().text(), "a");
5128        assert!(!decls[0].expr().unwrap_literal().unwrap_boolean().value());
5129
5130        // Second declaration
5131        assert_eq!(decls[1].ty().to_string(), "Boolean");
5132        assert_eq!(decls[1].name().text(), "b");
5133        assert!(decls[1].expr().unwrap_literal().unwrap_boolean().value());
5134
5135        // Third declaration
5136        assert_eq!(decls[2].ty().to_string(), "Boolean");
5137        assert_eq!(decls[2].name().text(), "c");
5138        let (lhs, rhs) = decls[2].expr().unwrap_logical_or().operands();
5139        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5140        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5141    }
5142
5143    #[test]
5144    fn logical_and() {
5145        let (document, diagnostics) = Document::parse(
5146            r#"
5147version 1.1
5148
5149task test {
5150    Boolean a = true
5151    Boolean b = true
5152    Boolean c = a && b
5153}
5154"#,
5155            None,
5156        );
5157
5158        assert!(diagnostics.is_empty());
5159        let ast = document.ast();
5160        let ast = ast.as_v1().expect("should be a V1 AST");
5161        let tasks: Vec<_> = ast.tasks().collect();
5162        assert_eq!(tasks.len(), 1);
5163        assert_eq!(tasks[0].name().text(), "test");
5164
5165        // Task declarations
5166        let decls: Vec<_> = tasks[0].declarations().collect();
5167        assert_eq!(decls.len(), 3);
5168
5169        // First declaration
5170        assert_eq!(decls[0].ty().to_string(), "Boolean");
5171        assert_eq!(decls[0].name().text(), "a");
5172        assert!(decls[0].expr().unwrap_literal().unwrap_boolean().value());
5173
5174        // Second declaration
5175        assert_eq!(decls[1].ty().to_string(), "Boolean");
5176        assert_eq!(decls[1].name().text(), "b");
5177        assert!(decls[1].expr().unwrap_literal().unwrap_boolean().value());
5178
5179        // Third declaration
5180        assert_eq!(decls[2].ty().to_string(), "Boolean");
5181        assert_eq!(decls[2].name().text(), "c");
5182        let (lhs, rhs) = decls[2].expr().unwrap_logical_and().operands();
5183        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5184        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5185    }
5186
5187    #[test]
5188    fn equality() {
5189        let (document, diagnostics) = Document::parse(
5190            r#"
5191version 1.1
5192
5193task test {
5194    Boolean a = true
5195    Boolean b = false
5196    Boolean c = a == b
5197}
5198"#,
5199            None,
5200        );
5201
5202        assert!(diagnostics.is_empty());
5203        let ast = document.ast();
5204        let ast = ast.as_v1().expect("should be a V1 AST");
5205        let tasks: Vec<_> = ast.tasks().collect();
5206        assert_eq!(tasks.len(), 1);
5207        assert_eq!(tasks[0].name().text(), "test");
5208
5209        // Task declarations
5210        let decls: Vec<_> = tasks[0].declarations().collect();
5211        assert_eq!(decls.len(), 3);
5212
5213        // First declaration
5214        assert_eq!(decls[0].ty().to_string(), "Boolean");
5215        assert_eq!(decls[0].name().text(), "a");
5216        assert!(decls[0].expr().unwrap_literal().unwrap_boolean().value());
5217
5218        // Second declaration
5219        assert_eq!(decls[1].ty().to_string(), "Boolean");
5220        assert_eq!(decls[1].name().text(), "b");
5221        assert!(!decls[1].expr().unwrap_literal().unwrap_boolean().value());
5222
5223        // Third declaration
5224        assert_eq!(decls[2].ty().to_string(), "Boolean");
5225        assert_eq!(decls[2].name().text(), "c");
5226        let (lhs, rhs) = decls[2].expr().unwrap_equality().operands();
5227        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5228        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5229    }
5230
5231    #[test]
5232    fn inequality() {
5233        let (document, diagnostics) = Document::parse(
5234            r#"
5235version 1.1
5236
5237task test {
5238    Boolean a = true
5239    Boolean b = false
5240    Boolean c = a != b
5241}
5242"#,
5243            None,
5244        );
5245
5246        assert!(diagnostics.is_empty());
5247        let ast = document.ast();
5248        let ast = ast.as_v1().expect("should be a V1 AST");
5249        let tasks: Vec<_> = ast.tasks().collect();
5250        assert_eq!(tasks.len(), 1);
5251        assert_eq!(tasks[0].name().text(), "test");
5252
5253        // Task declarations
5254        let decls: Vec<_> = tasks[0].declarations().collect();
5255        assert_eq!(decls.len(), 3);
5256
5257        // First declaration
5258        assert_eq!(decls[0].ty().to_string(), "Boolean");
5259        assert_eq!(decls[0].name().text(), "a");
5260        assert!(decls[0].expr().unwrap_literal().unwrap_boolean().value());
5261
5262        // Second declaration
5263        assert_eq!(decls[1].ty().to_string(), "Boolean");
5264        assert_eq!(decls[1].name().text(), "b");
5265        assert!(!decls[1].expr().unwrap_literal().unwrap_boolean().value());
5266
5267        // Third declaration
5268        assert_eq!(decls[2].ty().to_string(), "Boolean");
5269        assert_eq!(decls[2].name().text(), "c");
5270        let (lhs, rhs) = decls[2].expr().unwrap_inequality().operands();
5271        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5272        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5273    }
5274
5275    #[test]
5276    fn less() {
5277        let (document, diagnostics) = Document::parse(
5278            r#"
5279version 1.1
5280
5281task test {
5282    Int a = 1
5283    Int b = 2
5284    Boolean c = a < b
5285}
5286"#,
5287            None,
5288        );
5289
5290        assert!(diagnostics.is_empty());
5291        let ast = document.ast();
5292        let ast = ast.as_v1().expect("should be a V1 AST");
5293        let tasks: Vec<_> = ast.tasks().collect();
5294        assert_eq!(tasks.len(), 1);
5295        assert_eq!(tasks[0].name().text(), "test");
5296
5297        // Task declarations
5298        let decls: Vec<_> = tasks[0].declarations().collect();
5299        assert_eq!(decls.len(), 3);
5300
5301        // First declaration
5302        assert_eq!(decls[0].ty().to_string(), "Int");
5303        assert_eq!(decls[0].name().text(), "a");
5304        assert_eq!(
5305            decls[0]
5306                .expr()
5307                .unwrap_literal()
5308                .unwrap_integer()
5309                .value()
5310                .unwrap(),
5311            1
5312        );
5313
5314        // Second declaration
5315        assert_eq!(decls[1].ty().to_string(), "Int");
5316        assert_eq!(decls[1].name().text(), "b");
5317        assert_eq!(
5318            decls[1]
5319                .expr()
5320                .unwrap_literal()
5321                .unwrap_integer()
5322                .value()
5323                .unwrap(),
5324            2
5325        );
5326
5327        // Third declaration
5328        assert_eq!(decls[2].ty().to_string(), "Boolean");
5329        assert_eq!(decls[2].name().text(), "c");
5330        let (lhs, rhs) = decls[2].expr().unwrap_less().operands();
5331        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5332        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5333    }
5334
5335    #[test]
5336    fn less_equal() {
5337        let (document, diagnostics) = Document::parse(
5338            r#"
5339version 1.1
5340
5341task test {
5342    Int a = 1
5343    Int b = 2
5344    Boolean c = a <= b
5345}
5346"#,
5347            None,
5348        );
5349
5350        assert!(diagnostics.is_empty());
5351        let ast = document.ast();
5352        let ast = ast.as_v1().expect("should be a V1 AST");
5353        let tasks: Vec<_> = ast.tasks().collect();
5354        assert_eq!(tasks.len(), 1);
5355        assert_eq!(tasks[0].name().text(), "test");
5356
5357        // Task declarations
5358        let decls: Vec<_> = tasks[0].declarations().collect();
5359        assert_eq!(decls.len(), 3);
5360
5361        // First declaration
5362        assert_eq!(decls[0].ty().to_string(), "Int");
5363        assert_eq!(decls[0].name().text(), "a");
5364        assert_eq!(
5365            decls[0]
5366                .expr()
5367                .unwrap_literal()
5368                .unwrap_integer()
5369                .value()
5370                .unwrap(),
5371            1
5372        );
5373
5374        // Second declaration
5375        assert_eq!(decls[1].ty().to_string(), "Int");
5376        assert_eq!(decls[1].name().text(), "b");
5377        assert_eq!(
5378            decls[1]
5379                .expr()
5380                .unwrap_literal()
5381                .unwrap_integer()
5382                .value()
5383                .unwrap(),
5384            2
5385        );
5386
5387        // Third declaration
5388        assert_eq!(decls[2].ty().to_string(), "Boolean");
5389        assert_eq!(decls[2].name().text(), "c");
5390        let (lhs, rhs) = decls[2].expr().unwrap_less_equal().operands();
5391        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5392        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5393    }
5394
5395    #[test]
5396    fn greater() {
5397        let (document, diagnostics) = Document::parse(
5398            r#"
5399version 1.1
5400
5401task test {
5402    Int a = 1
5403    Int b = 2
5404    Boolean c = a > b
5405}
5406"#,
5407            None,
5408        );
5409
5410        assert!(diagnostics.is_empty());
5411        let ast = document.ast();
5412        let ast = ast.as_v1().expect("should be a V1 AST");
5413        let tasks: Vec<_> = ast.tasks().collect();
5414        assert_eq!(tasks.len(), 1);
5415        assert_eq!(tasks[0].name().text(), "test");
5416
5417        // Task declarations
5418        let decls: Vec<_> = tasks[0].declarations().collect();
5419        assert_eq!(decls.len(), 3);
5420
5421        // First declaration
5422        assert_eq!(decls[0].ty().to_string(), "Int");
5423        assert_eq!(decls[0].name().text(), "a");
5424        assert_eq!(
5425            decls[0]
5426                .expr()
5427                .unwrap_literal()
5428                .unwrap_integer()
5429                .value()
5430                .unwrap(),
5431            1
5432        );
5433
5434        // Second declaration
5435        assert_eq!(decls[1].ty().to_string(), "Int");
5436        assert_eq!(decls[1].name().text(), "b");
5437        assert_eq!(
5438            decls[1]
5439                .expr()
5440                .unwrap_literal()
5441                .unwrap_integer()
5442                .value()
5443                .unwrap(),
5444            2
5445        );
5446
5447        // Third declaration
5448        assert_eq!(decls[2].ty().to_string(), "Boolean");
5449        assert_eq!(decls[2].name().text(), "c");
5450        let (lhs, rhs) = decls[2].expr().unwrap_greater().operands();
5451        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5452        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5453    }
5454
5455    #[test]
5456    fn greater_equal() {
5457        let (document, diagnostics) = Document::parse(
5458            r#"
5459version 1.1
5460
5461task test {
5462    Int a = 1
5463    Int b = 2
5464    Boolean c = a >= b
5465}
5466"#,
5467            None,
5468        );
5469
5470        assert!(diagnostics.is_empty());
5471        let ast = document.ast();
5472        let ast = ast.as_v1().expect("should be a V1 AST");
5473        let tasks: Vec<_> = ast.tasks().collect();
5474        assert_eq!(tasks.len(), 1);
5475        assert_eq!(tasks[0].name().text(), "test");
5476
5477        // Task declarations
5478        let decls: Vec<_> = tasks[0].declarations().collect();
5479        assert_eq!(decls.len(), 3);
5480
5481        // First declaration
5482        assert_eq!(decls[0].ty().to_string(), "Int");
5483        assert_eq!(decls[0].name().text(), "a");
5484        assert_eq!(
5485            decls[0]
5486                .expr()
5487                .unwrap_literal()
5488                .unwrap_integer()
5489                .value()
5490                .unwrap(),
5491            1
5492        );
5493
5494        // Second declaration
5495        assert_eq!(decls[1].ty().to_string(), "Int");
5496        assert_eq!(decls[1].name().text(), "b");
5497        assert_eq!(
5498            decls[1]
5499                .expr()
5500                .unwrap_literal()
5501                .unwrap_integer()
5502                .value()
5503                .unwrap(),
5504            2
5505        );
5506
5507        // Third declaration
5508        assert_eq!(decls[2].ty().to_string(), "Boolean");
5509        assert_eq!(decls[2].name().text(), "c");
5510        let (lhs, rhs) = decls[2].expr().unwrap_greater_equal().operands();
5511        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5512        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5513    }
5514
5515    #[test]
5516    fn addition() {
5517        let (document, diagnostics) = Document::parse(
5518            r#"
5519version 1.1
5520
5521task test {
5522    Int a = 1
5523    Int b = 2
5524    Int c = a + b
5525}
5526"#,
5527            None,
5528        );
5529
5530        assert!(diagnostics.is_empty());
5531        let ast = document.ast();
5532        let ast = ast.as_v1().expect("should be a V1 AST");
5533        let tasks: Vec<_> = ast.tasks().collect();
5534        assert_eq!(tasks.len(), 1);
5535        assert_eq!(tasks[0].name().text(), "test");
5536
5537        // Task declarations
5538        let decls: Vec<_> = tasks[0].declarations().collect();
5539        assert_eq!(decls.len(), 3);
5540
5541        // First declaration
5542        assert_eq!(decls[0].ty().to_string(), "Int");
5543        assert_eq!(decls[0].name().text(), "a");
5544        assert_eq!(
5545            decls[0]
5546                .expr()
5547                .unwrap_literal()
5548                .unwrap_integer()
5549                .value()
5550                .unwrap(),
5551            1
5552        );
5553
5554        // Second declaration
5555        assert_eq!(decls[1].ty().to_string(), "Int");
5556        assert_eq!(decls[1].name().text(), "b");
5557        assert_eq!(
5558            decls[1]
5559                .expr()
5560                .unwrap_literal()
5561                .unwrap_integer()
5562                .value()
5563                .unwrap(),
5564            2
5565        );
5566
5567        // Third declaration
5568        assert_eq!(decls[2].ty().to_string(), "Int");
5569        assert_eq!(decls[2].name().text(), "c");
5570        let (lhs, rhs) = decls[2].expr().unwrap_addition().operands();
5571        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5572        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5573    }
5574
5575    #[test]
5576    fn subtraction() {
5577        let (document, diagnostics) = Document::parse(
5578            r#"
5579version 1.1
5580
5581task test {
5582    Int a = 1
5583    Int b = 2
5584    Int c = a - b
5585}
5586"#,
5587            None,
5588        );
5589
5590        assert!(diagnostics.is_empty());
5591        let ast = document.ast();
5592        let ast = ast.as_v1().expect("should be a V1 AST");
5593        let tasks: Vec<_> = ast.tasks().collect();
5594        assert_eq!(tasks.len(), 1);
5595        assert_eq!(tasks[0].name().text(), "test");
5596
5597        // Task declarations
5598        let decls: Vec<_> = tasks[0].declarations().collect();
5599        assert_eq!(decls.len(), 3);
5600
5601        // First declaration
5602        assert_eq!(decls[0].ty().to_string(), "Int");
5603        assert_eq!(decls[0].name().text(), "a");
5604        assert_eq!(
5605            decls[0]
5606                .expr()
5607                .unwrap_literal()
5608                .unwrap_integer()
5609                .value()
5610                .unwrap(),
5611            1
5612        );
5613
5614        // Second declaration
5615        assert_eq!(decls[1].ty().to_string(), "Int");
5616        assert_eq!(decls[1].name().text(), "b");
5617        assert_eq!(
5618            decls[1]
5619                .expr()
5620                .unwrap_literal()
5621                .unwrap_integer()
5622                .value()
5623                .unwrap(),
5624            2
5625        );
5626
5627        // Third declaration
5628        assert_eq!(decls[2].ty().to_string(), "Int");
5629        assert_eq!(decls[2].name().text(), "c");
5630        let (lhs, rhs) = decls[2].expr().unwrap_subtraction().operands();
5631        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5632        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5633    }
5634
5635    #[test]
5636    fn multiplication() {
5637        let (document, diagnostics) = Document::parse(
5638            r#"
5639version 1.1
5640
5641task test {
5642    Int a = 1
5643    Int b = 2
5644    Int c = a * b
5645}
5646"#,
5647            None,
5648        );
5649
5650        assert!(diagnostics.is_empty());
5651        let ast = document.ast();
5652        let ast = ast.as_v1().expect("should be a V1 AST");
5653        let tasks: Vec<_> = ast.tasks().collect();
5654        assert_eq!(tasks.len(), 1);
5655        assert_eq!(tasks[0].name().text(), "test");
5656
5657        // Task declarations
5658        let decls: Vec<_> = tasks[0].declarations().collect();
5659        assert_eq!(decls.len(), 3);
5660
5661        // First declaration
5662        assert_eq!(decls[0].ty().to_string(), "Int");
5663        assert_eq!(decls[0].name().text(), "a");
5664        assert_eq!(
5665            decls[0]
5666                .expr()
5667                .unwrap_literal()
5668                .unwrap_integer()
5669                .value()
5670                .unwrap(),
5671            1
5672        );
5673
5674        // Second declaration
5675        assert_eq!(decls[1].ty().to_string(), "Int");
5676        assert_eq!(decls[1].name().text(), "b");
5677        assert_eq!(
5678            decls[1]
5679                .expr()
5680                .unwrap_literal()
5681                .unwrap_integer()
5682                .value()
5683                .unwrap(),
5684            2
5685        );
5686
5687        // Third declaration
5688        assert_eq!(decls[2].ty().to_string(), "Int");
5689        assert_eq!(decls[2].name().text(), "c");
5690        let (lhs, rhs) = decls[2].expr().unwrap_multiplication().operands();
5691        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5692        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5693    }
5694
5695    #[test]
5696    fn division() {
5697        let (document, diagnostics) = Document::parse(
5698            r#"
5699version 1.1
5700
5701task test {
5702    Int a = 1
5703    Int b = 2
5704    Int c = a / b
5705}
5706"#,
5707            None,
5708        );
5709
5710        assert!(diagnostics.is_empty());
5711        let ast = document.ast();
5712        let ast = ast.as_v1().expect("should be a V1 AST");
5713        let tasks: Vec<_> = ast.tasks().collect();
5714        assert_eq!(tasks.len(), 1);
5715        assert_eq!(tasks[0].name().text(), "test");
5716
5717        // Task declarations
5718        let decls: Vec<_> = tasks[0].declarations().collect();
5719        assert_eq!(decls.len(), 3);
5720
5721        // First declaration
5722        assert_eq!(decls[0].ty().to_string(), "Int");
5723        assert_eq!(decls[0].name().text(), "a");
5724        assert_eq!(
5725            decls[0]
5726                .expr()
5727                .unwrap_literal()
5728                .unwrap_integer()
5729                .value()
5730                .unwrap(),
5731            1
5732        );
5733
5734        // Second declaration
5735        assert_eq!(decls[1].ty().to_string(), "Int");
5736        assert_eq!(decls[1].name().text(), "b");
5737        assert_eq!(
5738            decls[1]
5739                .expr()
5740                .unwrap_literal()
5741                .unwrap_integer()
5742                .value()
5743                .unwrap(),
5744            2
5745        );
5746
5747        // Third declaration
5748        assert_eq!(decls[2].ty().to_string(), "Int");
5749        assert_eq!(decls[2].name().text(), "c");
5750        let (lhs, rhs) = decls[2].expr().unwrap_division().operands();
5751        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5752        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5753    }
5754
5755    #[test]
5756    fn modulo() {
5757        let (document, diagnostics) = Document::parse(
5758            r#"
5759version 1.1
5760
5761task test {
5762    Int a = 1
5763    Int b = 2
5764    Int c = a % b
5765}
5766"#,
5767            None,
5768        );
5769
5770        assert!(diagnostics.is_empty());
5771        let ast = document.ast();
5772        let ast = ast.as_v1().expect("should be a V1 AST");
5773        let tasks: Vec<_> = ast.tasks().collect();
5774        assert_eq!(tasks.len(), 1);
5775        assert_eq!(tasks[0].name().text(), "test");
5776
5777        // Task declarations
5778        let decls: Vec<_> = tasks[0].declarations().collect();
5779        assert_eq!(decls.len(), 3);
5780
5781        // First declaration
5782        assert_eq!(decls[0].ty().to_string(), "Int");
5783        assert_eq!(decls[0].name().text(), "a");
5784        assert_eq!(
5785            decls[0]
5786                .expr()
5787                .unwrap_literal()
5788                .unwrap_integer()
5789                .value()
5790                .unwrap(),
5791            1
5792        );
5793
5794        // Second declaration
5795        assert_eq!(decls[1].ty().to_string(), "Int");
5796        assert_eq!(decls[1].name().text(), "b");
5797        assert_eq!(
5798            decls[1]
5799                .expr()
5800                .unwrap_literal()
5801                .unwrap_integer()
5802                .value()
5803                .unwrap(),
5804            2
5805        );
5806
5807        // Third declaration
5808        assert_eq!(decls[2].ty().to_string(), "Int");
5809        assert_eq!(decls[2].name().text(), "c");
5810        let (lhs, rhs) = decls[2].expr().unwrap_modulo().operands();
5811        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5812        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5813    }
5814
5815    #[test]
5816    fn exponentiation() {
5817        let (document, diagnostics) = Document::parse(
5818            r#"
5819version 1.2
5820
5821task test {
5822    Int a = 2
5823    Int b = 8
5824    Int c = a ** b
5825}
5826"#,
5827            None,
5828        );
5829
5830        assert!(diagnostics.is_empty());
5831        let ast = document.ast();
5832        let ast = ast.as_v1().expect("should be a V1 AST");
5833        let tasks: Vec<_> = ast.tasks().collect();
5834        assert_eq!(tasks.len(), 1);
5835        assert_eq!(tasks[0].name().text(), "test");
5836
5837        // Task declarations
5838        let decls: Vec<_> = tasks[0].declarations().collect();
5839        assert_eq!(decls.len(), 3);
5840
5841        // First declaration
5842        assert_eq!(decls[0].ty().to_string(), "Int");
5843        assert_eq!(decls[0].name().text(), "a");
5844        assert_eq!(
5845            decls[0]
5846                .expr()
5847                .unwrap_literal()
5848                .unwrap_integer()
5849                .value()
5850                .unwrap(),
5851            2
5852        );
5853
5854        // Second declaration
5855        assert_eq!(decls[1].ty().to_string(), "Int");
5856        assert_eq!(decls[1].name().text(), "b");
5857        assert_eq!(
5858            decls[1]
5859                .expr()
5860                .unwrap_literal()
5861                .unwrap_integer()
5862                .value()
5863                .unwrap(),
5864            8
5865        );
5866
5867        // Third declaration
5868        assert_eq!(decls[2].ty().to_string(), "Int");
5869        assert_eq!(decls[2].name().text(), "c");
5870        let (lhs, rhs) = decls[2].expr().unwrap_exponentiation().operands();
5871        assert_eq!(lhs.unwrap_name_ref().name().text(), "a");
5872        assert_eq!(rhs.unwrap_name_ref().name().text(), "b");
5873    }
5874
5875    #[test]
5876    fn call() {
5877        let (document, diagnostics) = Document::parse(
5878            r#"
5879version 1.1
5880
5881task test {
5882    Array[Int] a = [1, 2, 3]
5883    String b = sep(" ", a)
5884}
5885"#,
5886            None,
5887        );
5888
5889        assert!(diagnostics.is_empty());
5890        let ast = document.ast();
5891        let ast = ast.as_v1().expect("should be a V1 AST");
5892        let tasks: Vec<_> = ast.tasks().collect();
5893        assert_eq!(tasks.len(), 1);
5894        assert_eq!(tasks[0].name().text(), "test");
5895
5896        // Task declarations
5897        let decls: Vec<_> = tasks[0].declarations().collect();
5898        assert_eq!(decls.len(), 2);
5899
5900        // First declaration
5901        assert_eq!(decls[0].ty().to_string(), "Array[Int]");
5902        assert_eq!(decls[0].name().text(), "a");
5903        let elements: Vec<_> = decls[0]
5904            .expr()
5905            .unwrap_literal()
5906            .unwrap_array()
5907            .elements()
5908            .collect();
5909        assert_eq!(elements.len(), 3);
5910        assert_eq!(
5911            elements[0]
5912                .clone()
5913                .unwrap_literal()
5914                .unwrap_integer()
5915                .value()
5916                .unwrap(),
5917            1
5918        );
5919        assert_eq!(
5920            elements[1]
5921                .clone()
5922                .unwrap_literal()
5923                .unwrap_integer()
5924                .value()
5925                .unwrap(),
5926            2
5927        );
5928        assert_eq!(
5929            elements[2]
5930                .clone()
5931                .unwrap_literal()
5932                .unwrap_integer()
5933                .value()
5934                .unwrap(),
5935            3
5936        );
5937
5938        // Second declaration
5939        assert_eq!(decls[1].ty().to_string(), "String");
5940        assert_eq!(decls[1].name().text(), "b");
5941        let call = decls[1].expr().unwrap_call();
5942        assert_eq!(call.target().text(), "sep");
5943        let args: Vec<_> = call.arguments().collect();
5944        assert_eq!(args.len(), 2);
5945        assert_eq!(
5946            args[0]
5947                .clone()
5948                .unwrap_literal()
5949                .unwrap_string()
5950                .text()
5951                .unwrap()
5952                .text(),
5953            " "
5954        );
5955        assert_eq!(args[1].clone().unwrap_name_ref().name().text(), "a");
5956    }
5957
5958    #[test]
5959    fn index() {
5960        let (document, diagnostics) = Document::parse(
5961            r#"
5962version 1.1
5963
5964task test {
5965    Array[Int] a = [1, 2, 3]
5966    Int b = a[1]
5967}
5968"#,
5969            None,
5970        );
5971
5972        assert!(diagnostics.is_empty());
5973        let ast = document.ast();
5974        let ast = ast.as_v1().expect("should be a V1 AST");
5975        let tasks: Vec<_> = ast.tasks().collect();
5976        assert_eq!(tasks.len(), 1);
5977        assert_eq!(tasks[0].name().text(), "test");
5978
5979        // Task declarations
5980        let decls: Vec<_> = tasks[0].declarations().collect();
5981        assert_eq!(decls.len(), 2);
5982
5983        // First declaration
5984        assert_eq!(decls[0].ty().to_string(), "Array[Int]");
5985        assert_eq!(decls[0].name().text(), "a");
5986        let elements: Vec<_> = decls[0]
5987            .expr()
5988            .unwrap_literal()
5989            .unwrap_array()
5990            .elements()
5991            .collect();
5992        assert_eq!(elements.len(), 3);
5993        assert_eq!(
5994            elements[0]
5995                .clone()
5996                .unwrap_literal()
5997                .unwrap_integer()
5998                .value()
5999                .unwrap(),
6000            1
6001        );
6002        assert_eq!(
6003            elements[1]
6004                .clone()
6005                .unwrap_literal()
6006                .unwrap_integer()
6007                .value()
6008                .unwrap(),
6009            2
6010        );
6011        assert_eq!(
6012            elements[2]
6013                .clone()
6014                .unwrap_literal()
6015                .unwrap_integer()
6016                .value()
6017                .unwrap(),
6018            3
6019        );
6020
6021        // Second declaration
6022        assert_eq!(decls[1].ty().to_string(), "Int");
6023        assert_eq!(decls[1].name().text(), "b");
6024        let (expr, index) = decls[1].expr().unwrap_index().operands();
6025        assert_eq!(expr.unwrap_name_ref().name().text(), "a");
6026        assert_eq!(index.unwrap_literal().unwrap_integer().value().unwrap(), 1);
6027    }
6028
6029    #[test]
6030    fn access() {
6031        let (document, diagnostics) = Document::parse(
6032            r#"
6033version 1.1
6034
6035task test {
6036    Object a = object { foo: "bar" }
6037    String b = a.foo
6038}
6039"#,
6040            None,
6041        );
6042
6043        assert!(diagnostics.is_empty());
6044        let ast = document.ast();
6045        let ast = ast.as_v1().expect("should be a V1 AST");
6046        let tasks: Vec<_> = ast.tasks().collect();
6047        assert_eq!(tasks.len(), 1);
6048        assert_eq!(tasks[0].name().text(), "test");
6049
6050        // Task declarations
6051        let decls: Vec<_> = tasks[0].declarations().collect();
6052        assert_eq!(decls.len(), 2);
6053
6054        // First declaration
6055        assert_eq!(decls[0].ty().to_string(), "Object");
6056        assert_eq!(decls[0].name().text(), "a");
6057        let items: Vec<_> = decls[0]
6058            .expr()
6059            .unwrap_literal()
6060            .unwrap_object()
6061            .items()
6062            .collect();
6063        assert_eq!(items.len(), 1);
6064        let (name, value) = items[0].name_value();
6065        assert_eq!(name.text(), "foo");
6066        assert_eq!(
6067            value
6068                .unwrap_literal()
6069                .unwrap_string()
6070                .text()
6071                .unwrap()
6072                .text(),
6073            "bar"
6074        );
6075
6076        // Second declaration
6077        assert_eq!(decls[1].ty().to_string(), "String");
6078        assert_eq!(decls[1].name().text(), "b");
6079        let (expr, index) = decls[1].expr().unwrap_access().operands();
6080        assert_eq!(expr.unwrap_name_ref().name().text(), "a");
6081        assert_eq!(index.text(), "foo");
6082    }
6083
6084    #[test]
6085    fn strip_whitespace_on_single_line_string() {
6086        let (document, diagnostics) = Document::parse(
6087            r#"
6088version 1.1
6089
6090task test {
6091    String a = "  foo  "
6092}"#,
6093            None,
6094        );
6095
6096        assert!(diagnostics.is_empty());
6097        let ast = document.ast();
6098        let ast = ast.as_v1().expect("should be a V1 AST");
6099
6100        let tasks: Vec<_> = ast.tasks().collect();
6101        assert_eq!(tasks.len(), 1);
6102
6103        let decls: Vec<_> = tasks[0].declarations().collect();
6104        assert_eq!(decls.len(), 1);
6105
6106        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6107        assert_eq!(expr.text().unwrap().text(), "  foo  ");
6108
6109        let stripped = expr.strip_whitespace();
6110        assert!(stripped.is_none());
6111    }
6112
6113    #[test]
6114    fn strip_whitespace_on_multi_line_string_no_interpolation() {
6115        let (document, diagnostics) = Document::parse(
6116            r#"
6117version 1.2
6118
6119task test {
6120    # all of these strings evaluate to "hello  world"
6121    String hw1 = <<<hello  world>>>
6122    String hw2 = <<<   hello  world   >>>
6123    String hw3 = <<<   
6124        hello  world>>>
6125    String hw4 = <<<   
6126        hello  world
6127        >>>
6128    String hw5 = <<<   
6129        hello  world
6130    >>>
6131    # The line continuation causes the newline and all whitespace preceding 'world' to be 
6132    # removed - to put two spaces between 'hello' and world' we need to put them before 
6133    # the line continuation.
6134    String hw6 = <<<
6135        hello  \
6136            world
6137    >>>
6138}"#,
6139            None,
6140        );
6141
6142        assert!(diagnostics.is_empty());
6143        let ast = document.ast();
6144        let ast = ast.as_v1().expect("should be a V1 AST");
6145
6146        let tasks: Vec<_> = ast.tasks().collect();
6147        assert_eq!(tasks.len(), 1);
6148
6149        let decls: Vec<_> = tasks[0].declarations().collect();
6150        assert_eq!(decls.len(), 6);
6151
6152        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6153        let stripped = expr.strip_whitespace().unwrap();
6154        assert_eq!(stripped.len(), 1);
6155        match &stripped[0] {
6156            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6157            _ => panic!("expected text part"),
6158        }
6159
6160        let expr = decls[1].expr().unwrap_literal().unwrap_string();
6161        let stripped = expr.strip_whitespace().unwrap();
6162        assert_eq!(stripped.len(), 1);
6163        match &stripped[0] {
6164            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6165            _ => panic!("expected text part"),
6166        }
6167
6168        let expr = decls[2].expr().unwrap_literal().unwrap_string();
6169        let stripped = expr.strip_whitespace().unwrap();
6170        assert_eq!(stripped.len(), 1);
6171        match &stripped[0] {
6172            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6173            _ => panic!("expected text part"),
6174        }
6175
6176        let expr = decls[3].expr().unwrap_literal().unwrap_string();
6177        let stripped = expr.strip_whitespace().unwrap();
6178        assert_eq!(stripped.len(), 1);
6179        match &stripped[0] {
6180            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6181            _ => panic!("expected text part"),
6182        }
6183
6184        let expr = decls[4].expr().unwrap_literal().unwrap_string();
6185        let stripped = expr.strip_whitespace().unwrap();
6186        assert_eq!(stripped.len(), 1);
6187        match &stripped[0] {
6188            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6189            _ => panic!("expected text part"),
6190        }
6191
6192        let expr = decls[5].expr().unwrap_literal().unwrap_string();
6193        let stripped = expr.strip_whitespace().unwrap();
6194        assert_eq!(stripped.len(), 1);
6195        match &stripped[0] {
6196            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  world"),
6197            _ => panic!("expected text part"),
6198        }
6199    }
6200
6201    #[test]
6202    fn strip_whitespace_on_multi_line_string_with_interpolation() {
6203        let (document, diagnostics) = Document::parse(
6204            r#"
6205version 1.2
6206
6207task test {
6208    String hw1 = <<<
6209        hello  ${"world"}
6210    >>>
6211    String hw2 = <<<
6212        hello  ${
6213            "world"
6214        }
6215        my name
6216        is \
6217            Jerry\
6218    !
6219    >>>
6220}"#,
6221            None,
6222        );
6223
6224        assert!(diagnostics.is_empty());
6225        let ast = document.ast();
6226        let ast = ast.as_v1().expect("should be a V1 AST");
6227
6228        let tasks: Vec<_> = ast.tasks().collect();
6229        assert_eq!(tasks.len(), 1);
6230
6231        let decls: Vec<_> = tasks[0].declarations().collect();
6232        assert_eq!(decls.len(), 2);
6233
6234        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6235        let stripped = expr.strip_whitespace().unwrap();
6236        assert_eq!(stripped.len(), 3);
6237        match &stripped[0] {
6238            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  "),
6239            _ => panic!("expected text part"),
6240        }
6241        match &stripped[1] {
6242            StrippedStringPart::Placeholder(_) => {}
6243            _ => panic!("expected interpolated part"),
6244        }
6245        match &stripped[2] {
6246            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), ""),
6247            _ => panic!("expected text part"),
6248        }
6249
6250        let expr = decls[1].expr().unwrap_literal().unwrap_string();
6251        let stripped = expr.strip_whitespace().unwrap();
6252        assert_eq!(stripped.len(), 3);
6253        match &stripped[0] {
6254            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "hello  "),
6255            _ => panic!("expected text part"),
6256        }
6257        match &stripped[1] {
6258            StrippedStringPart::Placeholder(_) => {}
6259            _ => panic!("expected interpolated part"),
6260        }
6261        match &stripped[2] {
6262            StrippedStringPart::Text(text) => assert_eq!(text.as_str(), "\nmy name\nis Jerry!"),
6263            _ => panic!("expected text part"),
6264        }
6265    }
6266
6267    #[test]
6268    fn remove_multiple_line_continuations() {
6269        let (document, diagnostics) = Document::parse(
6270            r#"
6271version 1.2
6272
6273task test {
6274    String hw = <<<
6275    hello world \
6276    \
6277    \
6278    my name is Jeff.
6279    >>>
6280}"#,
6281            None,
6282        );
6283
6284        assert!(diagnostics.is_empty());
6285        let ast = document.ast();
6286        let ast = ast.as_v1().expect("should be a V1 AST");
6287
6288        let tasks: Vec<_> = ast.tasks().collect();
6289        assert_eq!(tasks.len(), 1);
6290
6291        let decls: Vec<_> = tasks[0].declarations().collect();
6292        assert_eq!(decls.len(), 1);
6293
6294        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6295        let stripped = expr.strip_whitespace().unwrap();
6296        assert_eq!(stripped.len(), 1);
6297        match &stripped[0] {
6298            StrippedStringPart::Text(text) => {
6299                assert_eq!(text.as_str(), "hello world my name is Jeff.")
6300            }
6301            _ => panic!("expected text part"),
6302        }
6303    }
6304
6305    #[test]
6306    fn strip_whitespace_with_content_on_first_line() {
6307        let (document, diagnostics) = Document::parse(
6308            r#"
6309version 1.2
6310
6311task test {
6312    String hw = <<<    hello world
6313    my name is Jeff.
6314    >>>
6315}"#,
6316            None,
6317        );
6318
6319        assert!(diagnostics.is_empty());
6320        let ast = document.ast();
6321        let ast = ast.as_v1().expect("should be a V1 AST");
6322
6323        let tasks: Vec<_> = ast.tasks().collect();
6324        assert_eq!(tasks.len(), 1);
6325
6326        let decls: Vec<_> = tasks[0].declarations().collect();
6327        assert_eq!(decls.len(), 1);
6328
6329        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6330        let stripped = expr.strip_whitespace().unwrap();
6331        assert_eq!(stripped.len(), 1);
6332        match &stripped[0] {
6333            StrippedStringPart::Text(text) => {
6334                assert_eq!(text.as_str(), "hello world\n    my name is Jeff.")
6335            }
6336            _ => panic!("expected text part"),
6337        }
6338    }
6339
6340    #[test]
6341    fn whitespace_stripping_on_windows() {
6342        let (document, diagnostics) = Document::parse(
6343            "version 1.2\r\ntask test {\r\n    String s = <<<\r\n        hello\r\n    >>>\r\n}\r\n",
6344            None,
6345        );
6346
6347        assert!(diagnostics.is_empty());
6348        let ast = document.ast();
6349        let ast = ast.as_v1().expect("should be a V1 AST");
6350
6351        let tasks: Vec<_> = ast.tasks().collect();
6352        assert_eq!(tasks.len(), 1);
6353
6354        let decls: Vec<_> = tasks[0].declarations().collect();
6355        assert_eq!(decls.len(), 1);
6356
6357        let expr = decls[0].expr().unwrap_literal().unwrap_string();
6358        let stripped = expr.strip_whitespace().unwrap();
6359        assert_eq!(stripped.len(), 1);
6360        match &stripped[0] {
6361            StrippedStringPart::Text(text) => {
6362                assert_eq!(text.as_str(), "hello")
6363            }
6364            _ => panic!("expected text part"),
6365        }
6366    }
6367}