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}