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