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