1use crate::SyntaxKind::{
8 self, AMP, AMP_AMP, BANG, BANG_EQ, BANG_QUESTION, CARET, COLON, DIVERT, DOLLAR, EQ, EQ_EQ,
9 FLOAT, GT, GT_EQ, HASH, IDENT, INTEGER, KW_AND, KW_CYCLE, KW_DONE, KW_ELSE, KW_END, KW_FALSE,
10 KW_FUNCTION, KW_HAS, KW_HASNT, KW_MOD, KW_NOT, KW_ONCE, KW_OR, KW_REF, KW_SHUFFLE, KW_STOPPING,
11 KW_TODO, KW_TRUE, L_PAREN, LT, LT_EQ, MINUS, MINUS_EQ, NEWLINE, PERCENT, PIPE, PLUS, PLUS_EQ,
12 QUESTION, R_PAREN, SLASH, STAR, TILDE,
13};
14use crate::ast::AstNode as _;
15use crate::ast::ast_node;
16use crate::ast::support;
17use crate::{SyntaxNode, SyntaxToken};
18
19ast_node!(SourceFile, SOURCE_FILE);
22ast_node!(IncludeStmt, INCLUDE_STMT);
23ast_node!(ImportStmt, IMPORT_STMT);
24ast_node!(ImportList, IMPORT_LIST);
25ast_node!(ImportItem, IMPORT_ITEM);
26ast_node!(ImportModule, IMPORT_MODULE);
27ast_node!(FilePath, FILE_PATH);
28ast_node!(ExternalDecl, EXTERNAL_DECL);
29
30ast_node!(KnotDef, KNOT_DEF);
33ast_node!(KnotHeader, KNOT_HEADER);
34ast_node!(KnotBody, KNOT_BODY);
35ast_node!(KnotParams, KNOT_PARAMS);
36ast_node!(KnotParamDecl, KNOT_PARAM_DECL);
37ast_node!(StitchDef, STITCH_DEF);
38ast_node!(StitchHeader, STITCH_HEADER);
39ast_node!(StitchBody, STITCH_BODY);
40
41ast_node!(EmptyLine, EMPTY_LINE);
44ast_node!(AuthorWarning, AUTHOR_WARNING);
45ast_node!(LogicLine, LOGIC_LINE);
46ast_node!(ContentLine, CONTENT_LINE);
47ast_node!(TagLine, TAG_LINE);
48ast_node!(AnnotationLine, ANNOTATION_LINE);
49ast_node!(StrayClosingBrace, STRAY_CLOSING_BRACE);
50
51ast_node!(ReturnStmt, RETURN_STMT);
54ast_node!(TempDecl, TEMP_DECL);
55ast_node!(Assignment, ASSIGNMENT);
56ast_node!(AwaitStmt, AWAIT_STMT);
57
58ast_node!(MixedContent, MIXED_CONTENT);
61ast_node!(Text, TEXT);
62ast_node!(Escape, ESCAPE);
63ast_node!(GlueNode, GLUE_NODE);
64
65ast_node!(Choice, CHOICE);
68ast_node!(ChoiceBullets, CHOICE_BULLETS);
69ast_node!(Label, LABEL);
70ast_node!(ChoiceCondition, CHOICE_CONDITION);
71ast_node!(ChoiceStartContent, CHOICE_START_CONTENT);
72ast_node!(ChoiceBracketContent, CHOICE_BRACKET_CONTENT);
73ast_node!(ChoiceInnerContent, CHOICE_INNER_CONTENT);
74
75ast_node!(Gather, GATHER);
78ast_node!(GatherDashes, GATHER_DASHES);
79
80ast_node!(Tags, TAGS);
83ast_node!(Tag, TAG);
84
85ast_node!(InlineLogic, INLINE_LOGIC);
88ast_node!(MultilineBlock, MULTILINE_BLOCK);
89ast_node!(SequenceWithAnnotation, SEQUENCE_WITH_ANNOTATION);
90ast_node!(SequenceSymbolAnnotation, SEQUENCE_SYMBOL_ANNOTATION);
91ast_node!(SequenceWordAnnotation, SEQUENCE_WORD_ANNOTATION);
92ast_node!(InlineBranchesSeq, INLINE_BRANCHES_SEQ);
93ast_node!(MultilineBranchesSeq, MULTILINE_BRANCHES_SEQ);
94ast_node!(MultilineBranchSeq, MULTILINE_BRANCH_SEQ);
95ast_node!(BranchContent, BRANCH_CONTENT);
96
97ast_node!(ConditionalWithExpr, CONDITIONAL_WITH_EXPR);
100ast_node!(BranchlessCondBody, BRANCHLESS_COND_BODY);
101ast_node!(ElseBranch, ELSE_BRANCH);
102ast_node!(InlineBranchesCond, INLINE_BRANCHES_COND);
103ast_node!(MultilineBranchesCond, MULTILINE_BRANCHES_COND);
104ast_node!(MultilineConditional, MULTILINE_CONDITIONAL);
105ast_node!(MultilineBranchCond, MULTILINE_BRANCH_COND);
106ast_node!(MultilineBranchBody, MULTILINE_BRANCH_BODY);
107ast_node!(ImplicitSequence, IMPLICIT_SEQUENCE);
108
109ast_node!(InnerExpression, INNER_EXPRESSION);
112ast_node!(PrefixExpr, PREFIX_EXPR);
113ast_node!(PostfixExpr, POSTFIX_EXPR);
114ast_node!(InfixExpr, INFIX_EXPR);
115ast_node!(ParenExpr, PAREN_EXPR);
116ast_node!(FunctionCall, FUNCTION_CALL);
117ast_node!(ArgList, ARG_LIST);
118ast_node!(DivertTargetExpr, DIVERT_TARGET_EXPR);
119ast_node!(ListExpr, LIST_EXPR);
120
121ast_node!(ArrayLiteral, ARRAY_LITERAL);
124ast_node!(MapLiteral, MAP_LITERAL);
125ast_node!(MapEntry, MAP_ENTRY);
126ast_node!(IndexExpr, INDEX_EXPR);
127ast_node!(RangeExpr, RANGE_EXPR);
128
129ast_node!(StmtBlock, STMT_BLOCK);
132ast_node!(IfStmt, IF_STMT);
133ast_node!(ElseClause, ELSE_CLAUSE);
134ast_node!(WhileStmt, WHILE_STMT);
135ast_node!(ForStmt, FOR_STMT);
136ast_node!(BreakStmt, BREAK_STMT);
137ast_node!(ContinueStmt, CONTINUE_STMT);
138ast_node!(ExprStmt, EXPR_STMT);
139
140ast_node!(TypeAnnotation, TYPE_ANNOTATION);
143ast_node!(TypeExpr, TYPE_EXPR);
144ast_node!(TypeName, TYPE_NAME);
145ast_node!(TypeGeneric, TYPE_GENERIC);
146ast_node!(TypeFn, TYPE_FN);
147
148ast_node!(StructDecl, STRUCT_DECL);
151ast_node!(StructFieldDecl, STRUCT_FIELD_DECL);
152ast_node!(StructLiteral, STRUCT_LITERAL);
153ast_node!(StructFieldInit, STRUCT_FIELD_INIT);
154ast_node!(FieldAccessExpr, FIELD_ACCESS_EXPR);
155
156ast_node!(FnLiteral, FN_LITERAL);
159
160ast_node!(RefExpr, REF_EXPR);
163
164ast_node!(CallExpr, CALL_EXPR);
167
168ast_node!(DivertNode, DIVERT_NODE);
171ast_node!(SimpleDivert, SIMPLE_DIVERT);
172ast_node!(DivertTargetWithArgs, DIVERT_TARGET_WITH_ARGS);
173ast_node!(ThreadStart, THREAD_START);
174ast_node!(TunnelOnwardsNode, TUNNEL_ONWARDS_NODE);
175ast_node!(TunnelCallNode, TUNNEL_CALL_NODE);
176
177impl TypeAnnotation {
180 pub fn type_expr(&self) -> Option<TypeExpr> {
182 support::child(&self.syntax)
183 }
184}
185
186pub enum TypeExprKind {
188 Name(TypeName),
189 Generic(TypeGeneric),
190 Fn(TypeFn),
191}
192
193impl TypeExpr {
194 pub fn kind(&self) -> Option<TypeExprKind> {
200 if let Some(n) = support::child::<TypeName>(&self.syntax) {
201 Some(TypeExprKind::Name(n))
202 } else if let Some(g) = support::child::<TypeGeneric>(&self.syntax) {
203 Some(TypeExprKind::Generic(g))
204 } else {
205 support::child::<TypeFn>(&self.syntax).map(TypeExprKind::Fn)
206 }
207 }
208}
209
210impl TypeName {
211 pub fn identifier(&self) -> Option<Identifier> {
212 support::child(&self.syntax)
213 }
214
215 pub fn name(&self) -> Option<String> {
218 self.identifier().and_then(|id| id.name())
219 }
220}
221
222impl TypeGeneric {
223 pub fn identifier(&self) -> Option<Identifier> {
224 support::child(&self.syntax)
225 }
226
227 pub fn name(&self) -> Option<String> {
229 self.identifier().and_then(|id| id.name())
230 }
231
232 pub fn args(&self) -> impl Iterator<Item = TypeExpr> {
234 support::children(&self.syntax)
235 }
236}
237
238impl TypeFn {
239 fn type_exprs(&self) -> Vec<TypeExpr> {
242 support::children(&self.syntax).collect()
243 }
244
245 pub fn params(&self) -> Vec<TypeExpr> {
247 let mut exprs = self.type_exprs();
248 if exprs.is_empty() {
249 return exprs;
250 }
251 exprs.pop(); exprs
253 }
254
255 pub fn return_type(&self) -> Option<TypeExpr> {
257 self.type_exprs().pop()
258 }
259}
260
261ast_node!(Identifier, IDENTIFIER);
264ast_node!(Path, PATH);
265
266ast_node!(VarDecl, VAR_DECL);
269ast_node!(ConstDecl, CONST_DECL);
270ast_node!(ListDecl, LIST_DECL);
271ast_node!(ListDef, LIST_DEF);
272ast_node!(ListMember, LIST_MEMBER);
273ast_node!(ListMemberOn, LIST_MEMBER_ON);
274ast_node!(ListMemberOff, LIST_MEMBER_OFF);
275ast_node!(FunctionParamList, FUNCTION_PARAM_LIST);
276
277ast_node!(IntegerLit, INTEGER_LIT);
280ast_node!(FloatLit, FLOAT_LIT);
281ast_node!(StringLit, STRING_LIT);
282ast_node!(BooleanLit, BOOLEAN_LIT);
283
284ast_node!(Error, ERROR);
287
288#[derive(Clone, PartialEq, Eq, Hash)]
294pub enum Expr {
295 Prefix(PrefixExpr),
296 Postfix(PostfixExpr),
297 Infix(InfixExpr),
298 Paren(ParenExpr),
299 FunctionCall(FunctionCall),
300 IntegerLit(IntegerLit),
301 FloatLit(FloatLit),
302 StringLit(StringLit),
303 BooleanLit(BooleanLit),
304 Path(Path),
305 ListExpr(ListExpr),
306 DivertTarget(DivertTargetExpr),
307 ArrayLiteral(ArrayLiteral),
309 MapLiteral(MapLiteral),
311 Index(IndexExpr),
313 StructLiteral(StructLiteral),
316 FieldAccess(FieldAccessExpr),
320 FnLiteral(FnLiteral),
323 RefExpr(RefExpr),
328 ComputedCall(CallExpr),
336 Range(RangeExpr),
339}
340
341impl std::fmt::Debug for Expr {
342 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343 std::fmt::Debug::fmt(self.syntax(), f)
344 }
345}
346
347impl std::fmt::Display for Expr {
348 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
349 std::fmt::Display::fmt(&self.syntax().text(), f)
350 }
351}
352
353impl crate::ast::AstNode for Expr {
354 fn can_cast(kind: SyntaxKind) -> bool {
355 matches!(
356 kind,
357 SyntaxKind::PREFIX_EXPR
358 | SyntaxKind::POSTFIX_EXPR
359 | SyntaxKind::INFIX_EXPR
360 | SyntaxKind::PAREN_EXPR
361 | SyntaxKind::FUNCTION_CALL
362 | SyntaxKind::INTEGER_LIT
363 | SyntaxKind::FLOAT_LIT
364 | SyntaxKind::STRING_LIT
365 | SyntaxKind::BOOLEAN_LIT
366 | SyntaxKind::PATH
367 | SyntaxKind::LIST_EXPR
368 | SyntaxKind::DIVERT_TARGET_EXPR
369 | SyntaxKind::ARRAY_LITERAL
370 | SyntaxKind::MAP_LITERAL
371 | SyntaxKind::INDEX_EXPR
372 | SyntaxKind::STRUCT_LITERAL
373 | SyntaxKind::FIELD_ACCESS_EXPR
374 | SyntaxKind::FN_LITERAL
375 | SyntaxKind::REF_EXPR
376 | SyntaxKind::CALL_EXPR
377 | SyntaxKind::RANGE_EXPR
378 )
379 }
380
381 fn cast(node: SyntaxNode) -> Option<Self> {
382 match node.kind() {
383 SyntaxKind::PREFIX_EXPR => PrefixExpr::cast(node).map(Expr::Prefix),
384 SyntaxKind::POSTFIX_EXPR => PostfixExpr::cast(node).map(Expr::Postfix),
385 SyntaxKind::INFIX_EXPR => InfixExpr::cast(node).map(Expr::Infix),
386 SyntaxKind::PAREN_EXPR => ParenExpr::cast(node).map(Expr::Paren),
387 SyntaxKind::FUNCTION_CALL => FunctionCall::cast(node).map(Expr::FunctionCall),
388 SyntaxKind::INTEGER_LIT => IntegerLit::cast(node).map(Expr::IntegerLit),
389 SyntaxKind::FLOAT_LIT => FloatLit::cast(node).map(Expr::FloatLit),
390 SyntaxKind::STRING_LIT => StringLit::cast(node).map(Expr::StringLit),
391 SyntaxKind::BOOLEAN_LIT => BooleanLit::cast(node).map(Expr::BooleanLit),
392 SyntaxKind::PATH => Path::cast(node).map(Expr::Path),
393 SyntaxKind::LIST_EXPR => ListExpr::cast(node).map(Expr::ListExpr),
394 SyntaxKind::DIVERT_TARGET_EXPR => DivertTargetExpr::cast(node).map(Expr::DivertTarget),
395 SyntaxKind::ARRAY_LITERAL => ArrayLiteral::cast(node).map(Expr::ArrayLiteral),
396 SyntaxKind::MAP_LITERAL => MapLiteral::cast(node).map(Expr::MapLiteral),
397 SyntaxKind::INDEX_EXPR => IndexExpr::cast(node).map(Expr::Index),
398 SyntaxKind::STRUCT_LITERAL => StructLiteral::cast(node).map(Expr::StructLiteral),
399 SyntaxKind::FIELD_ACCESS_EXPR => FieldAccessExpr::cast(node).map(Expr::FieldAccess),
400 SyntaxKind::FN_LITERAL => FnLiteral::cast(node).map(Expr::FnLiteral),
401 SyntaxKind::REF_EXPR => RefExpr::cast(node).map(Expr::RefExpr),
402 SyntaxKind::CALL_EXPR => CallExpr::cast(node).map(Expr::ComputedCall),
403 SyntaxKind::RANGE_EXPR => RangeExpr::cast(node).map(Expr::Range),
404 _ => None,
405 }
406 }
407
408 fn syntax(&self) -> &SyntaxNode {
409 match self {
410 Expr::Prefix(n) => n.syntax(),
411 Expr::Postfix(n) => n.syntax(),
412 Expr::Infix(n) => n.syntax(),
413 Expr::Paren(n) => n.syntax(),
414 Expr::FunctionCall(n) => n.syntax(),
415 Expr::IntegerLit(n) => n.syntax(),
416 Expr::FloatLit(n) => n.syntax(),
417 Expr::StringLit(n) => n.syntax(),
418 Expr::BooleanLit(n) => n.syntax(),
419 Expr::Path(n) => n.syntax(),
420 Expr::ListExpr(n) => n.syntax(),
421 Expr::DivertTarget(n) => n.syntax(),
422 Expr::ArrayLiteral(n) => n.syntax(),
423 Expr::MapLiteral(n) => n.syntax(),
424 Expr::Index(n) => n.syntax(),
425 Expr::StructLiteral(n) => n.syntax(),
426 Expr::FieldAccess(n) => n.syntax(),
427 Expr::FnLiteral(n) => n.syntax(),
428 Expr::RefExpr(n) => n.syntax(),
429 Expr::ComputedCall(n) => n.syntax(),
430 Expr::Range(n) => n.syntax(),
431 }
432 }
433}
434
435macro_rules! content_node_accessors {
440 ($name:ident) => {
441 impl $name {
442 pub fn texts(&self) -> impl Iterator<Item = Text> {
443 support::children(&self.syntax)
444 }
445
446 pub fn inline_logics(&self) -> impl Iterator<Item = InlineLogic> {
447 support::children(&self.syntax)
448 }
449
450 pub fn glue_nodes(&self) -> impl Iterator<Item = GlueNode> {
451 support::children(&self.syntax)
452 }
453
454 pub fn escapes(&self) -> impl Iterator<Item = Escape> {
455 support::children(&self.syntax)
456 }
457 }
458 };
459}
460
461content_node_accessors!(ChoiceStartContent);
462content_node_accessors!(ChoiceBracketContent);
463content_node_accessors!(ChoiceInnerContent);
464content_node_accessors!(BranchContent);
465
466impl SourceFile {
473 pub fn knots(&self) -> impl Iterator<Item = KnotDef> {
474 support::children(&self.syntax)
475 }
476
477 pub fn includes(&self) -> impl Iterator<Item = IncludeStmt> {
478 support::children(&self.syntax)
479 }
480
481 pub fn imports(&self) -> impl Iterator<Item = ImportStmt> {
483 support::children(&self.syntax)
484 }
485
486 pub fn externals(&self) -> impl Iterator<Item = ExternalDecl> {
487 support::children(&self.syntax)
488 }
489
490 pub fn stitches(&self) -> impl Iterator<Item = StitchDef> {
491 support::children(&self.syntax)
492 }
493
494 pub fn var_decls(&self) -> impl Iterator<Item = VarDecl> {
495 support::children(&self.syntax)
496 }
497
498 pub fn const_decls(&self) -> impl Iterator<Item = ConstDecl> {
499 support::children(&self.syntax)
500 }
501
502 pub fn list_decls(&self) -> impl Iterator<Item = ListDecl> {
503 support::children(&self.syntax)
504 }
505
506 pub fn struct_decls(&self) -> impl Iterator<Item = StructDecl> {
511 support::children(&self.syntax)
512 }
513
514 pub fn content_lines(&self) -> impl Iterator<Item = ContentLine> {
515 support::children(&self.syntax)
516 }
517
518 pub fn logic_lines(&self) -> impl Iterator<Item = LogicLine> {
519 support::children(&self.syntax)
520 }
521
522 pub fn choices(&self) -> impl Iterator<Item = Choice> {
523 support::children(&self.syntax)
524 }
525
526 pub fn gathers(&self) -> impl Iterator<Item = Gather> {
527 support::children(&self.syntax)
528 }
529}
530
531impl IncludeStmt {
534 pub fn file_path(&self) -> Option<FilePath> {
535 support::child(&self.syntax)
536 }
537}
538
539impl ImportStmt {
542 pub fn list(&self) -> Option<ImportList> {
546 support::child(&self.syntax)
547 }
548
549 pub fn module(&self) -> Option<ImportModule> {
551 support::child(&self.syntax)
552 }
553}
554
555impl ImportList {
556 pub fn items(&self) -> impl Iterator<Item = ImportItem> {
557 support::children(&self.syntax)
558 }
559}
560
561impl ImportItem {
562 fn identifiers(&self) -> impl Iterator<Item = Identifier> {
566 support::children(&self.syntax)
567 }
568
569 pub fn name(&self) -> Option<String> {
571 self.identifiers().next().and_then(|id| id.name())
572 }
573
574 pub fn alias(&self) -> Option<String> {
576 self.identifiers().nth(1).and_then(|id| id.name())
577 }
578}
579
580impl ImportModule {
581 pub fn name(&self) -> Option<String> {
582 support::child::<Identifier>(&self.syntax).and_then(|id| id.name())
583 }
584}
585
586impl FilePath {
589 pub fn text(&self) -> String {
591 self.syntax.text().to_string()
592 }
593}
594
595impl ExternalDecl {
598 pub fn identifier(&self) -> Option<Identifier> {
599 support::child(&self.syntax)
600 }
601
602 pub fn name(&self) -> Option<String> {
603 self.identifier().and_then(|id| id.name())
604 }
605
606 pub fn param_list(&self) -> Option<FunctionParamList> {
607 support::child(&self.syntax)
608 }
609}
610
611impl KnotDef {
614 pub fn header(&self) -> Option<KnotHeader> {
615 support::child(&self.syntax)
616 }
617
618 pub fn body(&self) -> Option<KnotBody> {
619 support::child(&self.syntax)
620 }
621}
622
623impl KnotHeader {
626 pub fn function_kw(&self) -> Option<SyntaxToken> {
627 support::token(&self.syntax, KW_FUNCTION)
628 }
629
630 pub fn is_function(&self) -> bool {
631 self.function_kw().is_some()
632 }
633
634 pub fn identifier(&self) -> Option<Identifier> {
635 support::child(&self.syntax)
636 }
637
638 pub fn name(&self) -> Option<String> {
639 self.identifier().and_then(|id| id.name())
640 }
641
642 pub fn params(&self) -> Option<KnotParams> {
643 support::child(&self.syntax)
644 }
645
646 pub fn return_type(&self) -> Option<TypeAnnotation> {
649 support::child(&self.syntax)
650 }
651}
652
653impl KnotBody {
656 pub fn stitches(&self) -> impl Iterator<Item = StitchDef> {
657 support::children(&self.syntax)
658 }
659
660 pub fn content_lines(&self) -> impl Iterator<Item = ContentLine> {
661 support::children(&self.syntax)
662 }
663
664 pub fn logic_lines(&self) -> impl Iterator<Item = LogicLine> {
665 support::children(&self.syntax)
666 }
667
668 pub fn choices(&self) -> impl Iterator<Item = Choice> {
669 support::children(&self.syntax)
670 }
671
672 pub fn gathers(&self) -> impl Iterator<Item = Gather> {
673 support::children(&self.syntax)
674 }
675}
676
677impl KnotParams {
680 pub fn params(&self) -> impl Iterator<Item = KnotParamDecl> {
681 support::children(&self.syntax)
682 }
683}
684
685impl KnotParamDecl {
688 pub fn divert_token(&self) -> Option<SyntaxToken> {
689 support::token(&self.syntax, DIVERT)
690 }
691
692 pub fn is_divert(&self) -> bool {
693 self.divert_token().is_some()
694 }
695
696 pub fn ref_kw(&self) -> Option<SyntaxToken> {
697 support::token(&self.syntax, KW_REF)
698 }
699
700 pub fn is_ref(&self) -> bool {
701 self.ref_kw().is_some()
702 }
703
704 pub fn identifier(&self) -> Option<Identifier> {
705 support::child(&self.syntax)
706 }
707
708 pub fn name(&self) -> Option<String> {
709 self.identifier().and_then(|id| id.name())
710 }
711
712 pub fn type_annotation(&self) -> Option<TypeAnnotation> {
715 support::child(&self.syntax)
716 }
717}
718
719impl StitchDef {
722 pub fn header(&self) -> Option<StitchHeader> {
723 support::child(&self.syntax)
724 }
725
726 pub fn body(&self) -> Option<StitchBody> {
727 support::child(&self.syntax)
728 }
729}
730
731impl StitchHeader {
734 pub fn identifier(&self) -> Option<Identifier> {
735 support::child(&self.syntax)
736 }
737
738 pub fn name(&self) -> Option<String> {
739 self.identifier().and_then(|id| id.name())
740 }
741
742 pub fn params(&self) -> Option<KnotParams> {
743 support::child(&self.syntax)
744 }
745
746 pub fn return_type(&self) -> Option<TypeAnnotation> {
751 support::child(&self.syntax)
752 }
753}
754
755impl StitchBody {
758 pub fn content_lines(&self) -> impl Iterator<Item = ContentLine> {
759 support::children(&self.syntax)
760 }
761
762 pub fn logic_lines(&self) -> impl Iterator<Item = LogicLine> {
763 support::children(&self.syntax)
764 }
765
766 pub fn choices(&self) -> impl Iterator<Item = Choice> {
767 support::children(&self.syntax)
768 }
769
770 pub fn gathers(&self) -> impl Iterator<Item = Gather> {
771 support::children(&self.syntax)
772 }
773}
774
775impl ContentLine {
778 pub fn mixed_content(&self) -> Option<MixedContent> {
779 support::child(&self.syntax)
780 }
781
782 pub fn divert(&self) -> Option<DivertNode> {
783 support::child(&self.syntax)
784 }
785
786 pub fn tags(&self) -> Option<Tags> {
787 support::child(&self.syntax)
788 }
789}
790
791impl LogicLine {
794 pub fn return_stmt(&self) -> Option<ReturnStmt> {
795 support::child(&self.syntax)
796 }
797
798 pub fn temp_decl(&self) -> Option<TempDecl> {
799 support::child(&self.syntax)
800 }
801
802 pub fn assignment(&self) -> Option<Assignment> {
803 support::child(&self.syntax)
804 }
805
806 pub fn await_stmt(&self) -> Option<AwaitStmt> {
809 support::child(&self.syntax)
810 }
811
812 pub fn stmt_block(&self) -> Option<StmtBlock> {
815 support::child(&self.syntax)
816 }
817}
818
819impl TagLine {
822 pub fn tags(&self) -> Option<Tags> {
823 support::child(&self.syntax)
824 }
825}
826
827impl AnnotationLine {
830 pub fn name_token(&self) -> Option<SyntaxToken> {
833 self.syntax
834 .children_with_tokens()
835 .filter_map(rowan::NodeOrToken::into_token)
836 .find(|t| t.kind() == IDENT)
837 }
838
839 pub fn arg_text(&self) -> Option<String> {
845 let mut depth = 0usize;
846 let mut collecting = false;
847 let mut out = String::new();
848 for el in self.syntax.children_with_tokens() {
849 let rowan::NodeOrToken::Token(tok) = el else {
850 continue;
851 };
852 match tok.kind() {
853 L_PAREN => {
854 if collecting {
855 out.push_str(tok.text());
856 }
857 depth += 1;
858 collecting = true;
859 }
860 R_PAREN => {
861 depth = depth.saturating_sub(1);
862 if depth == 0 {
863 return Some(out);
864 }
865 out.push_str(tok.text());
866 }
867 _ if collecting => out.push_str(tok.text()),
868 _ => {}
869 }
870 }
871 collecting.then_some(out)
872 }
873}
874
875impl ReturnStmt {
878 pub fn value(&self) -> Option<Expr> {
883 support::child(&self.syntax)
884 }
885
886 pub fn has_value(&self) -> bool {
888 self.value().is_some()
889 }
890}
891
892impl AwaitStmt {
895 pub fn condition(&self) -> Option<Expr> {
899 self.syntax.children().find_map(Expr::cast)
900 }
901}
902
903impl TempDecl {
906 pub fn identifier(&self) -> Option<Identifier> {
907 support::child(&self.syntax)
908 }
909
910 pub fn name(&self) -> Option<String> {
911 self.identifier().and_then(|id| id.name())
912 }
913
914 pub fn type_annotation(&self) -> Option<TypeAnnotation> {
917 support::child(&self.syntax)
918 }
919
920 pub fn eq_token(&self) -> Option<SyntaxToken> {
921 support::token(&self.syntax, EQ)
922 }
923
924 pub fn value(&self) -> Option<Expr> {
926 support::child(&self.syntax)
927 }
928}
929
930impl Assignment {
933 pub fn target(&self) -> Option<Expr> {
934 self.syntax.children().find_map(Expr::cast)
935 }
936
937 pub fn op_token(&self) -> Option<SyntaxToken> {
939 self.syntax
940 .children_with_tokens()
941 .filter_map(rowan::NodeOrToken::into_token)
942 .find(|tok| matches!(tok.kind(), EQ | PLUS_EQ | MINUS_EQ))
943 }
944
945 pub fn value(&self) -> Option<Expr> {
947 self.syntax.children().filter_map(Expr::cast).nth(1)
948 }
949}
950
951#[derive(Clone, PartialEq, Eq, Hash)]
961pub enum BlockStmt {
962 TempDecl(TempDecl),
963 Assignment(Assignment),
964 Return(ReturnStmt),
965 If(IfStmt),
966 While(WhileStmt),
967 For(ForStmt),
968 Break(BreakStmt),
969 Continue(ContinueStmt),
970 ExprStmt(ExprStmt),
971 Await(AwaitStmt),
974}
975
976impl std::fmt::Debug for BlockStmt {
977 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
978 std::fmt::Debug::fmt(self.syntax(), f)
979 }
980}
981
982impl crate::ast::AstNode for BlockStmt {
983 fn can_cast(kind: SyntaxKind) -> bool {
984 matches!(
985 kind,
986 SyntaxKind::TEMP_DECL
987 | SyntaxKind::ASSIGNMENT
988 | SyntaxKind::RETURN_STMT
989 | SyntaxKind::IF_STMT
990 | SyntaxKind::WHILE_STMT
991 | SyntaxKind::FOR_STMT
992 | SyntaxKind::BREAK_STMT
993 | SyntaxKind::CONTINUE_STMT
994 | SyntaxKind::EXPR_STMT
995 | SyntaxKind::AWAIT_STMT
996 )
997 }
998
999 fn cast(node: SyntaxNode) -> Option<Self> {
1000 match node.kind() {
1001 SyntaxKind::TEMP_DECL => TempDecl::cast(node).map(BlockStmt::TempDecl),
1002 SyntaxKind::ASSIGNMENT => Assignment::cast(node).map(BlockStmt::Assignment),
1003 SyntaxKind::RETURN_STMT => ReturnStmt::cast(node).map(BlockStmt::Return),
1004 SyntaxKind::IF_STMT => IfStmt::cast(node).map(BlockStmt::If),
1005 SyntaxKind::WHILE_STMT => WhileStmt::cast(node).map(BlockStmt::While),
1006 SyntaxKind::FOR_STMT => ForStmt::cast(node).map(BlockStmt::For),
1007 SyntaxKind::BREAK_STMT => BreakStmt::cast(node).map(BlockStmt::Break),
1008 SyntaxKind::CONTINUE_STMT => ContinueStmt::cast(node).map(BlockStmt::Continue),
1009 SyntaxKind::EXPR_STMT => ExprStmt::cast(node).map(BlockStmt::ExprStmt),
1010 SyntaxKind::AWAIT_STMT => AwaitStmt::cast(node).map(BlockStmt::Await),
1011 _ => None,
1012 }
1013 }
1014
1015 fn syntax(&self) -> &SyntaxNode {
1016 match self {
1017 BlockStmt::TempDecl(n) => n.syntax(),
1018 BlockStmt::Assignment(n) => n.syntax(),
1019 BlockStmt::Return(n) => n.syntax(),
1020 BlockStmt::If(n) => n.syntax(),
1021 BlockStmt::While(n) => n.syntax(),
1022 BlockStmt::For(n) => n.syntax(),
1023 BlockStmt::Break(n) => n.syntax(),
1024 BlockStmt::Continue(n) => n.syntax(),
1025 BlockStmt::ExprStmt(n) => n.syntax(),
1026 BlockStmt::Await(n) => n.syntax(),
1027 }
1028 }
1029}
1030
1031impl StmtBlock {
1034 pub fn stmts(&self) -> impl Iterator<Item = BlockStmt> {
1036 support::children(&self.syntax)
1037 }
1038}
1039
1040impl IfStmt {
1043 pub fn condition(&self) -> Option<Expr> {
1045 self.syntax.children().find_map(Expr::cast)
1046 }
1047
1048 pub fn body(&self) -> Option<StmtBlock> {
1050 support::child(&self.syntax)
1051 }
1052
1053 pub fn else_clause(&self) -> Option<ElseClause> {
1055 support::child(&self.syntax)
1056 }
1057}
1058
1059impl ElseClause {
1062 pub fn if_stmt(&self) -> Option<IfStmt> {
1064 support::child(&self.syntax)
1065 }
1066
1067 pub fn body(&self) -> Option<StmtBlock> {
1070 support::child(&self.syntax)
1071 }
1072}
1073
1074impl WhileStmt {
1077 pub fn condition(&self) -> Option<Expr> {
1078 self.syntax.children().find_map(Expr::cast)
1079 }
1080
1081 pub fn body(&self) -> Option<StmtBlock> {
1082 support::child(&self.syntax)
1083 }
1084
1085 pub fn is_await(&self) -> bool {
1092 self.syntax
1093 .children_with_tokens()
1094 .filter_map(rowan::NodeOrToken::into_token)
1095 .any(|tok| tok.kind() == SyntaxKind::IDENT && tok.text() == "await")
1096 }
1097}
1098
1099impl ForStmt {
1102 pub fn identifier(&self) -> Option<Identifier> {
1104 support::child(&self.syntax)
1105 }
1106
1107 pub fn name(&self) -> Option<String> {
1108 self.identifier().and_then(|id| id.name())
1109 }
1110
1111 pub fn iterable(&self) -> Option<Expr> {
1113 self.syntax.children().find_map(Expr::cast)
1114 }
1115
1116 pub fn body(&self) -> Option<StmtBlock> {
1117 support::child(&self.syntax)
1118 }
1119}
1120
1121impl ExprStmt {
1124 pub fn expr(&self) -> Option<Expr> {
1125 support::child(&self.syntax)
1126 }
1127}
1128
1129impl ArrayLiteral {
1136 pub fn elements(&self) -> impl Iterator<Item = Expr> {
1137 support::children(&self.syntax)
1138 }
1139}
1140
1141impl MapLiteral {
1144 pub fn entries(&self) -> impl Iterator<Item = MapEntry> {
1145 support::children(&self.syntax)
1146 }
1147}
1148
1149impl MapEntry {
1152 pub fn key(&self) -> Option<Expr> {
1154 self.syntax.children().find_map(Expr::cast)
1155 }
1156
1157 pub fn value(&self) -> Option<Expr> {
1159 self.syntax.children().filter_map(Expr::cast).nth(1)
1160 }
1161}
1162
1163impl IndexExpr {
1166 pub fn base(&self) -> Option<Expr> {
1168 self.syntax.children().find_map(Expr::cast)
1169 }
1170
1171 pub fn index(&self) -> Option<Expr> {
1173 self.syntax.children().filter_map(Expr::cast).nth(1)
1174 }
1175}
1176
1177impl RangeExpr {
1180 pub fn start(&self) -> Option<Expr> {
1182 self.syntax.children().find_map(Expr::cast)
1183 }
1184
1185 pub fn end(&self) -> Option<Expr> {
1187 self.syntax.children().filter_map(Expr::cast).nth(1)
1188 }
1189
1190 pub fn is_inclusive(&self) -> bool {
1193 self.syntax
1194 .children_with_tokens()
1195 .filter_map(rowan::NodeOrToken::into_token)
1196 .any(|t| t.kind() == SyntaxKind::EQ)
1197 }
1198}
1199
1200impl StructDecl {
1207 pub fn identifier(&self) -> Option<Identifier> {
1208 support::child(&self.syntax)
1209 }
1210
1211 pub fn name(&self) -> Option<String> {
1212 self.identifier().and_then(|id| id.name())
1213 }
1214
1215 pub fn fields(&self) -> impl Iterator<Item = StructFieldDecl> {
1217 support::children(&self.syntax)
1218 }
1219}
1220
1221impl StructFieldDecl {
1224 pub fn identifier(&self) -> Option<Identifier> {
1225 support::child(&self.syntax)
1226 }
1227
1228 pub fn name(&self) -> Option<String> {
1229 self.identifier().and_then(|id| id.name())
1230 }
1231
1232 pub fn type_expr(&self) -> Option<TypeExpr> {
1235 support::child(&self.syntax)
1236 }
1237}
1238
1239impl StructLiteral {
1242 pub fn identifier(&self) -> Option<Identifier> {
1244 support::child(&self.syntax)
1245 }
1246
1247 pub fn shape_name(&self) -> Option<String> {
1248 self.identifier().and_then(|id| id.name())
1249 }
1250
1251 pub fn fields(&self) -> impl Iterator<Item = StructFieldInit> {
1253 support::children(&self.syntax)
1254 }
1255}
1256
1257impl StructFieldInit {
1260 pub fn identifier(&self) -> Option<Identifier> {
1261 support::child(&self.syntax)
1262 }
1263
1264 pub fn name(&self) -> Option<String> {
1265 self.identifier().and_then(|id| id.name())
1266 }
1267
1268 pub fn value(&self) -> Option<Expr> {
1270 support::child(&self.syntax)
1271 }
1272}
1273
1274impl FieldAccessExpr {
1277 pub fn base(&self) -> Option<Expr> {
1280 self.syntax.children().find_map(Expr::cast)
1281 }
1282
1283 pub fn field(&self) -> Option<Identifier> {
1285 support::child(&self.syntax)
1286 }
1287
1288 pub fn field_name(&self) -> Option<String> {
1289 self.field().and_then(|id| id.name())
1290 }
1291}
1292
1293impl FnLiteral {
1300 pub fn target(&self) -> Option<Path> {
1303 support::child(&self.syntax)
1304 }
1305
1306 pub fn args(&self) -> impl Iterator<Item = Expr> {
1310 let target_node = self.target().map(|t| t.syntax().clone());
1311 self.syntax
1312 .children()
1313 .filter_map(Expr::cast)
1314 .filter(move |e| Some(e.syntax()) != target_node.as_ref())
1315 }
1316}
1317
1318impl RefExpr {
1325 pub fn ref_kw(&self) -> Option<SyntaxToken> {
1326 support::token(&self.syntax, KW_REF)
1327 }
1328
1329 pub fn operand(&self) -> Option<Expr> {
1333 support::child(&self.syntax)
1334 }
1335}
1336
1337impl MixedContent {
1340 pub fn texts(&self) -> impl Iterator<Item = Text> {
1341 support::children(&self.syntax)
1342 }
1343
1344 pub fn glue_nodes(&self) -> impl Iterator<Item = GlueNode> {
1345 support::children(&self.syntax)
1346 }
1347
1348 pub fn inline_logics(&self) -> impl Iterator<Item = InlineLogic> {
1349 support::children(&self.syntax)
1350 }
1351
1352 pub fn escapes(&self) -> impl Iterator<Item = Escape> {
1353 support::children(&self.syntax)
1354 }
1355}
1356
1357impl Choice {
1360 pub fn bullets(&self) -> Option<ChoiceBullets> {
1361 support::child(&self.syntax)
1362 }
1363
1364 pub fn label(&self) -> Option<Label> {
1365 support::child(&self.syntax)
1366 }
1367
1368 pub fn conditions(&self) -> impl Iterator<Item = ChoiceCondition> {
1369 support::children(&self.syntax)
1370 }
1371
1372 pub fn start_content(&self) -> Option<ChoiceStartContent> {
1373 support::child(&self.syntax)
1374 }
1375
1376 pub fn bracket_content(&self) -> Option<ChoiceBracketContent> {
1377 support::child(&self.syntax)
1378 }
1379
1380 pub fn inner_content(&self) -> Option<ChoiceInnerContent> {
1381 support::child(&self.syntax)
1382 }
1383
1384 pub fn divert(&self) -> Option<DivertNode> {
1385 support::child(&self.syntax)
1386 }
1387
1388 pub fn tags(&self) -> Option<Tags> {
1389 support::child(&self.syntax)
1390 }
1391
1392 pub fn all_tags(&self) -> impl Iterator<Item = Tags> {
1395 support::children(&self.syntax)
1396 }
1397}
1398
1399impl ChoiceBullets {
1402 pub fn depth(&self) -> usize {
1404 self.syntax
1405 .children_with_tokens()
1406 .filter_map(rowan::NodeOrToken::into_token)
1407 .filter(|tok| matches!(tok.kind(), STAR | PLUS))
1408 .count()
1409 }
1410
1411 pub fn is_sticky(&self) -> bool {
1416 self.syntax
1417 .children_with_tokens()
1418 .filter_map(rowan::NodeOrToken::into_token)
1419 .find(|tok| matches!(tok.kind(), STAR | PLUS))
1420 .is_some_and(|tok| tok.kind() == PLUS)
1421 }
1422
1423 pub fn is_mixed(&self) -> bool {
1427 let mut has_star = false;
1428 let mut has_plus = false;
1429 for tok in self
1430 .syntax
1431 .children_with_tokens()
1432 .filter_map(rowan::NodeOrToken::into_token)
1433 {
1434 match tok.kind() {
1435 STAR => has_star = true,
1436 PLUS => has_plus = true,
1437 _ => {}
1438 }
1439 }
1440 has_star && has_plus
1441 }
1442}
1443
1444impl Label {
1447 pub fn identifier(&self) -> Option<Identifier> {
1448 support::child(&self.syntax)
1449 }
1450
1451 pub fn name(&self) -> Option<String> {
1452 self.identifier().and_then(|id| id.name())
1453 }
1454}
1455
1456impl Gather {
1459 pub fn dashes(&self) -> Option<GatherDashes> {
1460 support::child(&self.syntax)
1461 }
1462
1463 pub fn label(&self) -> Option<Label> {
1464 support::child(&self.syntax)
1465 }
1466
1467 pub fn mixed_content(&self) -> Option<MixedContent> {
1468 support::child(&self.syntax)
1469 }
1470
1471 pub fn choice(&self) -> Option<Choice> {
1473 support::child(&self.syntax)
1474 }
1475
1476 pub fn divert(&self) -> Option<DivertNode> {
1477 support::child(&self.syntax)
1478 }
1479
1480 pub fn tags(&self) -> Option<Tags> {
1481 support::child(&self.syntax)
1482 }
1483}
1484
1485impl GatherDashes {
1488 pub fn depth(&self) -> usize {
1490 support::tokens(&self.syntax, MINUS).count()
1491 }
1492}
1493
1494impl Tags {
1497 pub fn tags(&self) -> impl Iterator<Item = Tag> {
1498 support::children(&self.syntax)
1499 }
1500}
1501
1502impl Tag {
1505 pub fn text(&self) -> String {
1510 self.syntax
1511 .children_with_tokens()
1512 .filter_map(rowan::NodeOrToken::into_token)
1513 .filter(|tok| tok.kind() != HASH)
1514 .map(|tok| tok.text().to_string())
1515 .collect::<String>()
1516 .trim()
1517 .to_string()
1518 }
1519}
1520
1521impl InlineLogic {
1524 pub fn inner_expression(&self) -> Option<InnerExpression> {
1525 support::child(&self.syntax)
1526 }
1527
1528 pub fn conditional(&self) -> Option<ConditionalWithExpr> {
1529 support::child(&self.syntax)
1530 }
1531
1532 pub fn sequence(&self) -> Option<SequenceWithAnnotation> {
1533 support::child(&self.syntax)
1534 }
1535
1536 pub fn implicit_sequence(&self) -> Option<ImplicitSequence> {
1537 support::child(&self.syntax)
1538 }
1539
1540 pub fn multiline_conditional(&self) -> Option<MultilineConditional> {
1541 support::child(&self.syntax)
1542 }
1543}
1544
1545impl MultilineBlock {
1548 pub fn conditional(&self) -> Option<ConditionalWithExpr> {
1549 support::child(&self.syntax)
1550 }
1551
1552 pub fn sequence(&self) -> Option<SequenceWithAnnotation> {
1553 support::child(&self.syntax)
1554 }
1555
1556 pub fn branches_cond(&self) -> Option<MultilineBranchesCond> {
1557 support::child(&self.syntax)
1558 }
1559}
1560
1561impl SequenceWithAnnotation {
1564 pub fn symbol_annotation(&self) -> Option<SequenceSymbolAnnotation> {
1565 support::child(&self.syntax)
1566 }
1567
1568 pub fn word_annotation(&self) -> Option<SequenceWordAnnotation> {
1569 support::child(&self.syntax)
1570 }
1571
1572 pub fn inline_branches(&self) -> Option<InlineBranchesSeq> {
1573 support::child(&self.syntax)
1574 }
1575
1576 pub fn multiline_branches(&self) -> Option<MultilineBranchesSeq> {
1577 support::child(&self.syntax)
1578 }
1579}
1580
1581impl SequenceSymbolAnnotation {
1584 pub fn amp_token(&self) -> Option<SyntaxToken> {
1585 support::token(&self.syntax, AMP)
1586 }
1587
1588 pub fn bang_token(&self) -> Option<SyntaxToken> {
1589 support::token(&self.syntax, BANG)
1590 }
1591
1592 pub fn tilde_token(&self) -> Option<SyntaxToken> {
1593 support::token(&self.syntax, TILDE)
1594 }
1595
1596 pub fn dollar_token(&self) -> Option<SyntaxToken> {
1597 support::token(&self.syntax, DOLLAR)
1598 }
1599}
1600
1601impl SequenceWordAnnotation {
1604 pub fn stopping_kw(&self) -> Option<SyntaxToken> {
1605 support::token(&self.syntax, KW_STOPPING)
1606 }
1607
1608 pub fn cycle_kw(&self) -> Option<SyntaxToken> {
1609 support::token(&self.syntax, KW_CYCLE)
1610 }
1611
1612 pub fn shuffle_kw(&self) -> Option<SyntaxToken> {
1613 support::token(&self.syntax, KW_SHUFFLE)
1614 }
1615
1616 pub fn once_kw(&self) -> Option<SyntaxToken> {
1617 support::token(&self.syntax, KW_ONCE)
1618 }
1619}
1620
1621impl InlineBranchesSeq {
1624 pub fn branches(&self) -> impl Iterator<Item = BranchContent> {
1625 support::children(&self.syntax)
1626 }
1627}
1628
1629impl InlineBranchesCond {
1632 pub fn branches(&self) -> impl Iterator<Item = BranchContent> {
1633 support::children(&self.syntax)
1634 }
1635}
1636
1637impl MultilineBranchesSeq {
1640 pub fn branches(&self) -> impl Iterator<Item = MultilineBranchSeq> {
1641 support::children(&self.syntax)
1642 }
1643}
1644
1645impl MultilineBranchesCond {
1648 pub fn branches(&self) -> impl Iterator<Item = MultilineBranchCond> {
1649 support::children(&self.syntax)
1650 }
1651}
1652
1653impl MultilineBranchSeq {
1656 pub fn body(&self) -> Option<MultilineBranchBody> {
1657 support::child(&self.syntax)
1658 }
1659}
1660
1661impl MultilineBranchCond {
1664 pub fn condition(&self) -> Option<Expr> {
1666 support::child(&self.syntax)
1667 }
1668
1669 pub fn body(&self) -> Option<MultilineBranchBody> {
1670 support::child(&self.syntax)
1671 }
1672
1673 pub fn else_kw(&self) -> Option<SyntaxToken> {
1674 support::token(&self.syntax, KW_ELSE)
1675 }
1676
1677 pub fn is_else(&self) -> bool {
1678 self.else_kw().is_some()
1679 }
1680}
1681
1682impl ConditionalWithExpr {
1685 pub fn condition(&self) -> Option<Expr> {
1687 support::child(&self.syntax)
1688 }
1689
1690 pub fn inline_branches(&self) -> Option<InlineBranchesCond> {
1691 support::child(&self.syntax)
1692 }
1693
1694 pub fn multiline_branches(&self) -> Option<MultilineBranchesCond> {
1695 support::child(&self.syntax)
1696 }
1697
1698 pub fn branchless_body(&self) -> Option<BranchlessCondBody> {
1699 support::child(&self.syntax)
1700 }
1701}
1702
1703impl BranchlessCondBody {
1706 pub fn texts(&self) -> impl Iterator<Item = Text> {
1707 support::children(&self.syntax)
1708 }
1709
1710 pub fn inline_logics(&self) -> impl Iterator<Item = InlineLogic> {
1711 support::children(&self.syntax)
1712 }
1713
1714 pub fn glue_nodes(&self) -> impl Iterator<Item = GlueNode> {
1715 support::children(&self.syntax)
1716 }
1717
1718 pub fn escapes(&self) -> impl Iterator<Item = Escape> {
1719 support::children(&self.syntax)
1720 }
1721
1722 pub fn logic_lines(&self) -> impl Iterator<Item = LogicLine> {
1723 support::children(&self.syntax)
1724 }
1725
1726 pub fn divert(&self) -> Option<DivertNode> {
1727 support::child(&self.syntax)
1728 }
1729
1730 pub fn content_lines(&self) -> impl Iterator<Item = ContentLine> {
1731 support::children(&self.syntax)
1732 }
1733
1734 pub fn else_branch(&self) -> Option<ElseBranch> {
1735 support::child(&self.syntax)
1736 }
1737}
1738
1739impl ElseBranch {
1742 pub fn branch(&self) -> Option<MultilineBranchCond> {
1743 support::child(&self.syntax)
1744 }
1745}
1746
1747impl MultilineConditional {
1750 pub fn branches(&self) -> impl Iterator<Item = MultilineBranchCond> {
1751 support::children(&self.syntax)
1752 }
1753}
1754
1755impl ImplicitSequence {
1758 pub fn branches(&self) -> impl Iterator<Item = BranchContent> {
1759 support::children(&self.syntax)
1760 }
1761}
1762
1763impl PrefixExpr {
1766 pub fn op_token(&self) -> Option<SyntaxToken> {
1767 self.syntax
1768 .children_with_tokens()
1769 .filter_map(rowan::NodeOrToken::into_token)
1770 .find(|tok| matches!(tok.kind(), MINUS | BANG | KW_NOT))
1771 }
1772
1773 pub fn operand(&self) -> Option<Expr> {
1775 support::child(&self.syntax)
1776 }
1777}
1778
1779impl PostfixExpr {
1782 pub fn op_token(&self) -> Option<SyntaxToken> {
1785 self.syntax
1786 .children_with_tokens()
1787 .filter_map(rowan::NodeOrToken::into_token)
1788 .find(|tok| matches!(tok.kind(), PLUS | MINUS))
1789 }
1790
1791 pub fn operand(&self) -> Option<Expr> {
1793 support::child(&self.syntax)
1794 }
1795}
1796
1797impl InfixExpr {
1800 pub fn op_token(&self) -> Option<SyntaxToken> {
1801 self.syntax
1802 .children_with_tokens()
1803 .filter_map(rowan::NodeOrToken::into_token)
1804 .find(|tok| {
1805 matches!(
1806 tok.kind(),
1807 PLUS | MINUS
1808 | STAR
1809 | SLASH
1810 | PERCENT
1811 | CARET
1812 | EQ_EQ
1813 | BANG_EQ
1814 | LT
1815 | GT
1816 | LT_EQ
1817 | GT_EQ
1818 | KW_AND
1819 | AMP_AMP
1820 | KW_OR
1821 | PIPE
1822 | KW_MOD
1823 | KW_HAS
1824 | KW_HASNT
1825 | QUESTION
1826 | BANG_QUESTION
1827 | PLUS_EQ
1828 | MINUS_EQ
1829 )
1830 })
1831 }
1832
1833 pub fn lhs(&self) -> Option<Expr> {
1834 self.syntax.children().find_map(Expr::cast)
1835 }
1836
1837 pub fn rhs(&self) -> Option<Expr> {
1838 self.syntax.children().filter_map(Expr::cast).nth(1)
1839 }
1840}
1841
1842impl FunctionCall {
1845 pub fn identifier(&self) -> Option<Identifier> {
1846 support::child(&self.syntax)
1847 }
1848
1849 pub fn name(&self) -> Option<String> {
1850 self.identifier().and_then(|id| id.name())
1851 }
1852
1853 pub fn arg_list(&self) -> Option<ArgList> {
1854 support::child(&self.syntax)
1855 }
1856}
1857
1858impl CallExpr {
1861 pub fn callee(&self) -> Option<Expr> {
1865 self.syntax.children().find_map(Expr::cast)
1866 }
1867
1868 pub fn arg_list(&self) -> Option<ArgList> {
1869 support::child(&self.syntax)
1870 }
1871}
1872
1873impl ArgList {
1876 pub fn arg_count(&self) -> usize {
1878 self.syntax
1879 .children()
1880 .filter(|child| child.kind() != SyntaxKind::ERROR)
1881 .count()
1882 }
1883
1884 pub fn args(&self) -> impl Iterator<Item = Expr> {
1886 support::children(&self.syntax)
1887 }
1888}
1889
1890impl DivertTargetExpr {
1893 pub fn target(&self) -> Option<Path> {
1894 support::child(&self.syntax)
1895 }
1896}
1897
1898impl ListExpr {
1901 pub fn items(&self) -> impl Iterator<Item = Path> {
1902 support::children(&self.syntax)
1903 }
1904}
1905
1906impl DivertNode {
1909 pub fn thread_start(&self) -> Option<ThreadStart> {
1910 support::child(&self.syntax)
1911 }
1912
1913 pub fn tunnel_onwards(&self) -> Option<TunnelOnwardsNode> {
1914 support::child(&self.syntax)
1915 }
1916
1917 pub fn tunnel_call(&self) -> Option<TunnelCallNode> {
1918 support::child(&self.syntax)
1919 }
1920
1921 pub fn simple_divert(&self) -> Option<SimpleDivert> {
1922 support::child(&self.syntax)
1923 }
1924}
1925
1926impl SimpleDivert {
1929 pub fn targets(&self) -> impl Iterator<Item = DivertTargetWithArgs> {
1930 support::children(&self.syntax)
1931 }
1932}
1933
1934impl DivertTargetWithArgs {
1937 pub fn path(&self) -> Option<Path> {
1938 support::child(&self.syntax)
1939 }
1940
1941 pub fn done_kw(&self) -> Option<SyntaxToken> {
1942 support::token(&self.syntax, KW_DONE)
1943 }
1944
1945 pub fn end_kw(&self) -> Option<SyntaxToken> {
1946 support::token(&self.syntax, KW_END)
1947 }
1948
1949 pub fn arg_list(&self) -> Option<ArgList> {
1950 support::child(&self.syntax)
1951 }
1952}
1953
1954impl ThreadStart {
1957 pub fn target(&self) -> Option<Path> {
1962 support::child(&self.syntax)
1963 }
1964
1965 pub fn arg_list(&self) -> Option<ArgList> {
1966 support::child(&self.syntax)
1967 }
1968}
1969
1970impl TunnelOnwardsNode {
1973 pub fn targets(&self) -> impl Iterator<Item = DivertTargetWithArgs> {
1974 support::children(&self.syntax)
1975 }
1976
1977 pub fn tunnel_call(&self) -> Option<TunnelCallNode> {
1978 support::child(&self.syntax)
1979 }
1980}
1981
1982impl TunnelCallNode {
1985 pub fn targets(&self) -> impl Iterator<Item = DivertTargetWithArgs> {
1986 support::children(&self.syntax)
1987 }
1988}
1989
1990impl Identifier {
1993 pub fn ident_token(&self) -> Option<SyntaxToken> {
1994 support::token(&self.syntax, IDENT)
1995 }
1996
1997 pub fn name(&self) -> Option<String> {
2000 self.ident_token()
2001 .or_else(|| {
2002 self.syntax
2003 .children_with_tokens()
2004 .filter_map(rowan::NodeOrToken::into_token)
2005 .find(|t| t.kind().is_keyword())
2006 })
2007 .map(|t| t.text().to_string())
2008 }
2009}
2010
2011impl Path {
2014 pub fn segments(&self) -> impl Iterator<Item = SyntaxToken> {
2016 self.syntax
2017 .children_with_tokens()
2018 .filter_map(rowan::NodeOrToken::into_token)
2019 .filter(|t| t.kind() == IDENT || t.kind().is_keyword())
2020 }
2021
2022 pub fn full_name(&self) -> String {
2024 self.segments()
2025 .map(|t| t.text().to_string())
2026 .collect::<Vec<_>>()
2027 .join(".")
2028 }
2029}
2030
2031impl VarDecl {
2034 pub fn identifier(&self) -> Option<Identifier> {
2035 support::child(&self.syntax)
2036 }
2037
2038 pub fn name(&self) -> Option<String> {
2039 self.identifier().and_then(|id| id.name())
2040 }
2041
2042 pub fn type_annotation(&self) -> Option<TypeAnnotation> {
2045 support::child(&self.syntax)
2046 }
2047
2048 pub fn value(&self) -> Option<Expr> {
2050 support::child(&self.syntax)
2051 }
2052}
2053
2054impl ConstDecl {
2057 pub fn identifier(&self) -> Option<Identifier> {
2058 support::child(&self.syntax)
2059 }
2060
2061 pub fn name(&self) -> Option<String> {
2062 self.identifier().and_then(|id| id.name())
2063 }
2064
2065 pub fn type_annotation(&self) -> Option<TypeAnnotation> {
2068 support::child(&self.syntax)
2069 }
2070
2071 pub fn value(&self) -> Option<Expr> {
2073 support::child(&self.syntax)
2074 }
2075}
2076
2077impl ListDecl {
2080 pub fn identifier(&self) -> Option<Identifier> {
2081 support::child(&self.syntax)
2082 }
2083
2084 pub fn name(&self) -> Option<String> {
2085 self.identifier().and_then(|id| id.name())
2086 }
2087
2088 pub fn definition(&self) -> Option<ListDef> {
2089 support::child(&self.syntax)
2090 }
2091}
2092
2093impl ListDef {
2096 pub fn members(&self) -> impl Iterator<Item = ListMember> {
2097 support::children(&self.syntax)
2098 }
2099}
2100
2101impl ListMember {
2104 pub fn on_member(&self) -> Option<ListMemberOn> {
2105 support::child(&self.syntax)
2106 }
2107
2108 pub fn off_member(&self) -> Option<ListMemberOff> {
2109 support::child(&self.syntax)
2110 }
2111}
2112
2113impl ListMemberOn {
2116 pub fn name_token(&self) -> Option<SyntaxToken> {
2117 support::ident_or_keyword_token(&self.syntax)
2119 }
2120
2121 pub fn name(&self) -> Option<String> {
2122 self.name_token().map(|t| t.text().to_string())
2123 }
2124
2125 pub fn value_token(&self) -> Option<SyntaxToken> {
2126 support::token(&self.syntax, INTEGER)
2127 }
2128
2129 pub fn value(&self) -> Option<i64> {
2131 self.value_token()
2132 .and_then(|t| t.text().parse::<i64>().ok())
2133 }
2134}
2135
2136impl ListMemberOff {
2139 pub fn name_token(&self) -> Option<SyntaxToken> {
2140 support::ident_or_keyword_token(&self.syntax)
2142 }
2143
2144 pub fn name(&self) -> Option<String> {
2145 self.name_token().map(|t| t.text().to_string())
2146 }
2147
2148 pub fn value_token(&self) -> Option<SyntaxToken> {
2149 support::token(&self.syntax, INTEGER)
2150 }
2151
2152 pub fn value(&self) -> Option<i64> {
2154 self.value_token()
2155 .and_then(|t| t.text().parse::<i64>().ok())
2156 }
2157}
2158
2159impl FunctionParamList {
2162 pub fn params(&self) -> impl Iterator<Item = Identifier> {
2164 support::children(&self.syntax)
2165 }
2166}
2167
2168impl IntegerLit {
2171 pub fn value_token(&self) -> Option<SyntaxToken> {
2172 support::token(&self.syntax, INTEGER)
2173 }
2174
2175 pub fn value(&self) -> Option<i64> {
2176 self.value_token()
2177 .and_then(|t| t.text().parse::<i64>().ok())
2178 }
2179}
2180
2181impl FloatLit {
2184 pub fn value_token(&self) -> Option<SyntaxToken> {
2185 support::token(&self.syntax, FLOAT)
2186 }
2187
2188 pub fn value(&self) -> Option<f64> {
2189 self.value_token()
2190 .and_then(|t| t.text().parse::<f64>().ok())
2191 }
2192}
2193
2194impl StringLit {
2197 pub fn raw_text(&self) -> String {
2205 let full = self.syntax.text().to_string();
2206 let trimmed = full.strip_prefix('"').unwrap_or(&full);
2207 trimmed.strip_suffix('"').unwrap_or(trimmed).to_string()
2208 }
2209}
2210
2211impl BooleanLit {
2214 pub fn value(&self) -> Option<bool> {
2215 let tok = self
2216 .syntax
2217 .children_with_tokens()
2218 .filter_map(rowan::NodeOrToken::into_token)
2219 .find(|tok| matches!(tok.kind(), KW_TRUE | KW_FALSE))?;
2220 match tok.kind() {
2221 KW_TRUE => Some(true),
2222 KW_FALSE => Some(false),
2223 _ => None,
2224 }
2225 }
2226}
2227
2228impl AuthorWarning {
2231 pub fn text(&self) -> String {
2236 self.syntax
2237 .children_with_tokens()
2238 .filter_map(rowan::NodeOrToken::into_token)
2239 .skip_while(|tok| matches!(tok.kind(), KW_TODO | COLON) || tok.kind().is_trivia())
2240 .take_while(|tok| tok.kind() != NEWLINE)
2241 .map(|tok| tok.text().to_string())
2242 .collect::<String>()
2243 .trim()
2244 .to_string()
2245 }
2246}
2247
2248impl ChoiceCondition {
2251 pub fn expr(&self) -> Option<Expr> {
2253 support::child(&self.syntax)
2254 }
2255}
2256
2257impl InnerExpression {
2260 pub fn expr(&self) -> Option<Expr> {
2262 support::child(&self.syntax)
2263 }
2264}
2265
2266impl ParenExpr {
2269 pub fn inner(&self) -> Option<Expr> {
2271 support::child(&self.syntax)
2272 }
2273}
2274
2275impl BranchContent {
2278 pub fn divert(&self) -> Option<DivertNode> {
2279 support::child(&self.syntax)
2280 }
2281}
2282
2283impl MultilineBranchBody {
2286 pub fn texts(&self) -> impl Iterator<Item = Text> {
2287 support::children(&self.syntax)
2288 }
2289
2290 pub fn inline_logics(&self) -> impl Iterator<Item = InlineLogic> {
2291 support::children(&self.syntax)
2292 }
2293
2294 pub fn glue_nodes(&self) -> impl Iterator<Item = GlueNode> {
2295 support::children(&self.syntax)
2296 }
2297
2298 pub fn escapes(&self) -> impl Iterator<Item = Escape> {
2299 support::children(&self.syntax)
2300 }
2301
2302 pub fn logic_lines(&self) -> impl Iterator<Item = LogicLine> {
2303 support::children(&self.syntax)
2304 }
2305
2306 pub fn divert(&self) -> Option<DivertNode> {
2307 support::child(&self.syntax)
2308 }
2309
2310 pub fn content_lines(&self) -> impl Iterator<Item = ContentLine> {
2311 support::children(&self.syntax)
2312 }
2313
2314 pub fn choices(&self) -> impl Iterator<Item = Choice> {
2315 support::children(&self.syntax)
2316 }
2317}