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