teo_parser/macros/
node.rs

1#[macro_export]
2macro_rules! declare_node {
3    ($struct_name:ident) => {
4        #[derive(Debug)]
5        pub struct $struct_name {
6            pub(crate) span: crate::ast::span::Span,
7            pub(crate) path: Vec<usize>,
8        }
9    };
10    ($struct_name:ident, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
11        #[derive(Debug)]
12        pub struct $struct_name {
13            pub(crate) span: crate::ast::span::Span,
14            pub(crate) path: Vec<usize>,
15            $($vis $element: $ty),*
16        }
17    };
18}
19
20#[macro_export]
21macro_rules! declare_container_node {
22    ($struct_name:ident) => {
23        #[derive(Debug)]
24        pub struct $struct_name {
25            pub(crate) span: Span,
26            pub(crate) path: Vec<usize>,
27            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
28        }
29    };
30    ($struct_name:ident, named) => {
31        #[derive(Debug)]
32        pub struct $struct_name {
33            pub(crate) span: Span,
34            pub(crate) path: Vec<usize>,
35            pub(crate) string_path: Vec<String>,
36            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
37        }
38    };
39    ($struct_name:ident, availability) => {
40        #[derive(Debug)]
41        pub struct $struct_name {
42            pub(crate) span: Span,
43            pub(crate) path: Vec<usize>,
44            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
45            pub(crate) define_availability: crate::availability::Availability,
46            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
47        }
48    };
49    ($struct_name:ident, named, availability, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
50        #[derive(Debug)]
51        pub struct $struct_name {
52            pub(crate) span: crate::ast::span::Span,
53            pub(crate) path: Vec<usize>,
54            pub(crate) string_path: Vec<String>,
55            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
56            pub(crate) define_availability: crate::availability::Availability,
57            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
58            $($vis $element: $ty),*
59        }
60    };
61    ($struct_name:ident, named, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
62        #[derive(Debug)]
63        pub struct $struct_name {
64            pub(crate) span: crate::ast::span::Span,
65            pub(crate) path: Vec<usize>,
66            pub(crate) string_path: Vec<String>,
67            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
68            $($vis $element: $ty),*
69        }
70    };
71    ($struct_name:ident, availability, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
72        #[derive(Debug)]
73        pub struct $struct_name {
74            pub(crate) span: crate::ast::span::Span,
75            pub(crate) path: Vec<usize>,
76            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
77            pub(crate) define_availability: crate::availability::Availability,
78            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
79            $($vis $element: $ty),*
80        }
81    };
82    ($struct_name:ident, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
83        #[derive(Debug)]
84        pub struct $struct_name {
85            pub(crate) span: crate::ast::span::Span,
86            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
87            pub(crate) path: Vec<usize>,
88            $($vis $element: $ty),*
89        }
90    };
91}
92
93#[macro_export]
94macro_rules! impl_node_defaults {
95    ($struct_name:ident) => {
96        impl crate::traits::identifiable::Identifiable for $struct_name {
97            fn path(&self) -> &Vec<usize> {
98               &self.path
99            }
100        }
101        impl crate::traits::node_trait::NodeTrait for $struct_name {
102            fn span(&self) -> crate::ast::span::Span {
103                self.span
104            }
105            fn children(&self) -> Option<&std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>> {
106                None
107            }
108        }
109        impl From<$struct_name> for crate::ast::node::Node {
110            fn from(value: $struct_name) -> Self {
111                crate::ast::node::Node::$struct_name(value)
112            }
113        }
114        impl TryFrom<crate::ast::node::Node> for $struct_name {
115            type Error = &'static str;
116            fn try_from(value: crate::ast::node::Node) -> Result<Self, Self::Error> {
117                match value {
118                    crate::ast::node::Node::$struct_name(n) => Ok(n),
119                    _ => Err("convert failed"),
120                }
121            }
122        }
123        impl<'a> TryFrom<&'a crate::ast::node::Node> for &'a $struct_name {
124            type Error = &'static str;
125
126            fn try_from(value: &'a crate::ast::node::Node) -> Result<Self, Self::Error> {
127                match value {
128                    crate::ast::node::Node::$struct_name(n) => Ok(n),
129                    _ => Err("convert failed"),
130                }
131            }
132        }
133        impl std::fmt::Display for $struct_name {
134            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135                f.write_str(&self.write_output_with_default_writer())
136            }
137        }
138    };
139}
140
141#[macro_export]
142macro_rules! impl_container_node_defaults {
143    ($struct_name:ident) => {
144        impl crate::traits::identifiable::Identifiable for $struct_name {
145            fn path(&self) -> &Vec<usize> {
146               &self.path
147            }
148        }
149        impl crate::traits::node_trait::NodeTrait for $struct_name {
150            fn span(&self) -> crate::ast::span::Span {
151                self.span
152            }
153            fn children(&self) -> Option<&std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>> {
154                Some(&self.children)
155            }
156        }
157        impl From<$struct_name> for crate::ast::node::Node {
158            fn from(value: $struct_name) -> Self {
159                crate::ast::node::Node::$struct_name(value)
160            }
161        }
162        impl TryFrom<crate::ast::node::Node> for $struct_name {
163            type Error = &'static str;
164            fn try_from(value: crate::ast::node::Node) -> Result<Self, Self::Error> {
165                match value {
166                    crate::ast::node::Node::$struct_name(n) => Ok(n),
167                    _ => Err("convert failed"),
168                }
169            }
170        }
171        impl<'a> TryFrom<&'a crate::ast::node::Node> for &'a $struct_name {
172            type Error = &'static str;
173
174            fn try_from(value: &'a crate::ast::node::Node) -> Result<Self, Self::Error> {
175                match value {
176                    crate::ast::node::Node::$struct_name(n) => Ok(n),
177                    _ => Err("convert failed"),
178                }
179            }
180        }
181        impl std::fmt::Display for $struct_name {
182            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
183                f.write_str(&self.write_output_with_default_writer())
184            }
185        }
186    };
187    ($struct_name:ident, named) => {
188        impl_container_node_defaults!($struct_name);
189        impl crate::traits::named_identifiable::NamedIdentifiable for $struct_name {
190            fn string_path(&self) -> &Vec<String> {
191                &self.string_path
192            }
193        }
194
195    };
196    ($struct_name:ident, availability) => {
197        impl_container_node_defaults!($struct_name);
198        impl crate::traits::has_availability::HasAvailability for $struct_name {
199            fn define_availability(&self) -> crate::availability::Availability {
200                self.define_availability
201            }
202            fn actual_availability(&self) -> crate::availability::Availability {
203                *self.actual_availability.borrow()
204            }
205        }
206    };
207    ($struct_name:ident, named, availability) => {
208        impl_container_node_defaults!($struct_name);
209        impl crate::traits::named_identifiable::NamedIdentifiable for $struct_name {
210            fn string_path(&self) -> &Vec<String> {
211                &self.string_path
212            }
213        }
214        impl crate::traits::has_availability::HasAvailability for $struct_name {
215            fn define_availability(&self) -> crate::availability::Availability {
216                self.define_availability
217            }
218            fn actual_availability(&self) -> crate::availability::Availability {
219                *self.actual_availability.borrow()
220            }
221        }
222    };
223}
224
225#[macro_export]
226macro_rules! node_children_iter {
227    ($struct_name:ident, $child_struct_name:ident, $iter_name:ident, $field_name:ident) => {
228        pub struct $iter_name<'a> {
229            index: usize,
230            owner: &'a $struct_name,
231        }
232        impl<'a> Iterator for $iter_name<'a> {
233            type Item = &'a $child_struct_name;
234            fn next(&mut self) -> Option<Self::Item> {
235                self.index += 1;
236                self.owner.$field_name.get(self.index - 1).map(|i| self.owner.children.get(i).unwrap().try_into().unwrap())
237            }
238        }
239    };
240}
241
242#[macro_export]
243macro_rules! node_children_iter_fn {
244    ($fn_name:ident, $iter_name:ident) => {
245        pub fn $fn_name(&self) -> $iter_name {
246            $iter_name {
247                owner: self,
248                index: 0,
249            }
250        }
251    }
252}
253
254#[macro_export]
255macro_rules! node_children_pair_iter {
256    ($struct_name:ident, $child_struct_name:ident, $iter_name:ident, $field_name:ident) => {
257        pub struct $iter_name<'a> {
258            index: usize,
259            owner: &'a $struct_name,
260        }
261        impl<'a> Iterator for $iter_name<'a> {
262            type Item = (&'a $child_struct_name, &'a $child_struct_name);
263            fn next(&mut self) -> Option<Self::Item> {
264                self.index += 1;
265                self.owner.$field_name.get(self.index - 1).map(|(k, v)| (self.owner.children.get(k).unwrap().try_into().unwrap(), self.owner.children.get(v).unwrap().try_into().unwrap()))
266            }
267        }
268    };
269}
270
271#[macro_export]
272macro_rules! node_child_fn {
273    ($name:ident, $struct_type:ident) => {
274        pub fn $name(&self) -> &$struct_type {
275            self.children.get(&self.$name).unwrap().try_into().unwrap()
276        }
277    }
278}
279
280#[macro_export]
281macro_rules! node_optional_child_fn {
282    ($name:ident, $class:ident) => {
283        pub fn $name(&self) -> Option<&$class> {
284            if let Some(id) = self.$name {
285                Some(self.children.get(&id).unwrap().try_into().unwrap())
286            } else {
287                None
288            }
289        }
290    }
291}