Skip to main content

skullbrain_parser/cst/
nodes.rs

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    /// A `break` statement.
11    pub struct Break {
12        kind: SyntaxKind::LoopBreak,
13        child: [optional_expr => Expr],
14        tokens : [
15            /// A `break` token
16            break_token BreakToken => SyntaxKind::Keyword
17        ],
18    }
19}
20
21define_cst_node! {
22    /// A `continue` statement.
23    pub struct Continue {
24        kind: SyntaxKind::LoopContinue,
25        tokens: [
26            /// A `continue` token
27            continue_token ContinueToken => SyntaxKind::Keyword
28        ],
29    }
30}
31
32define_cst_node! {
33    /// A `return` statement.
34    pub struct Return {
35        kind: SyntaxKind::Return,
36        child: [optional_expr => Expr],
37        tokens: [
38            /// A `return` token
39            return_token ReturnToken => SyntaxKind::Keyword
40        ],
41    }
42}
43
44define_cst_node! {
45    /// A `throw` statement.
46    pub struct Throw {
47        kind: SyntaxKind::ThrowError,
48        child: [expr => Expr],
49        tokens: [
50            /// A `throw` token
51            throw_token ThrowToken => SyntaxKind::Keyword
52        ],
53    }
54}
55
56define_cst_node! {
57    /// A block expr
58    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    /// All the child statements (top-level `Expr` nodes) in this block.
69    pub fn exprs(&self) -> impl Iterator<Item = Expr> + use<'_> {
70        // skip the delimiters and cast each inner element
71        self.syntax.children_with_tokens().map(Expr::cast_element)
72    }
73}
74define_cst_node! {
75    ///
76    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    /// All the expressions inside the parentheses.
87    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    /// A type .
94    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    /// A function signature .
107    pub struct FunctionSignature {
108        kind : SyntaxKind::FunctionSignature,
109        child : [return_ty => Type],
110        tokens: [
111            /// A `->` token
112            return_ty_token ReturnTypeToken => SyntaxKind::Arrow
113        ],
114    }
115}
116
117define_cst_node! {
118    /// Wrapper around the `ParenRange` to iterate `Parameter`.
119    pub struct Parameters {}
120}
121
122impl FunctionSignature {
123    ///
124    pub fn parameters(&self) -> Option<Parameters> {
125        utils::child::<ParenRange>(&self.syntax).map(|paren| Parameters {
126            syntax: paren.syntax,
127        })
128    }
129
130    ///
131    pub fn open_brace_token(&self) -> Option<OpenParenToken> {
132        utils::child::<ParenRange>(&self.syntax)?.open_token()
133    }
134
135    ///
136    pub fn close_brace_token(&self) -> Option<CloseParenToken> {
137        utils::child::<ParenRange>(&self.syntax)?.close_token()
138    }
139}
140
141///
142pub enum CommaSeperated<T> {
143    Comma(CommaToken),
144    Item(T),
145}
146
147impl Parameters {
148    /// Iterate each `Parameter` inside `( ... )`.
149    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    /// A `while` loop.
174    pub struct While {
175        kind: SyntaxKind::WhileLoop,
176        tokens: [
177            /// A `while` token
178            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    /// A `for (...) { … }` loop.
189    pub struct ForLoop {
190        kind: SyntaxKind::ForLoop,
191    }
192}
193
194define_cst_token! {
195    ///
196    pub struct ForIterOpenToken { kind : SyntaxKind::ForIterOpen}
197}
198
199define_cst_token! {
200    ///
201    pub struct ForIterCloseToken { kind : SyntaxKind::ForIterClose}
202}
203
204impl ForLoop {
205    ///
206    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    ///
211    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    ///
217    pub fn body(&self) -> Option<BlockExpr> {
218        children(&self.syntax).last()
219    }
220
221    ///
222    pub fn iter(&self) -> Option<ParenExpr> {
223        children(&self.syntax).next()
224    }
225}
226
227define_cst_node! {
228    /// A `try { … } catch { … }` block.
229    pub struct TryCatch {
230        kind: SyntaxKind::TryCatch,
231        child: [try_arm => TryArm],
232    }
233}
234
235define_cst_node! {
236    /// A `try { ... }  arm.
237    pub struct TryArm {
238        kind : SyntaxKind::Try,
239        child:[block => BlockExpr],
240        tokens:[
241            /// A `try` token
242            try_token TryToken => SyntaxKind::Keyword
243        ],
244    }
245}
246
247define_cst_node! {
248    /// A `catch <TYPE> { … }` arm.
249    pub struct CatchArm {
250        kind : SyntaxKind::Catch,
251        child:[catch_ty => CatchType,block => BlockExpr],
252        tokens:[
253            /// A `catch` token
254            catch_token CatchToken => SyntaxKind::Keyword
255        ],
256    }
257}
258
259define_cst_node! {
260    /// The <TYPE> part in a  `catch <TYPE> { … }` arm.
261    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    ///
273    pub fn catch_arms(&self) -> impl Iterator<Item = CatchArm> + use<'_> {
274        utils::children::<CatchArm>(&self.syntax)
275    }
276}
277
278define_cst_node! {
279    /// A type alias declaration.
280    pub struct TypeAlias {
281        kind: SyntaxKind::TypeAlias,
282        child : [modifiers => Modifiers,aliased => Type],
283        tokens: [
284            /// A `alias` token
285            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    /// A variable declaration.
296    pub struct VariableStmt {
297        kind: SyntaxKind::VariableDeclaration,
298        child:[modifiers => Modifiers,initialiser => BlockExpr],
299    }
300}
301impl VariableStmt {
302    ///
303    pub fn name(&self) -> Option<IdentToken> {
304        Parameter::forward_name_from(&self.syntax)
305    }
306
307    ///
308    pub fn ty(&self) -> Option<Type> {
309        Parameter::forward_type_from(&self.syntax)
310    }
311
312    ///
313    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    /// A `var` token
329    pub struct VariableToken {}
330}
331
332impl VariableToken {
333    ///
334    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    /// A function parameter
358    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    ///
381    pub struct BinaryExpr {
382        forward: [
383            lhs SyntaxKind::Lhs => Expr,
384            rhs SyntaxKind::Rhs => Expr
385        ],
386    }
387}
388
389define_cst_token! {
390    ///
391    pub struct BinaryOp {}
392}
393
394impl BinaryExpr {
395    ///
396    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    ///
426    pub struct UnaryExpr {
427        forward: [
428            expr SyntaxKind::Rhs => Expr
429        ],
430    }
431}
432
433define_cst_token! {
434    ///
435    pub struct UnaryOp {}
436}
437
438impl UnaryExpr {
439    ///
440    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    ///
456    pub struct ChainExpr {
457        tokens : [
458            /// A `.` token
459            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    /// An `if (cond) { … }` statement.
470    pub struct IfElse {
471        kind: SyntaxKind::IfElse,
472        child : [if_arm => IfArm],
473    }
474}
475
476define_cst_node! {
477    /// A `if (cond) { ... }  arm.
478    pub struct IfArm {
479        kind : SyntaxKind::If,
480        tokens:[
481            /// A 'if' token
482            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    /// A `else { .. }` arm.
492    pub struct ElseArm {
493        tokens:[
494            /// A `else` token
495            else_token ElseToken => SyntaxKind::Keyword],
496        forward: [
497            body SyntaxKind::Body => BlockExpr
498        ],
499    }
500}
501
502define_cst_node! {
503    /// A `else if (..) { … }` arm.
504    pub struct ElseIfArm {
505        forward: [
506            body SyntaxKind::Body => BlockExpr,
507            condition SyntaxKind::Condition => ParenExpr
508        ],
509    }
510}
511
512///
513pub enum ElseBranch {
514    ///
515    Else(ElseArm),
516    ///
517    ElseIf(ElseIfArm),
518}
519
520impl IfElse {
521    ///
522    pub fn else_branches(&self) -> impl Iterator<Item = ElseBranch> + use<'_> {
523        utils::children::<ElseBranch>(&self.syntax)
524    }
525}
526
527impl ElseIfArm {
528    ///
529    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    /// A `match` expression.
576    pub struct Match {
577        kind: SyntaxKind::Match,
578        tokens: [
579            /// A `match` token
580            match_token MatchToken => SyntaxKind::Keyword
581        ],
582    }
583}
584
585define_cst_node! {
586    /// A match-arm condition.
587    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    /// A match-arm pattern
599    pub struct MatchPat {
600        nogen tokens:[
601            ident IdentToken => SyntaxKind::Ident,
602            lit LiteralToken => SyntaxKind::Literal
603        ],
604    }
605}
606
607define_cst_node! {
608    /// A match-arm default case (`_ => …`).
609    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
618///
619pub enum MatchArm {
620    /// A match-arm condition.
621    WithCondition(MatchArmWithCondition),
622    /// A match-arm default case (`_ => …`).
623    Default(MatchArmDefault),
624}
625
626impl Match {
627    ///
628    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    ///
639    pub fn body_open_token(&self) -> Option<OpenBraceToken> {
640        utils::token(self.body()?, SyntaxKind::OpenBrace)
641    }
642
643    ///
644    pub fn body_close_token(&self) -> Option<CloseBraceToken> {
645        utils::token(self.body()?, SyntaxKind::CloseBrace)
646    }
647
648    ///
649    pub fn match_arms(&self) -> Option<impl Iterator<Item = MatchArm> + use<'_>> {
650        Some(children(self.body()?))
651    }
652
653    ///
654    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    /// An import expression.
723    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    /// An import expression.
740    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    /// A import source
751    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    ///
762    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    /// A list of modifiers (e.g. `pub`, `static`).
772    pub struct Modifiers {
773        kind: SyntaxKind::Modifiers,
774    }
775}
776
777impl Modifiers {
778    ///
779    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    ///
790    pub struct ModifierToken {}
791}
792
793impl ModifierToken {
794    ///
795    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    /// A class declaration.
810    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    ///
830    pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
831        utils::token(self.body()?, SyntaxKind::OpenBrace)
832    }
833
834    ///
835    pub fn body_close_tok(&self) -> Option<CloseBraceToken> {
836        utils::token(self.body()?, SyntaxKind::CloseBrace)
837    }
838
839    /// All the methods (function declarations) in this class.
840    pub fn methods(&self) -> Option<impl Iterator<Item = Function> + use<'_>> {
841        self.body().map(|syn| utils::children(&syn))
842    }
843
844    ///
845    pub fn ty_aliasz(&self) -> Option<impl Iterator<Item = TypeAlias> + use<'_>> {
846        self.body().map(|syn| utils::children(&syn))
847    }
848
849    /// All the fields (variable declarations) in this class.
850    pub fn variables(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
851        self.body().map(|syn| utils::children(syn))
852    }
853
854    /// All the `impl` blocks nested inside this class
855    pub fn nested_impls(&self) -> Option<impl Iterator<Item = TraitImpl> + use<'_>> {
856        self.body().map(|syn| utils::children(syn))
857    }
858
859    ///
860    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    /// A trait implementation.
889    pub struct TraitImpl {
890        kind: SyntaxKind::TraitImpl,
891        child: [modifiers => Modifiers],
892        tokens: [impl_token TraitImplToken => SyntaxKind::Keyword],
893    }
894}
895
896impl TraitImpl {
897    ///
898    pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
899        utils::token(self.body()?, SyntaxKind::OpenBrace)
900    }
901
902    ///
903    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    /// Iterate *all* function implementations in this impl block.
914    pub fn methods(&self) -> Option<impl Iterator<Item = Function> + '_> {
915        self.body().map(|syntax| utils::children(syntax))
916    }
917
918    /// Iterate *all* variable declarations in this impl (e.g., overrides of associated constants).
919    pub fn var_decls(&self) -> Option<impl Iterator<Item = VariableStmt> + '_> {
920        self.body().map(|syntax| utils::children(syntax))
921    }
922
923    /// All associated type overrides in this impl.
924    pub fn type_aliases(&self) -> Option<impl Iterator<Item = TypeAlias> + '_> {
925        self.body().map(|syntax| utils::children(syntax))
926    }
927
928    ///
929    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    /// An enum declaration.
936    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    /// All the variants defined in this enum.
950    pub fn variants(&self) -> impl Iterator<Item = EnumVariant> + use<'_> {
951        utils::children::<EnumVariant>(&self.syntax)
952    }
953
954    ///
955    pub fn body_open_tok(&self) -> Option<OpenBraceToken> {
956        utils::token(self.body()?, SyntaxKind::OpenBrace)
957    }
958
959    ///
960    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    /// Any “implicit initializer” expressions attached directly under the enum
971    pub fn implicit_init_exprs(&self) -> Option<impl Iterator<Item = Expr> + use<'_>> {
972        self.body().map(|syntax| implicit_init_exprs(syntax))
973    }
974
975    /// All the methods (function declarations) in this enum.
976    pub fn methods(&self) -> Option<impl Iterator<Item = Function> + use<'_>> {
977        self.body().map(|syntax| utils::children(syntax))
978    }
979
980    /// All the fields (variable declarations) in this enum.
981    pub fn variables(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
982        self.body().map(|syntax| utils::children(syntax))
983    }
984
985    /// All the `impl` blocks nested inside this class
986    pub fn nested_impls(&self) -> Option<impl Iterator<Item = TraitImpl> + use<'_>> {
987        self.body().map(|syntax| utils::children(syntax))
988    }
989    ///
990    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    /// A single enum variant.
997    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    /// A single field/parameter of the enum variant.
1006    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    /// If this variant has associated fields (a brace‐delimited block of variable declarations),
1015    /// iterate them here.
1016    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    ///
1026    pub fn open_brace_token(&self) -> Option<OpenParenToken> {
1027        utils::child::<ParenRange>(&self.syntax)?.open_token()
1028    }
1029
1030    ///
1031    pub fn close_brace_token(&self) -> Option<CloseParenToken> {
1032        utils::child::<ParenRange>(&self.syntax)?.close_token()
1033    }
1034
1035    /// Does this variant carry no payload (i.e. a plain C‐style variant)?
1036    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    /// A trait declaration.
1059    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    ///
1081    pub fn open_brace_token(&self) -> Option<OpenParenToken> {
1082        utils::child::<ParenRange>(self.body()?)?.open_token()
1083    }
1084
1085    ///
1086    pub fn close_brace_token(&self) -> Option<CloseParenToken> {
1087        utils::child::<ParenRange>(self.body()?)?.close_token()
1088    }
1089
1090    /// Iterate *all* function declarations inside this trait (both required and default-implemented).
1091    pub fn functions(&self) -> Option<impl Iterator<Item = FunctionItem> + use<'_>> {
1092        // Any Function child under the trait node
1093        self.body().map(|syntax| children(syntax))
1094    }
1095
1096    /// Iterate *all* variable declarations in this trait (e.g., associated constants or properties).
1097    pub fn var_decls(&self) -> Option<impl Iterator<Item = VariableStmt> + use<'_>> {
1098        self.body().map(|syntax| children(syntax))
1099    }
1100
1101    /// All associated type aliases in this trait.
1102    pub fn type_aliases(&self) -> Option<impl Iterator<Item = TypeAlias> + '_> {
1103        self.body().map(|syntax| children(syntax))
1104    }
1105
1106    ///
1107    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    /// A function declaration.
1114    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    /// A function without a body in context of traits
1131    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
1143///
1144pub enum FunctionItem {
1145    ///
1146    Full(Function),
1147    ///
1148    Partial(PartialFunction),
1149}
1150
1151impl FunctionItem {
1152    ///
1153    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    ///
1161    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    ///
1169    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
1202///
1203pub enum Fragment {
1204    ///
1205    EnumVariant(EnumVariant),
1206
1207    /// Modifiers (if used inline).
1208    Modifiers(Modifiers),
1209
1210    /// Unknown or error node.
1211    Unknown(UnknownToken),
1212
1213    ///
1214    MatchArm(MatchArm),
1215    ///
1216    Generic {
1217        ///
1218        syntax: SyntaxNode,
1219    },
1220}