kodept_ast/graph/
children.rs

1use kodept_core::{ConvertibleToMut, ConvertibleToRef};
2
3use crate::graph::{AnyNode};
4use crate::graph::{PermTkn, SyntaxTree};
5use crate::graph::tags::ChildTag;
6use crate::graph::utils::FromOptVec;
7use crate::traits::Identifiable;
8
9pub mod tags {
10    pub type ChildTag = u8;
11
12    pub const PRIMARY: ChildTag = 1;
13    pub const SECONDARY: ChildTag = 2;
14    pub const LEFT: ChildTag = 3;
15    pub const RIGHT: ChildTag = 4;
16
17    pub static TAGS_DESC: [&str; 5] = ["", "P", "S", "L", "R"];
18}
19
20pub trait HasChildrenMarker<Child, const TAG: ChildTag>: Identifiable {
21    type Container: FromOptVec<T = Child>;
22
23    fn get_children<'b>(
24        &self,
25        tree: &'b SyntaxTree,
26        token: &'b PermTkn,
27    ) -> ChildrenRef<'b, Self, Child, TAG>
28    where
29        AnyNode: ConvertibleToRef<Child>,
30    {
31        Self::Container::unwrap(tree.children_of(self.get_id(), token, TAG))
32    }
33
34    fn get_children_mut<'b>(&self, tree: &'b SyntaxTree) -> ChildrenMut<'b, Self, Child, TAG>
35    where
36        AnyNode: ConvertibleToMut<Child>,
37    {
38        Self::Container::unwrap_mut(tree.children_of_raw(self.get_id(), TAG))
39    }
40}
41
42pub type ChildrenRef<'a, T, Child, const TAG: ChildTag> =
43    <<T as HasChildrenMarker<Child, TAG>>::Container as FromOptVec>::Ref<'a>;
44
45pub type ChildrenMut<'a, T, Child, const TAG: ChildTag> =
46    <<T as HasChildrenMarker<Child, TAG>>::Container as FromOptVec>::Mut<'a>;
47
48pub type ContainerT<T> = <T as FromOptVec>::T;
49
50pub mod macros {
51    macro_rules! with_children {
52        ($t:ty => {$($vis:vis $name:ident: $c_t:ty as $tag:tt,)*}) => {
53            paste::paste! {
54            $(
55            impl $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag> for $t {
56                type Container = $c_t;
57            }
58
59            impl $t {
60                $vis fn $name<'a>(
61                    &self,
62                    tree: &'a $crate::graph::SyntaxTree,
63                    token: &'a $crate::graph::PermTkn,
64                ) -> $crate::graph::ChildrenRef<'a, $t, $crate::graph::ContainerT<$c_t>, $tag> {
65                    <Self as $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag>>::get_children(self, tree, token)
66                }
67
68                $vis fn [<$name _mut>]<'a>(
69                    &self, tree: &'a $crate::graph::SyntaxTree
70                ) -> $crate::graph::ChildrenMut<'a, $t, $crate::graph::ContainerT<$c_t>, $tag> {
71                    <Self as $crate::graph::HasChildrenMarker<$crate::graph::ContainerT<$c_t>, $tag>>::get_children_mut(self, tree)
72                }
73            })*
74            }
75        };
76        ($t:ty => {$($vis:vis $name:ident: $c_t:ty,)*}) => {
77            $crate::with_children! { $t => {
78                $($vis $name: $c_t as 0,)*
79            } }
80        }
81    }
82    
83    pub(crate) use with_children;
84}