rust_code_analysis/
node.rs

1use tree_sitter::Node as OtherNode;
2
3use crate::traits::Search;
4
5/// An `AST` node.
6#[derive(Clone, Copy)]
7pub struct Node<'a>(OtherNode<'a>);
8
9impl<'a> Node<'a> {
10    /// Checks if a node represents a syntax error or contains any syntax errors
11    /// anywhere within it.
12    pub fn has_error(&self) -> bool {
13        self.0.has_error()
14    }
15
16    pub(crate) fn new(node: OtherNode<'a>) -> Self {
17        Node(node)
18    }
19
20    pub(crate) fn object(&self) -> OtherNode<'a> {
21        self.0
22    }
23
24    pub(crate) fn children(&self) -> impl ExactSizeIterator<Item = Node<'a>> {
25        let mut cursor = self.0.walk();
26        cursor.goto_first_child();
27        (0..self.object().child_count()).into_iter().map(move |_| {
28            let result = Node::new(cursor.node());
29            cursor.goto_next_sibling();
30            result
31        })
32    }
33}
34
35impl<'a> Search<'a> for Node<'a> {
36    fn first_occurence(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
37        let mut cursor = self.0.walk();
38        let mut stack = Vec::new();
39        let mut children = Vec::new();
40
41        stack.push(*self);
42
43        while let Some(node) = stack.pop() {
44            if pred(node.0.kind_id()) {
45                return Some(node);
46            }
47            cursor.reset(node.0);
48            if cursor.goto_first_child() {
49                loop {
50                    children.push(Node::new(cursor.node()));
51                    if !cursor.goto_next_sibling() {
52                        break;
53                    }
54                }
55                for child in children.drain(..).rev() {
56                    stack.push(child);
57                }
58            }
59        }
60
61        None
62    }
63
64    fn act_on_node(&self, action: &mut dyn FnMut(&Node<'a>)) {
65        let mut cursor = self.0.walk();
66        let mut stack = Vec::new();
67        let mut children = Vec::new();
68
69        stack.push(*self);
70
71        while let Some(node) = stack.pop() {
72            action(&node);
73            cursor.reset(node.0);
74            if cursor.goto_first_child() {
75                loop {
76                    children.push(Node::new(cursor.node()));
77                    if !cursor.goto_next_sibling() {
78                        break;
79                    }
80                }
81                for child in children.drain(..).rev() {
82                    stack.push(child);
83                }
84            }
85        }
86    }
87
88    fn first_child(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
89        let mut cursor = self.0.walk();
90        for child in self.0.children(&mut cursor) {
91            if pred(child.kind_id()) {
92                return Some(Node::new(child));
93            }
94        }
95        None
96    }
97
98    fn act_on_child(&self, action: &mut dyn FnMut(&Node<'a>)) {
99        let mut cursor = self.0.walk();
100        for child in self.0.children(&mut cursor) {
101            action(&Node::new(child));
102        }
103    }
104}