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