1use wdl_ast::SyntaxKind;
4
5use crate::Config;
6use crate::PreToken;
7use crate::TokenStream;
8use crate::Writable as _;
9use crate::element::FormatElement;
10
11pub fn format_sep_option(
17 element: &FormatElement,
18 stream: &mut TokenStream<PreToken>,
19 config: &Config,
20) {
21 let mut children = element.children().expect("sep option children");
22
23 let sep_keyword = children.next().expect("sep keyword");
24 assert!(sep_keyword.element().kind() == SyntaxKind::Ident);
25 (&sep_keyword).write(stream, config);
26
27 let equals = children.next().expect("sep equals");
28 assert!(equals.element().kind() == SyntaxKind::Assignment);
29 (&equals).write(stream, config);
30
31 let sep_value = children.next().expect("sep value");
32 assert!(sep_value.element().kind() == SyntaxKind::LiteralStringNode);
33 (&sep_value).write(stream, config);
34 stream.end_word();
35}
36
37pub fn format_default_option(
43 element: &FormatElement,
44 stream: &mut TokenStream<PreToken>,
45 config: &Config,
46) {
47 let mut children = element.children().expect("default option children");
48
49 let default_keyword = children.next().expect("default keyword");
50 assert!(default_keyword.element().kind() == SyntaxKind::Ident);
51 (&default_keyword).write(stream, config);
52
53 let equals = children.next().expect("default equals");
54 assert!(equals.element().kind() == SyntaxKind::Assignment);
55 (&equals).write(stream, config);
56
57 let default_value = children.next().expect("default value");
58 (&default_value).write(stream, config);
59 stream.end_word();
60}
61
62pub fn format_true_false_option(
68 element: &FormatElement,
69 stream: &mut TokenStream<PreToken>,
70 config: &Config,
71) {
72 let mut children = element.children().expect("true false option children");
73
74 let first_keyword = children.next().expect("true false option first keyword");
75 let first_keyword_kind = first_keyword.element().kind();
76 assert!(
77 first_keyword_kind == SyntaxKind::TrueKeyword
78 || first_keyword_kind == SyntaxKind::FalseKeyword
79 );
80
81 let first_equals = children.next().expect("true false option first equals");
82 assert!(first_equals.element().kind() == SyntaxKind::Assignment);
83
84 let first_value = children.next().expect("true false option first value");
85
86 let second_keyword = children.next().expect("true false option second keyword");
87 let second_keyword_kind = second_keyword.element().kind();
88 assert!(
89 second_keyword_kind == SyntaxKind::TrueKeyword
90 || second_keyword_kind == SyntaxKind::FalseKeyword
91 );
92
93 let second_equals = children.next().expect("true false option second equals");
94 assert!(second_equals.element().kind() == SyntaxKind::Assignment);
95
96 let second_value = children.next().expect("true false option second value");
97
98 if first_keyword_kind == SyntaxKind::TrueKeyword {
99 assert!(second_keyword_kind == SyntaxKind::FalseKeyword);
100 (&first_keyword).write(stream, config);
101 (&first_equals).write(stream, config);
102 (&first_value).write(stream, config);
103 stream.end_word();
104 (&second_keyword).write(stream, config);
105 (&second_equals).write(stream, config);
106 (&second_value).write(stream, config);
107 } else {
108 assert!(second_keyword_kind == SyntaxKind::TrueKeyword);
109 (&second_keyword).write(stream, config);
110 (&second_equals).write(stream, config);
111 (&second_value).write(stream, config);
112 stream.end_word();
113 (&first_keyword).write(stream, config);
114 (&first_equals).write(stream, config);
115 (&first_value).write(stream, config);
116 }
117 stream.end_word();
118}
119
120pub fn format_placeholder(
126 element: &FormatElement,
127 stream: &mut TokenStream<PreToken>,
128 config: &Config,
129) {
130 let mut children = element.children().expect("placeholder children");
131
132 let open = children.next().expect("placeholder open");
133 assert!(open.element().kind() == SyntaxKind::PlaceholderOpen);
134 let syntax = open.element().inner();
135 let text = syntax.as_token().expect("token").text();
136 match text {
137 "${" => {
138 stream.push_literal_in_place_of_token(
139 open.element().as_token().expect("token"),
140 "~{".to_owned(),
141 );
142 }
143 "~{" => {
144 (&open).write(stream, config);
145 }
146 _ => {
147 unreachable!("unexpected placeholder open: {:?}", text);
148 }
149 }
150
151 for child in children {
152 (&child).write(stream, config);
153 }
154}
155
156pub fn format_literal_string(
162 element: &FormatElement,
163 stream: &mut TokenStream<PreToken>,
164 config: &Config,
165) {
166 for child in element.children().expect("literal string children") {
167 match child.element().kind() {
168 SyntaxKind::SingleQuote => {
169 stream.push_literal_in_place_of_token(
170 child.element().as_token().expect("token"),
171 "\"".to_owned(),
172 );
173 }
174 SyntaxKind::OpenHeredoc | SyntaxKind::CloseHeredoc | SyntaxKind::DoubleQuote => {
175 (&child).write(stream, config);
176 }
177 SyntaxKind::LiteralStringText => {
178 let mut replacement = String::new();
179 let syntax = child.element().inner();
180 let mut chars = syntax.as_token().expect("token").text().chars().peekable();
181 let mut prev_c = None;
182 while let Some(c) = chars.next() {
183 match c {
184 '\\' => {
185 if let Some(next_c) = chars.peek()
186 && *next_c == '\''
187 {
188 prev_c = Some(c);
192 continue;
193 }
194 replacement.push(c);
195 }
196 '"' => {
197 if prev_c.is_none_or(|c| c != '\\') {
198 replacement.push('\\');
202 }
203 replacement.push(c);
204 }
205 _ => {
206 replacement.push(c);
207 }
208 }
209 prev_c = Some(c);
210 }
211
212 stream.push_literal_in_place_of_token(
213 child.element().as_token().expect("token"),
214 replacement,
215 );
216 }
217 SyntaxKind::PlaceholderNode => {
218 (&child).write(stream, config);
219 }
220 _ => {
221 unreachable!(
222 "unexpected child in literal string: {:?}",
223 child.element().kind()
224 );
225 }
226 }
227 }
228}
229
230pub fn format_literal_none(
236 element: &FormatElement,
237 stream: &mut TokenStream<PreToken>,
238 config: &Config,
239) {
240 let mut children = element.children().expect("literal none children");
241 let none = children.next().expect("literal none token");
242 assert!(none.element().kind() == SyntaxKind::NoneKeyword);
243 (&none).write(stream, config);
244}
245
246pub fn format_literal_pair(
252 element: &FormatElement,
253 stream: &mut TokenStream<PreToken>,
254 config: &Config,
255) {
256 let mut children = element.children().expect("literal pair children");
257
258 let open_paren = children.next().expect("literal pair open paren");
259 assert!(open_paren.element().kind() == SyntaxKind::OpenParen);
260 (&open_paren).write(stream, config);
261
262 let left = children.next().expect("literal pair left");
263 (&left).write(stream, config);
264
265 let comma = children.next().expect("literal pair comma");
266 assert!(comma.element().kind() == SyntaxKind::Comma);
267 (&comma).write(stream, config);
268 stream.end_word();
269
270 let right = children.next().expect("literal pair right");
271 (&right).write(stream, config);
272
273 let close_paren = children.next().expect("literal pair close paren");
274 assert!(close_paren.element().kind() == SyntaxKind::CloseParen);
275 (&close_paren).write(stream, config);
276}
277
278pub fn format_literal_boolean(
284 element: &FormatElement,
285 stream: &mut TokenStream<PreToken>,
286 config: &Config,
287) {
288 let mut children = element.children().expect("literal boolean children");
289 let bool = children.next().expect("literal boolean token");
290 (&bool).write(stream, config);
291}
292
293pub fn format_negation_expr(
299 element: &FormatElement,
300 stream: &mut TokenStream<PreToken>,
301 config: &Config,
302) {
303 let mut children = element.children().expect("negation expr children");
304 let minus = children.next().expect("negation expr minus");
305 assert!(minus.element().kind() == SyntaxKind::Minus);
306 (&minus).write(stream, config);
307
308 let expr = children.next().expect("negation expr expr");
309 (&expr).write(stream, config);
310}
311
312pub fn format_literal_integer(
318 element: &FormatElement,
319 stream: &mut TokenStream<PreToken>,
320 config: &Config,
321) {
322 for child in element.children().expect("literal integer children") {
323 (&child).write(stream, config);
324 }
325}
326
327pub fn format_literal_float(
333 element: &FormatElement,
334 stream: &mut TokenStream<PreToken>,
335 config: &Config,
336) {
337 for child in element.children().expect("literal float children") {
338 (&child).write(stream, config);
339 }
340}
341
342pub fn format_name_ref_expr(
348 element: &FormatElement,
349 stream: &mut TokenStream<PreToken>,
350 config: &Config,
351) {
352 let mut children = element.children().expect("name ref children");
353 let name = children.next().expect("name ref name");
354 (&name).write(stream, config);
355}
356
357pub fn format_literal_array(
363 element: &FormatElement,
364 stream: &mut TokenStream<PreToken>,
365 config: &Config,
366) {
367 let mut children = element.children().expect("literal array children");
368
369 let open_bracket = children.next().expect("literal array open bracket");
370 assert!(open_bracket.element().kind() == SyntaxKind::OpenBracket);
371 (&open_bracket).write(stream, config);
372
373 let mut items = Vec::new();
374 let mut commas = Vec::new();
375 let mut close_bracket = None;
376
377 for child in children {
378 match child.element().kind() {
379 SyntaxKind::CloseBracket => {
380 close_bracket = Some(child.to_owned());
381 }
382 SyntaxKind::Comma => {
383 commas.push(child.to_owned());
384 }
385 _ => {
386 items.push(child.to_owned());
387 }
388 }
389 }
390
391 let empty = items.is_empty();
392 if !empty {
393 stream.increment_indent();
394 }
395 let mut commas = commas.iter();
396 for item in items {
397 (&item).write(stream, config);
398 if let Some(comma) = commas.next() {
399 (comma).write(stream, config);
400 } else if config.trailing_commas {
401 stream.push_literal(",".to_string(), SyntaxKind::Comma);
402 }
403 stream.end_line();
404 }
405
406 if !empty {
407 stream.decrement_indent();
408 }
409 (&close_bracket.expect("literal array close bracket")).write(stream, config);
410}
411
412pub fn format_literal_map_item(
418 element: &FormatElement,
419 stream: &mut TokenStream<PreToken>,
420 config: &Config,
421) {
422 let mut children = element.children().expect("literal map item children");
423
424 let key = children.next().expect("literal map item key");
425 (&key).write(stream, config);
426
427 let colon = children.next().expect("literal map item colon");
428 assert!(colon.element().kind() == SyntaxKind::Colon);
429 (&colon).write(stream, config);
430 stream.end_word();
431
432 let value = children.next().expect("literal map item value");
433 (&value).write(stream, config);
434}
435
436pub fn format_literal_map(
442 element: &FormatElement,
443 stream: &mut TokenStream<PreToken>,
444 config: &Config,
445) {
446 let mut children = element.children().expect("literal map children");
447
448 let open_brace = children.next().expect("literal map open brace");
449 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
450 (&open_brace).write(stream, config);
451 stream.increment_indent();
452
453 let mut items = Vec::new();
454 let mut commas = Vec::new();
455 let mut close_brace = None;
456
457 for child in children {
458 match child.element().kind() {
459 SyntaxKind::CloseBrace => {
460 close_brace = Some(child.to_owned());
461 }
462 SyntaxKind::Comma => {
463 commas.push(child.to_owned());
464 }
465 _ => {
466 items.push(child.to_owned());
467 }
468 }
469 }
470
471 let mut commas = commas.iter();
472 for item in items {
473 (&item).write(stream, config);
474 if let Some(comma) = commas.next() {
475 (comma).write(stream, config);
476 } else if config.trailing_commas {
477 stream.push_literal(",".to_string(), SyntaxKind::Comma);
478 }
479 stream.end_line();
480 }
481
482 stream.decrement_indent();
483 (&close_brace.expect("literal map close brace")).write(stream, config);
484}
485
486pub fn format_literal_object_item(
492 element: &FormatElement,
493 stream: &mut TokenStream<PreToken>,
494 config: &Config,
495) {
496 let mut children = element.children().expect("literal object item children");
497
498 let key = children.next().expect("literal object item key");
499 assert!(key.element().kind() == SyntaxKind::Ident);
500 (&key).write(stream, config);
501
502 let colon = children.next().expect("literal object item colon");
503 assert!(colon.element().kind() == SyntaxKind::Colon);
504 (&colon).write(stream, config);
505 stream.end_word();
506
507 let value = children.next().expect("literal object item value");
508 (&value).write(stream, config);
509 assert!(children.next().is_none());
510}
511
512pub fn format_literal_object(
518 element: &FormatElement,
519 stream: &mut TokenStream<PreToken>,
520 config: &Config,
521) {
522 let mut children = element.children().expect("literal object children");
523
524 let object_keyword = children.next().expect("literal object keyword");
525 assert!(object_keyword.element().kind() == SyntaxKind::ObjectKeyword);
526 (&object_keyword).write(stream, config);
527 stream.end_word();
528
529 let open_brace = children.next().expect("literal object open brace");
530 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
531 (&open_brace).write(stream, config);
532 stream.increment_indent();
533
534 let mut members = Vec::new();
535 let mut commas = Vec::new();
536 let mut close_brace = None;
537
538 for child in children {
539 match child.element().kind() {
540 SyntaxKind::CloseBrace => {
541 close_brace = Some(child.to_owned());
542 }
543 SyntaxKind::Comma => {
544 commas.push(child.to_owned());
545 }
546 _ => {
547 members.push(child.to_owned());
548 }
549 }
550 }
551
552 let mut commas = commas.iter();
553 for member in members {
554 (&member).write(stream, config);
555 if let Some(comma) = commas.next() {
556 (comma).write(stream, config);
557 } else if config.trailing_commas {
558 stream.push_literal(",".to_string(), SyntaxKind::Comma);
559 }
560 stream.end_line();
561 }
562
563 stream.decrement_indent();
564 (&close_brace.expect("literal object close brace")).write(stream, config);
565}
566
567pub fn format_access_expr(
573 element: &FormatElement,
574 stream: &mut TokenStream<PreToken>,
575 config: &Config,
576) {
577 for child in element.children().expect("access expr children") {
578 (&child).write(stream, config);
579 }
580}
581
582pub fn format_call_expr(
588 element: &FormatElement,
589 stream: &mut TokenStream<PreToken>,
590 config: &Config,
591) {
592 for child in element.children().expect("call expr children") {
593 (&child).write(stream, config);
594 if child.element().kind() == SyntaxKind::Comma {
595 stream.end_word();
596 }
597 }
598}
599
600pub fn format_index_expr(
606 element: &FormatElement,
607 stream: &mut TokenStream<PreToken>,
608 config: &Config,
609) {
610 for child in element.children().expect("index expr children") {
611 (&child).write(stream, config);
612 }
613}
614
615pub fn format_addition_expr(
621 element: &FormatElement,
622 stream: &mut TokenStream<PreToken>,
623 config: &Config,
624) {
625 for child in element.children().expect("addition expr children") {
626 let whitespace_wrapped = child.element().kind() == SyntaxKind::Plus;
627 if whitespace_wrapped {
628 stream.end_word();
629 }
630 (&child).write(stream, config);
631 if whitespace_wrapped {
632 stream.end_word();
633 }
634 }
635}
636
637pub fn format_subtraction_expr(
643 element: &FormatElement,
644 stream: &mut TokenStream<PreToken>,
645 config: &Config,
646) {
647 for child in element.children().expect("subtraction expr children") {
648 let whitespace_wrapped = child.element().kind() == SyntaxKind::Minus;
649 if whitespace_wrapped {
650 stream.end_word();
651 }
652 (&child).write(stream, config);
653 if whitespace_wrapped {
654 stream.end_word();
655 }
656 }
657}
658
659pub fn format_multiplication_expr(
665 element: &FormatElement,
666 stream: &mut TokenStream<PreToken>,
667 config: &Config,
668) {
669 for child in element.children().expect("multiplication expr children") {
670 let whitespace_wrapped = child.element().kind() == SyntaxKind::Asterisk;
671 if whitespace_wrapped {
672 stream.end_word();
673 }
674 (&child).write(stream, config);
675 if whitespace_wrapped {
676 stream.end_word();
677 }
678 }
679}
680
681pub fn format_division_expr(
687 element: &FormatElement,
688 stream: &mut TokenStream<PreToken>,
689 config: &Config,
690) {
691 for child in element.children().expect("division expr children") {
692 let whitespace_wrapped = child.element().kind() == SyntaxKind::Slash;
693 if whitespace_wrapped {
694 stream.end_word();
695 }
696 (&child).write(stream, config);
697 if whitespace_wrapped {
698 stream.end_word();
699 }
700 }
701}
702
703pub fn format_modulo_expr(
709 element: &FormatElement,
710 stream: &mut TokenStream<PreToken>,
711 config: &Config,
712) {
713 for child in element.children().expect("modulo expr children") {
714 let whitespace_wrapped = child.element().kind() == SyntaxKind::Percent;
715 if whitespace_wrapped {
716 stream.end_word();
717 }
718 (&child).write(stream, config);
719 if whitespace_wrapped {
720 stream.end_word();
721 }
722 }
723}
724
725pub fn format_exponentiation_expr(
731 element: &FormatElement,
732 stream: &mut TokenStream<PreToken>,
733 config: &Config,
734) {
735 for child in element.children().expect("exponentiation expr children") {
736 let whitespace_wrapped = child.element().kind() == SyntaxKind::Exponentiation;
737 if whitespace_wrapped {
738 stream.end_word();
739 }
740 (&child).write(stream, config);
741 if whitespace_wrapped {
742 stream.end_word();
743 }
744 }
745}
746
747pub fn format_logical_and_expr(
753 element: &FormatElement,
754 stream: &mut TokenStream<PreToken>,
755 config: &Config,
756) {
757 for child in element.children().expect("logical and expr children") {
758 let whitespace_wrapped = child.element().kind() == SyntaxKind::LogicalAnd;
759 if whitespace_wrapped {
760 stream.end_word();
761 }
762 (&child).write(stream, config);
763 if whitespace_wrapped {
764 stream.end_word();
765 }
766 }
767}
768
769pub fn format_logical_not_expr(
775 element: &FormatElement,
776 stream: &mut TokenStream<PreToken>,
777 config: &Config,
778) {
779 let mut children = element.children().expect("logical not expr children");
780 let not = children.next().expect("logical not expr not");
781 assert!(not.element().kind() == SyntaxKind::Exclamation);
782 (¬).write(stream, config);
783
784 let expr = children.next().expect("logical not expr expr");
785 (&expr).write(stream, config);
786}
787
788pub fn format_logical_or_expr(
794 element: &FormatElement,
795 stream: &mut TokenStream<PreToken>,
796 config: &Config,
797) {
798 for child in element.children().expect("logical or expr children") {
799 let whitespace_wrapped = child.element().kind() == SyntaxKind::LogicalOr;
800 if whitespace_wrapped {
801 stream.end_word();
802 }
803 (&child).write(stream, config);
804 if whitespace_wrapped {
805 stream.end_word();
806 }
807 }
808}
809
810pub fn format_equality_expr(
816 element: &FormatElement,
817 stream: &mut TokenStream<PreToken>,
818 config: &Config,
819) {
820 for child in element.children().expect("equality expr children") {
821 let whitespace_wrapped = child.element().kind() == SyntaxKind::Equal;
822 if whitespace_wrapped {
823 stream.end_word();
824 }
825 (&child).write(stream, config);
826 if whitespace_wrapped {
827 stream.end_word();
828 }
829 }
830}
831
832pub fn format_inequality_expr(
838 element: &FormatElement,
839 stream: &mut TokenStream<PreToken>,
840 config: &Config,
841) {
842 for child in element.children().expect("inequality expr children") {
843 let whitespace_wrapped = child.element().kind() == SyntaxKind::NotEqual;
844 if whitespace_wrapped {
845 stream.end_word();
846 }
847 (&child).write(stream, config);
848 if whitespace_wrapped {
849 stream.end_word();
850 }
851 }
852}
853
854pub fn format_less_expr(
860 element: &FormatElement,
861 stream: &mut TokenStream<PreToken>,
862 config: &Config,
863) {
864 for child in element.children().expect("less expr children") {
865 let whitespace_wrapped = child.element().kind() == SyntaxKind::Less;
866 if whitespace_wrapped {
867 stream.end_word();
868 }
869 (&child).write(stream, config);
870 if whitespace_wrapped {
871 stream.end_word();
872 }
873 }
874}
875
876pub fn format_less_equal_expr(
882 element: &FormatElement,
883 stream: &mut TokenStream<PreToken>,
884 config: &Config,
885) {
886 for child in element.children().expect("less equal expr children") {
887 let whitespace_wrapped = child.element().kind() == SyntaxKind::LessEqual;
888 if whitespace_wrapped {
889 stream.end_word();
890 }
891 (&child).write(stream, config);
892 if whitespace_wrapped {
893 stream.end_word();
894 }
895 }
896}
897
898pub fn format_greater_expr(
904 element: &FormatElement,
905 stream: &mut TokenStream<PreToken>,
906 config: &Config,
907) {
908 for child in element.children().expect("greater expr children") {
909 let whitespace_wrapped = child.element().kind() == SyntaxKind::Greater;
910 if whitespace_wrapped {
911 stream.end_word();
912 }
913 (&child).write(stream, config);
914 if whitespace_wrapped {
915 stream.end_word();
916 }
917 }
918}
919
920pub fn format_greater_equal_expr(
926 element: &FormatElement,
927 stream: &mut TokenStream<PreToken>,
928 config: &Config,
929) {
930 for child in element.children().expect("greater equal expr children") {
931 let whitespace_wrapped = child.element().kind() == SyntaxKind::GreaterEqual;
932 if whitespace_wrapped {
933 stream.end_word();
934 }
935 (&child).write(stream, config);
936 if whitespace_wrapped {
937 stream.end_word();
938 }
939 }
940}
941
942pub fn format_parenthesized_expr(
948 element: &FormatElement,
949 stream: &mut TokenStream<PreToken>,
950 config: &Config,
951) {
952 for child in element.children().expect("parenthesized expr children") {
953 (&child).write(stream, config);
954 }
955}
956
957pub fn format_if_expr(
963 element: &FormatElement,
964 stream: &mut TokenStream<PreToken>,
965 config: &Config,
966) {
967 let in_chain = {
968 let mut cur = element.element().inner();
969 let mut result = false;
970 while let Some(prev) = cur.prev_sibling_or_token() {
971 cur = prev;
972 if cur.kind().is_trivia() {
973 continue;
974 }
975 result = cur.kind() == SyntaxKind::ElseKeyword;
976 break;
977 }
978 result
979 };
980
981 for child in element.children().expect("if expr children") {
982 match child.element().kind() {
983 SyntaxKind::ThenKeyword => {
984 if !in_chain {
985 stream.increment_indent();
986 } else {
987 stream.end_line();
988 }
989 }
990 SyntaxKind::ElseKeyword => {
991 stream.end_line();
992 }
993 _ => {}
994 }
995 (&child).write(stream, config);
996 stream.end_word();
997 }
998
999 if !in_chain {
1000 stream.decrement_indent();
1001 }
1002}