rust_code_analysis/
asttools.rs1use crate::node::Node;
2
3#[allow(dead_code)]
4pub fn get_parent<'a>(node: &'a Node<'a>, level: usize) -> Option<Node<'a>> {
5 let mut level = level;
6 let mut node = *node;
7 while level != 0 {
8 if let Some(parent) = node.object().parent() {
9 node = Node::new(parent);
10 } else {
11 return None;
12 }
13 level -= 1;
14 }
15
16 Some(node)
17}
18
19macro_rules! has_ancestors {
20 ($node:expr, $( $typs:pat_param )|*, $( $typ:pat_param ),+) => {{
21 let mut res = false;
22 loop {
23 let mut node = *$node;
24 $(
25 if let Some(parent) = node.object().parent() {
26 match parent.kind_id().into() {
27 $typ => {
28 node = Node::new(parent);
29 },
30 _ => {
31 break;
32 }
33 }
34 } else {
35 break;
36 }
37 )*
38 if let Some(parent) = node.object().parent() {
39 match parent.kind_id().into() {
40 $( $typs )|+ => {
41 res = true;
42 },
43 _ => {
44 break;
45 }
46 }
47 } else {
48 break;
49 }
50 break;
51 }
52 res
53 }};
54}
55
56macro_rules! count_specific_ancestors {
57 ($node:expr, $( $typs:pat_param )|*, $( $stops:pat_param )|*) => {{
58 let mut count = 0;
59 let mut node = *$node;
60 while let Some(parent) = node.object().parent() {
61 match parent.kind_id().into() {
62 $( $typs )|* => {
63 if !Self::is_else_if(&Node::new(parent)) {
64 count += 1;
65 }
66 },
67 $( $stops )|* => break,
68 _ => {}
69 }
70 node = Node::new(parent);
71 }
72 count
73 }};
74}