1#![allow(missing_docs)]
2use cstree::interning::{Resolver, TokenKey};
3use skullbrain_lexer::ModifierKind;
4
5use crate::cst::utils::children;
6
7use super::*;
8
9define_cst_node! {
10 pub struct Break {
12 kind: SyntaxKind::LoopBreak,
13 child: [optional_expr => Expr],
14 tokens : [
15 break_token BreakToken => SyntaxKind::Keyword
17 ],
18 }
19}
20
21define_cst_node! {
22 pub struct Continue {
24 kind: SyntaxKind::LoopContinue,
25 tokens: [
26 continue_token ContinueToken => SyntaxKind::Keyword
28 ],
29 }
30}
31
32define_cst_node! {
33 pub struct Return {
35 kind: SyntaxKind::Return,
36 child: [optional_expr => Expr],
37 tokens: [
38 return_token ReturnToken => SyntaxKind::Keyword
40 ],
41 }
42}
43
44define_cst_node! {
45 pub struct Throw {
47 kind: SyntaxKind::ThrowError,
48 child: [expr => Expr],
49 tokens: [
50 throw_token ThrowToken => SyntaxKind::Keyword
52 ],
53 }
54}
55
56define_cst_node! {
57 pub struct BlockExpr {
59 kind : SyntaxKind::DelimitedRange,
60 nogen tokens: [
61 open_token OpenBraceToken => SyntaxKind::OpenBrace,
62 close_token CloseBraceToken => SyntaxKind::CloseBrace
63 ],
64 }
65}
66
67impl BlockExpr {
68 pub fn exprs(&self) -> impl Iterator<Item = Expr> + use<'_> {
70 self.syntax.children_with_tokens().map(Expr::cast_element)
72 }
73}
74define_cst_node! {
75 pub struct ParenExpr {
77 kind : SyntaxKind::DelimitedRange,
78 nogen tokens: [
79 open_token OpenParenToken => SyntaxKind::OpenParen,
80 close_token CloseParenToken => SyntaxKind::CloseParen
81 ],
82 }
83}
84
85impl ParenExpr {
86 pub fn exprs(&self) -> impl Iterator<Item = Expr> + use<'_> {
88 self.syntax.children_with_tokens().map(Expr::cast_element)
89 }
90}
91
92define_cst_node! {
93 pub struct Type {
95 kind: SyntaxKind::Type,
96 nogen tokens: [
97 ident IdentToken => SyntaxKind::Ident
98 ],
99 forward: [
100 signature SyntaxKind::FunctionSignature => FunctionSignature
101 ],
102 }
103}
104
105define_cst_node! {
106 pub struct FunctionSignature {
108 kind : SyntaxKind::FunctionSignature,
109 child : [return_ty => Type],
110 tokens: [
111 return_ty_token ReturnTypeToken => SyntaxKind::Arrow
113 ],
114 }
115}
116
117define_cst_node! {
118 pub struct Parameters {}
120}
121
122impl FunctionSignature {
123 pub fn parameters(&self) -> Option<Parameters> {
125 utils::child::<ParenRange>(&self.syntax).map(|paren| Parameters {
126 syntax: paren.syntax,
127 })
128 }
129
130 pub fn open_brace_token(&self) -> Option<OpenParenToken> {
132 utils::child::<ParenRange>(&self.syntax)?.open_token()
133 }
134
135 pub fn close_brace_token(&self) -> Option<CloseParenToken> {
137 utils::child::<ParenRange>(&self.syntax)?.close_token()
138 }
139}
140
141pub enum CommaSeperated<T> {
143 Comma(CommaToken),
144 Item(T),
145}
146
147impl Parameters {
148 pub fn iter(&self) -> impl Iterator<Item = CommaSeperated<Parameter>> + '_ {
150 self.syntax
151 .children_with_tokens()
152 .filter_map(|it| match it {
153 cstree::util::NodeOrToken::Node(node) if Parameter::can_cast(node.kind()) => {
154 let Some(item) = Parameter::cast(node.clone()) else {
155 unreachable!()
156 };
157
158 Some(CommaSeperated::Item(item))
159 }
160 cstree::util::NodeOrToken::Token(tok) if CommaToken::can_cast(tok.kind()) => {
161 let Some(comma) = CommaToken::cast(tok.clone()) else {
162 unreachable!()
163 };
164
165 Some(CommaSeperated::Comma(comma))
166 }
167 _ => None,
168 })
169 }
170}
171
172define_cst_node! {
173 pub struct While {
175 kind: SyntaxKind::WhileLoop,
176 tokens: [
177 while_token WhileToken => SyntaxKind::Keyword
179 ],
180 forward: [
181 body SyntaxKind::Body => BlockExpr,
182 condition SyntaxKind::Condition => ParenExpr
183 ],
184 }
185}
186
187define_cst_node! {
188 pub struct ForLoop {
190 kind: SyntaxKind::ForLoop,
191 }
192}
193
194define_cst_token! {
195 pub struct ForIterOpenToken { kind : SyntaxKind::ForIterOpen}
197}
198
199define_cst_token! {
200 pub struct ForIterCloseToken { kind : SyntaxKind::ForIterClose}
202}
203
204impl ForLoop {
205 pub fn open_token(&self) -> Option<ForIterOpenToken> {
207 let value = children::<ParenRange>(&self.syntax).next()?.syntax;
208 utils::token::<ForIterOpenToken>(&value, SyntaxKind::ForIterOpen)
209 }
210 pub fn close_token(&self) -> Option<ForIterCloseToken> {
212 let value = children::<ParenRange>(&self.syntax).next()?.syntax;
213 utils::token::<ForIterCloseToken>(&value, SyntaxKind::ForIterClose)
214 }
215
216 pub fn body(&self) -> Option<BlockExpr> {
218 children(&self.syntax).last()
219 }
220
221 pub fn iter(&self) -> Option<ParenExpr> {
223 children(&self.syntax).next()
224 }
225}
226
227define_cst_node! {
228 pub struct TryCatch {
230 kind: SyntaxKind::TryCatch,
231 child: [try_arm => TryArm],
232 }
233}
234
235define_cst_node! {
236 pub struct TryArm {
238 kind : SyntaxKind::Try,
239 child:[block => BlockExpr],
240 tokens:[
241 try_token TryToken => SyntaxKind::Keyword
243 ],
244 }
245}
246
247define_cst_node! {
248 pub struct CatchArm {
250 kind : SyntaxKind::Catch,
251 child:[catch_ty => CatchType,block => BlockExpr],
252 tokens:[
253 catch_token CatchToken => SyntaxKind::Keyword
255 ],
256 }
257}
258
259define_cst_node! {
260 pub struct CatchType {
262 kind : SyntaxKind::Parameter,
263 child : [ty => Type,try_arm => TryArm],
264 nogen tokens : [
265 name IdentToken => SyntaxKind::Ident,
266 colon_token ColonToken => SyntaxKind::Colon
267 ],
268 }
269}
270
271impl TryCatch {
272 pub fn catch_arms(&self) -> impl Iterator<Item = CatchArm> + use<'_> {
274 utils::children::<CatchArm>(&self.syntax)
275 }
276}
277
278define_cst_node! {
279 pub struct TypeAlias {
281 kind: SyntaxKind::TypeAlias,
282 child : [modifiers => Modifiers,aliased => Type],
283 tokens: [
284 alias_token AliasToken => SyntaxKind::Keyword
286 ],
287 nogen tokens: [
288 assignment_token AssignmentToken => SyntaxKind::Assignment,
289 name IdentToken => SyntaxKind::Ident
290 ],
291 }
292}
293
294define_cst_node! {
295 pub struct VariableStmt {
297 kind: SyntaxKind::VariableDeclaration,
298 child:[modifiers => Modifiers,initialiser => BlockExpr],
299 }
300}
301impl VariableStmt {
302 pub fn name(&self) -> Option<IdentToken> {
304 Parameter::forward_name_from(&self.syntax)
305 }
306
307 pub fn ty(&self) -> Option<Type> {
309 Parameter::forward_type_from(&self.syntax)
310 }
311
312 pub fn var_token(&self) -> VariableToken {
314 let Some(tok) = utils::token_with(&self.syntax, |k| {
315 matches!(
316 k,
317 SyntaxKind::MutableVariableKeyword | SyntaxKind::ImmutableVariableKeyword
318 )
319 }) else {
320 unreachable!()
321 };
322
323 VariableToken { token: tok.clone() }
324 }
325}
326
327define_cst_token! {
328 pub struct VariableToken {}
330}
331
332impl VariableToken {
333 pub fn is_mutable(&self) -> bool {
335 matches!(self.token.kind(), SyntaxKind::MutableVariableKeyword)
336 }
337}
338
339impl CstToken for VariableToken {
340 fn can_cast(kind: SyntaxKind) -> bool {
341 matches!(
342 kind,
343 SyntaxKind::MutableVariableKeyword | SyntaxKind::ImmutableVariableKeyword
344 )
345 }
346
347 fn cast(token: SyntaxToken) -> Option<Self> {
348 Self::can_cast(token.kind()).then(|| Self { token })
349 }
350
351 fn token(&self) -> &SyntaxToken {
352 &self.token
353 }
354}
355
356define_cst_node! {
357 pub struct Parameter {
359 kind: SyntaxKind::Parameter,
360 child :[ty => Type],
361
362 nogen tokens: [
363 name IdentToken => SyntaxKind::Ident,
364 colon_token ColonToken => SyntaxKind::Colon
365 ],
366 }
367}
368
369impl Parameter {
370 fn forward_name_from(syntax: &SyntaxNode) -> Option<IdentToken> {
371 utils::child::<Parameter>(&syntax)?.name()
372 }
373
374 fn forward_type_from(syntax: &SyntaxNode) -> Option<Type> {
375 utils::child::<Parameter>(&syntax)?.ty()
376 }
377}
378
379define_cst_node! {
380 pub struct BinaryExpr {
382 forward: [
383 lhs SyntaxKind::Lhs => Expr,
384 rhs SyntaxKind::Rhs => Expr
385 ],
386 }
387}
388
389define_cst_token! {
390 pub struct BinaryOp {}
392}
393
394impl BinaryExpr {
395 pub fn operator(&self) -> BinaryOp {
397 use SyntaxKind::*;
398 const fn is_op(it: SyntaxKind) -> bool {
399 matches!(
400 it,
401 OpEq | OpNotEq
402 | OpLt
403 | OpGt
404 | OpLtEq
405 | OpGtEq
406 | OpAnd
407 | OpOr
408 | OpMinus
409 | OpPlus
410 | OpMul
411 | OpDivide
412 | OpMod
413 )
414 }
415
416 let Some(tok) = utils::token_with(&self.syntax, is_op) else {
417 unreachable!()
418 };
419
420 BinaryOp { token: tok.clone() }
421 }
422}
423
424define_cst_node! {
425 pub struct UnaryExpr {
427 forward: [
428 expr SyntaxKind::Rhs => Expr
429 ],
430 }
431}
432
433define_cst_token! {
434 pub struct UnaryOp {}
436}
437
438impl UnaryExpr {
439 pub fn operator(&self) -> UnaryOp {
441 use SyntaxKind::*;
442 const fn is_op(it: SyntaxKind) -> bool {
443 matches!(it, OpMinus | OpNot)
444 }
445
446 let Some(tok) = utils::token_with(&self.syntax, is_op) else {
447 unreachable!()
448 };
449
450 UnaryOp { token: tok.clone() }
451 }
452}
453
454define_cst_node! {
455 pub struct ChainExpr {
457 tokens : [
458 chaining_token ChainingToken => SyntaxKind::OpMethodChaining
460 ],
461 forward: [
462 object SyntaxKind::Lhs => Expr,
463 method SyntaxKind::Rhs => Expr
464 ],
465 }
466}
467
468define_cst_node! {
469 pub struct IfElse {
471 kind: SyntaxKind::IfElse,
472 child : [if_arm => IfArm],
473 }
474}
475
476define_cst_node! {
477 pub struct IfArm {
479 kind : SyntaxKind::If,
480 tokens:[
481 if_token IfToken => SyntaxKind::Keyword],
483 forward: [
484 body SyntaxKind::Body => BlockExpr,
485 condition SyntaxKind::Condition => ParenExpr
486 ],
487 }
488}
489
490define_cst_node! {
491 pub struct ElseArm {
493 tokens:[
494 else_token ElseToken => SyntaxKind::Keyword],
496 forward: [
497 body SyntaxKind::Body => BlockExpr
498 ],
499 }
500}
501
502define_cst_node! {
503 pub struct ElseIfArm {
505 forward: [
506 body SyntaxKind::Body => BlockExpr,
507 condition SyntaxKind::Condition => ParenExpr
508 ],
509 }
510}
511
512pub enum ElseBranch {
514 Else(ElseArm),
516 ElseIf(ElseIfArm),
518}
519
520impl IfElse {
521 pub fn else_branches(&self) -> impl Iterator<Item = ElseBranch> + use<'_> {
523 utils::children::<ElseBranch>(&self.syntax)
524 }
525}
526
527impl ElseIfArm {
528 pub fn contains_else_if(&self) -> Option<()> {
530 let count_of_keywords = self
531 .syntax
532 .children_with_tokens()
533 .filter_map(|it| it.into_token())
534 .filter(|n| IdentToken::can_cast(n.kind()))
535 .count();
536
537 (count_of_keywords == 2).then_some(())
538 }
539}
540
541impl CstNode for ElseBranch {
542 fn can_cast(kind: SyntaxKind) -> bool {
543 matches!(kind, SyntaxKind::Else)
544 }
545
546 fn cast(syntax: SyntaxNode) -> Option<Self> {
547 if Self::can_cast(syntax.kind()) {
548 let count_of_keywords = syntax
549 .children_with_tokens()
550 .filter_map(|it| it.into_token())
551 .filter(|n| IdentToken::can_cast(n.kind()))
552 .count();
553
554 let res = match count_of_keywords {
555 1 => ElseBranch::Else(ElseArm { syntax }),
556 2 => ElseBranch::ElseIf(ElseIfArm { syntax }),
557 _ => unreachable!(),
558 };
559
560 Some(res)
561 } else {
562 None
563 }
564 }
565
566 fn syntax(&self) -> &SyntaxNode {
567 match self {
568 ElseBranch::Else(else_arm) => &else_arm.syntax,
569 ElseBranch::ElseIf(else_if_arm) => &else_if_arm.syntax,
570 }
571 }
572}
573
574define_cst_node! {
575 pub struct Match {
577 kind: SyntaxKind::Match,
578 tokens: [
579 match_token MatchToken => SyntaxKind::Keyword
581 ],
582 }
583}
584
585define_cst_node! {
586 pub struct MatchArmWithCondition {
588 kind: SyntaxKind::MatchCondition,
589 tokens:[arrow ArrowToken => SyntaxKind::Arrow],
590 forward: [
591 pat SyntaxKind::Condition => MatchPat,
592 body SyntaxKind::DelimitedRange => BlockExpr
593 ],
594 }
595}
596
597define_cst_node! {
598 pub struct MatchPat {
600 nogen tokens:[
601 ident IdentToken => SyntaxKind::Ident,
602 lit LiteralToken => SyntaxKind::Literal
603 ],
604 }
605}
606
607define_cst_node! {
608 pub struct MatchArmDefault {
610 kind: SyntaxKind::MatchConditionDefault,
611 nogen tokens:[arrow ArrowToken => SyntaxKind::Arrow],
612 forward: [
613 body SyntaxKind::DelimitedRange => BlockExpr
614 ],
615 }
616}
617
618pub enum MatchArm {
620 WithCondition(MatchArmWithCondition),
622 Default(MatchArmDefault),
624}
625
626impl Match {
627 pub fn expr(&self) -> Option<ParenExpr> {
629 children(&self.syntax).next()
630 }
631
632 fn body(&self) -> Option<&SyntaxNode> {
633 self.syntax
634 .children()
635 .find(|i| BraceRange::can_cast(i.kind()))
636 }
637
638 pub fn body_open_token(&self) -> Option<OpenBraceToken> {
640 utils::token(self.body()?, SyntaxKind::OpenBrace)
641 }
642
643 pub fn body_close_token(&self) -> Option<CloseBraceToken> {
645 utils::token(self.body()?, SyntaxKind::CloseBrace)
646 }
647
648 pub fn match_arms(&self) -> Option<impl Iterator<Item = MatchArm> + use<'_>> {
650 Some(children(self.body()?))
651 }
652
653 pub fn disallowed_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
655 Some(
656 self.body()?
657 .children_with_tokens()
658 .filter(|it| {
659 matches!(
660 it.kind(),
661 SyntaxKind::MatchCondition | SyntaxKind::MatchConditionDefault
662 )
663 })
664 .map(|it| Expr::cast_element(it.clone())),
665 )
666 }
667}
668
669impl CstNode for MatchArm {
670 fn can_cast(kind: SyntaxKind) -> bool {
671 matches!(
672 kind,
673 SyntaxKind::MatchCondition | SyntaxKind::MatchConditionDefault
674 )
675 }
676
677 fn syntax(&self) -> &SyntaxNode {
678 match self {
679 MatchArm::WithCondition(match_arm_with_condition) => &match_arm_with_condition.syntax,
680 MatchArm::Default(match_arm_default) => &match_arm_default.syntax,
681 }
682 }
683
684 fn cast(node: SyntaxNode) -> Option<Self> {
685 let res = match node.kind() {
686 SyntaxKind::MatchCondition => {
687 let Some(arm) = MatchArmWithCondition::cast(node) else {
688 unreachable!()
689 };
690
691 MatchArm::WithCondition(arm)
692 }
693 SyntaxKind::MatchConditionDefault => {
694 let Some(arm) = MatchArmDefault::cast(node) else {
695 unreachable!()
696 };
697
698 MatchArm::Default(arm)
699 }
700 _ => return None,
701 };
702
703 Some(res)
704 }
705}
706
707impl CstNode for MatchPat {
708 fn syntax(&self) -> &SyntaxNode {
709 &self.syntax
710 }
711
712 fn can_cast(kind: SyntaxKind) -> bool {
713 matches!(kind, SyntaxKind::Literal | SyntaxKind::Ident)
714 }
715
716 fn cast(node: SyntaxNode) -> Option<Self> {
717 Self::can_cast(node.kind()).then(|| Self { syntax: node })
718 }
719}
720
721define_cst_node! {
722 pub struct ImportStmt {
724 kind: SyntaxKind::Import,
725 child : [
726 source => ImportSource,
727 items => ImportItems
728 ],
729 tokens: [
730 import_token ImportToken => SyntaxKind::Keyword
731 ],
732 nogen tokens: [
733 alias_token AliasToken=> SyntaxKind::ImportAlias
734 ],
735 }
736}
737
738define_cst_node! {
739 pub struct ImportItems {
741 kind: SyntaxKind::ImportItem,
742 nogen tokens: [
743 open_token OpenBraceToken => SyntaxKind::OpenBrace,
744 close_token CloseBraceToken => SyntaxKind::CloseBrace
745 ],
746 }
747}
748
749define_cst_node! {
750 pub struct ImportSource {
752 kind : SyntaxKind::ImportSource,
753 nogen tokens : [
754 ident IdentToken => SyntaxKind::Ident,
755 path StringToken => SyntaxKind::Literal
756 ],
757 }
758}
759
760impl ImportItems {
761 pub fn idents(&self) -> impl Iterator<Item = IdentToken> + use<'_> {
763 self.syntax
764 .children_with_tokens()
765 .filter_map(|it| it.into_token())
766 .filter_map(|i| IdentToken::cast(i.clone()))
767 }
768}
769
770define_cst_node! {
771 pub struct Modifiers {
773 kind: SyntaxKind::Modifiers,
774 }
775}
776
777impl Modifiers {
778 pub fn iter(&self) -> impl Iterator<Item = ModifierToken> + '_ {
780 self.syntax
781 .children_with_tokens()
782 .filter_map(|it| it.into_token())
783 .filter(|token| matches!(token.kind(), SyntaxKind::Keyword))
784 .map(|it| ModifierToken { token: it.clone() })
785 }
786}
787
788define_cst_token! {
789 pub struct ModifierToken {}
791}
792
793impl ModifierToken {
794 pub fn kind<I>(&self, resolver: &I) -> ModifierKind
796 where
797 I: Resolver<TokenKey> + ?Sized,
798 {
799 let text = self.token.resolve_text(resolver);
800 let Some(kind) = ModifierKind::from_token_repr(text) else {
801 unreachable!()
802 };
803
804 kind
805 }
806}
807
808define_cst_node! {
809 pub struct Class {
811 kind: SyntaxKind::Class,
812 child:[modifiers => Modifiers],
813 tokens: [
814 class_token ClassToken => SyntaxKind::Keyword
815 ],
816 nogen tokens :[
817 name IdentToken => SyntaxKind::Ident
818 ],
819 }
820}
821
822impl Class {
823 fn body(&self) -> Option<&SyntaxNode> {
824 self.syntax
825 .children()
826 .find(|i| BraceRange::can_cast(i.kind()))
827 }
828
829 pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
831 utils::token(self.body()?, SyntaxKind::OpenBrace)
832 }
833
834 pub fn body_close_tok(&self) -> Option<CloseBraceToken> {
836 utils::token(self.body()?, SyntaxKind::CloseBrace)
837 }
838
839 pub fn methods(&self) -> Option<impl Iterator<Item = Function> + use<'_>> {
841 self.body().map(|syn| utils::children(&syn))
842 }
843
844 pub fn ty_aliasz(&self) -> Option<impl Iterator<Item = TypeAlias> + use<'_>> {
846 self.body().map(|syn| utils::children(&syn))
847 }
848
849 pub fn variables(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
851 self.body().map(|syn| utils::children(syn))
852 }
853
854 pub fn nested_impls(&self) -> Option<impl Iterator<Item = TraitImpl> + use<'_>> {
856 self.body().map(|syn| utils::children(syn))
857 }
858
859 pub fn implicit_init_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
861 self.body().map(|syn| implicit_init_exprs(syn))
862 }
863}
864
865fn implicit_init_exprs<'a>(syntax: &'a SyntaxNode) -> impl Iterator<Item = Expr> + 'a {
866 syntax
867 .children_with_tokens()
868 .filter(move |i| {
869 matches!(
870 i.kind(),
871 SyntaxKind::Function
872 | SyntaxKind::VariableDeclaration
873 | SyntaxKind::Trait
874 | SyntaxKind::TraitImpl
875 | SyntaxKind::TypeAlias
876 | SyntaxKind::Enum
877 | SyntaxKind::EnumVariant
878 | SyntaxKind::Import
879 | SyntaxKind::ImportAlias
880 | SyntaxKind::ImportSource
881 | SyntaxKind::ImportItem
882 )
883 })
884 .map(|element| Expr::cast_element(element))
885}
886
887define_cst_node! {
888 pub struct TraitImpl {
890 kind: SyntaxKind::TraitImpl,
891 child: [modifiers => Modifiers],
892 tokens: [impl_token TraitImplToken => SyntaxKind::Keyword],
893 }
894}
895
896impl TraitImpl {
897 pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
899 utils::token(self.body()?, SyntaxKind::OpenBrace)
900 }
901
902 pub fn body_close_tok(&self) -> Option<CloseBraceToken> {
904 utils::token(self.body()?, SyntaxKind::CloseBrace)
905 }
906
907 fn body(&self) -> Option<&SyntaxNode> {
908 self.syntax
909 .children()
910 .find(|i| BraceRange::can_cast(i.kind()))
911 }
912
913 pub fn methods(&self) -> Option<impl Iterator<Item = Function> + '_> {
915 self.body().map(|syntax| utils::children(syntax))
916 }
917
918 pub fn var_decls(&self) -> Option<impl Iterator<Item = VariableStmt> + '_> {
920 self.body().map(|syntax| utils::children(syntax))
921 }
922
923 pub fn type_aliases(&self) -> Option<impl Iterator<Item = TypeAlias> + '_> {
925 self.body().map(|syntax| utils::children(syntax))
926 }
927
928 pub fn implicit_init_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
930 self.body().map(|syntax| implicit_init_exprs(syntax))
931 }
932}
933
934define_cst_node! {
935 pub struct Enum {
937 kind: SyntaxKind::Enum,
938 child:[modifiers => Modifiers],
939 tokens: [
940 enum_token EnumToken => SyntaxKind::Keyword
941 ],
942 nogen tokens: [
943 name IdentToken => SyntaxKind::Ident
944 ],
945 }
946}
947
948impl Enum {
949 pub fn variants(&self) -> impl Iterator<Item = EnumVariant> + use<'_> {
951 utils::children::<EnumVariant>(&self.syntax)
952 }
953
954 pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
956 utils::token(self.body()?, SyntaxKind::OpenBrace)
957 }
958
959 pub fn body_close_tok(&self) -> Option<CloseBraceToken> {
961 utils::token(self.body()?, SyntaxKind::CloseBrace)
962 }
963
964 fn body(&self) -> Option<&SyntaxNode> {
965 self.syntax
966 .children()
967 .find(|i| BraceRange::can_cast(i.kind()))
968 }
969
970 pub fn implicit_init_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
972 self.body().map(|syntax| implicit_init_exprs(syntax))
973 }
974
975 pub fn methods(&self) -> Option<impl Iterator<Item = Function> + use<'_>> {
977 self.body().map(|syntax| utils::children(syntax))
978 }
979
980 pub fn variables(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
982 self.body().map(|syntax| utils::children(syntax))
983 }
984
985 pub fn nested_impls(&self) -> Option<impl Iterator<Item = TraitImpl> + use<'_>> {
987 self.body().map(|syntax| utils::children(syntax))
988 }
989 pub fn ty_aliasz(&self) -> Option<impl Iterator<Item = TypeAlias> + use<'_>> {
991 self.body().map(|syn| utils::children(&syn))
992 }
993}
994
995define_cst_node! {
996 pub struct EnumVariant {
998 kind: SyntaxKind::EnumVariant,
999 child:[modifiers => Modifiers],
1000 nogen tokens: [name IdentToken => SyntaxKind::Ident],
1001 }
1002}
1003
1004define_cst_node! {
1005 pub struct EnumVariantField {
1007 kind: SyntaxKind::Parameter,
1008 child :[ty => Type],
1009 nogen tokens: [name IdentToken => SyntaxKind::Ident,colon_token ColonToken => SyntaxKind::Colon ],
1010 }
1011}
1012
1013impl EnumVariant {
1014 pub fn fields(&self) -> Option<impl Iterator<Item = EnumVariantField> + use<'_>> {
1017 let syntax = self
1018 .syntax
1019 .children()
1020 .find(|i| ParenRange::can_cast(i.kind()))?;
1021 let children = children(syntax);
1022 Some(children)
1023 }
1024
1025 pub fn open_brace_token(&self) -> Option<OpenParenToken> {
1027 utils::child::<ParenRange>(&self.syntax)?.open_token()
1028 }
1029
1030 pub fn close_brace_token(&self) -> Option<CloseParenToken> {
1032 utils::child::<ParenRange>(&self.syntax)?.close_token()
1033 }
1034
1035 pub fn is_unit(&self) -> bool {
1037 self.fields().is_some()
1038 }
1039}
1040
1041define_cst_node! {
1042 pub(super) struct ParenRange {
1043 kind: SyntaxKind::DelimitedRange,
1044 nogen tokens: [
1045 open_token OpenParenToken => SyntaxKind::OpenParen,
1046 close_token CloseParenToken => SyntaxKind::CloseParen
1047 ],
1048 }
1049}
1050
1051define_cst_node! {
1052 struct BraceRange {
1053 kind: SyntaxKind::DelimitedRange,
1054 }
1055}
1056
1057define_cst_node! {
1058 pub struct Trait {
1060 kind: SyntaxKind::Trait,
1061 child: [
1062 modifiers => Modifiers
1063 ],
1064 tokens: [
1065 trait_token TraitToken => SyntaxKind::Keyword
1066 ],
1067 nogen tokens: [
1068 name IdentToken => SyntaxKind::Ident
1069 ],
1070 }
1071}
1072
1073impl Trait {
1074 fn body(&self) -> Option<&SyntaxNode> {
1075 self.syntax
1076 .children()
1077 .find(|i| BraceRange::can_cast(i.kind()))
1078 }
1079
1080 pub fn open_brace_token(&self) -> Option<OpenParenToken> {
1082 utils::child::<ParenRange>(self.body()?)?.open_token()
1083 }
1084
1085 pub fn close_brace_token(&self) -> Option<CloseParenToken> {
1087 utils::child::<ParenRange>(self.body()?)?.close_token()
1088 }
1089
1090 pub fn functions(&self) -> Option<impl Iterator<Item = FunctionItem> + use<'_>> {
1092 self.body().map(|syntax| children(syntax))
1094 }
1095
1096 pub fn var_decls(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
1098 self.body().map(|syntax| children(syntax))
1099 }
1100
1101 pub fn type_aliases(&self) -> Option<impl Iterator<Item = TypeAlias> + '_> {
1103 self.body().map(|syntax| children(syntax))
1104 }
1105
1106 pub fn implicit_init_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
1108 self.body().map(|syntax| implicit_init_exprs(syntax))
1109 }
1110}
1111
1112define_cst_node! {
1113 pub struct Function {
1115 kind: SyntaxKind::Function,
1116 child: [modifiers => Modifiers,body => BlockExpr],
1117 tokens: [
1118 fn_token FnToken => SyntaxKind::Keyword
1119 ],
1120 nogen tokens: [
1121 name IdentToken=> SyntaxKind::Ident
1122 ],
1123 forward: [
1124 signature SyntaxKind::FunctionSignature => FunctionSignature
1125 ],
1126 }
1127}
1128
1129define_cst_node! {
1130 pub struct PartialFunction {
1132 child: [modifiers => Modifiers],
1133 nogen tokens: [
1134 name IdentToken=> SyntaxKind::Ident,
1135 fn_token FnToken => SyntaxKind::Keyword
1136 ],
1137 forward: [
1138 signature SyntaxKind::FunctionSignature => FunctionSignature
1139 ],
1140 }
1141}
1142
1143pub enum FunctionItem {
1145 Full(Function),
1147 Partial(PartialFunction),
1149}
1150
1151impl FunctionItem {
1152 pub fn modifiers(&self) -> Option<Modifiers> {
1154 match self {
1155 FunctionItem::Full(function) => function.modifiers(),
1156 FunctionItem::Partial(partial_function) => partial_function.modifiers(),
1157 }
1158 }
1159
1160 pub fn name(&self) -> Option<IdentToken> {
1162 match self {
1163 FunctionItem::Full(function) => function.name(),
1164 FunctionItem::Partial(partial_function) => partial_function.name(),
1165 }
1166 }
1167
1168 pub fn signature(&self) -> Option<FunctionSignature> {
1170 match self {
1171 FunctionItem::Full(function) => function.signature(),
1172 FunctionItem::Partial(partial_function) => partial_function.signature(),
1173 }
1174 }
1175}
1176
1177impl CstNode for FunctionItem {
1178 fn can_cast(kind: SyntaxKind) -> bool {
1179 Function::can_cast(kind)
1180 }
1181
1182 fn cast(node: SyntaxNode) -> Option<Self> {
1183 Self::can_cast(node.kind()).then(|| {
1184 let function = Function { syntax: node };
1185 match function.body() {
1186 Some(_) => Self::Full(function),
1187 None => Self::Partial(PartialFunction {
1188 syntax: function.syntax,
1189 }),
1190 }
1191 })
1192 }
1193
1194 fn syntax(&self) -> &SyntaxNode {
1195 match self {
1196 FunctionItem::Full(function) => &function.syntax,
1197 FunctionItem::Partial(partial_function) => &partial_function.syntax,
1198 }
1199 }
1200}
1201
1202pub enum Fragment {
1204 EnumVariant(EnumVariant),
1206
1207 Modifiers(Modifiers),
1209
1210 Unknown(UnknownToken),
1212
1213 MatchArm(MatchArm),
1215 Generic {
1217 syntax: SyntaxNode,
1219 },
1220}