kodept_ast/graph/
children.rs1use 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}