rust_code_analysis/
node.rs1use tree_sitter::Node as OtherNode;
2
3use crate::traits::Search;
4
5#[derive(Clone, Copy)]
7pub struct Node<'a>(OtherNode<'a>);
8
9impl<'a> Node<'a> {
10 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}