rust_code_analysis_code_split/
node.rs1use tree_sitter::Node as OtherNode;
2use tree_sitter::Tree as OtherTree;
3use tree_sitter::{Parser, TreeCursor};
4
5use crate::checker::Checker;
6use crate::traits::{LanguageInfo, Search};
7
8#[derive(Clone, Debug)]
9pub(crate) struct Tree(OtherTree);
10
11impl Tree {
12 pub(crate) fn new<T: LanguageInfo>(code: &[u8]) -> Self {
13 let mut parser = Parser::new();
14 parser
15 .set_language(&T::get_lang().get_ts_language())
16 .unwrap();
17
18 Self(parser.parse(code, None).unwrap())
19 }
20
21 pub(crate) fn get_root(&self) -> Node<'_> {
22 Node(self.0.root_node())
23 }
24}
25
26#[derive(Clone, Copy, Debug)]
31pub struct Node<'a>(pub OtherNode<'a>);
32
33impl<'a> Node<'a> {
34 pub fn has_error(&self) -> bool {
37 self.0.has_error()
38 }
39
40 pub(crate) fn id(&self) -> usize {
41 self.0.id()
42 }
43
44 pub(crate) fn kind(&self) -> &'static str {
45 self.0.kind()
46 }
47
48 pub(crate) fn kind_id(&self) -> u16 {
49 self.0.kind_id()
50 }
51
52 pub(crate) fn utf8_text(&self, data: &'a [u8]) -> Option<&'a str> {
53 self.0.utf8_text(data).ok()
54 }
55
56 pub(crate) fn start_byte(&self) -> usize {
57 self.0.start_byte()
58 }
59
60 pub(crate) fn end_byte(&self) -> usize {
61 self.0.end_byte()
62 }
63
64 pub(crate) fn start_position(&self) -> (usize, usize) {
65 let temp = self.0.start_position();
66 (temp.row, temp.column)
67 }
68
69 pub(crate) fn end_position(&self) -> (usize, usize) {
70 let temp = self.0.end_position();
71 (temp.row, temp.column)
72 }
73
74 pub(crate) fn start_row(&self) -> usize {
75 self.0.start_position().row
76 }
77
78 pub(crate) fn end_row(&self) -> usize {
79 self.0.end_position().row
80 }
81
82 pub(crate) fn parent(&self) -> Option<Node<'a>> {
83 self.0.parent().map(Node)
84 }
85
86 #[inline(always)]
87 pub(crate) fn has_sibling(&self, id: u16) -> bool {
88 self.0.parent().is_some_and(|parent| {
89 self.0
90 .children(&mut parent.walk())
91 .any(|child| child.kind_id() == id)
92 })
93 }
94
95 pub(crate) fn previous_sibling(&self) -> Option<Node<'a>> {
96 self.0.prev_sibling().map(Node)
97 }
98
99 pub(crate) fn next_sibling(&self) -> Option<Node<'a>> {
100 self.0.next_sibling().map(Node)
101 }
102
103 #[inline(always)]
104 pub(crate) fn is_child(&self, id: u16) -> bool {
105 self.0
106 .children(&mut self.0.walk())
107 .any(|child| child.kind_id() == id)
108 }
109
110 pub(crate) fn child_count(&self) -> usize {
111 self.0.child_count()
112 }
113
114 pub(crate) fn child_by_field_name(&self, name: &str) -> Option<Node<'_>> {
115 self.0.child_by_field_name(name).map(Node)
116 }
117
118 pub(crate) fn child(&self, pos: usize) -> Option<Node<'a>> {
119 self.0.child(pos as u32).map(Node)
120 }
121
122 pub(crate) fn children(&self) -> impl ExactSizeIterator<Item = Node<'a>> + use<'a> {
123 let mut cursor = self.cursor();
124 cursor.goto_first_child();
125 (0..self.child_count()).map(move |_| {
126 let result = cursor.node();
127 cursor.goto_next_sibling();
128 result
129 })
130 }
131
132 pub(crate) fn cursor(&self) -> Cursor<'a> {
133 Cursor(self.0.walk())
134 }
135
136 #[allow(dead_code)]
137 pub(crate) fn get_parent(&self, level: usize) -> Option<Node<'a>> {
138 let mut level = level;
139 let mut node = *self;
140 while level != 0 {
141 if let Some(parent) = node.parent() {
142 node = parent;
143 } else {
144 return None;
145 }
146 level -= 1;
147 }
148
149 Some(node)
150 }
151
152 pub(crate) fn count_specific_ancestors<T: crate::ParserTrait>(
153 &self,
154 check: fn(&Node) -> bool,
155 stop: fn(&Node) -> bool,
156 ) -> usize {
157 let mut count = 0;
158 let mut node = *self;
159 while let Some(parent) = node.parent() {
160 if stop(&parent) {
161 break;
162 }
163 if check(&parent) && !T::Checker::is_else_if(&parent) {
164 count += 1;
165 }
166 node = parent;
167 }
168 count
169 }
170
171 pub(crate) fn has_ancestors(&self, typ: fn(&Node) -> bool, typs: fn(&Node) -> bool) -> bool {
172 let mut res = false;
173 let mut node = *self;
174 if let Some(parent) = node.parent()
175 && typ(&parent)
176 {
177 node = parent;
178 }
179 if let Some(parent) = node.parent()
180 && typs(&parent)
181 {
182 res = true;
183 }
184 res
185 }
186}
187
188#[derive(Clone)]
190pub struct Cursor<'a>(TreeCursor<'a>);
191
192impl<'a> Cursor<'a> {
193 pub(crate) fn reset(&mut self, node: &Node<'a>) {
194 self.0.reset(node.0);
195 }
196
197 pub(crate) fn goto_next_sibling(&mut self) -> bool {
198 self.0.goto_next_sibling()
199 }
200
201 pub(crate) fn goto_first_child(&mut self) -> bool {
202 self.0.goto_first_child()
203 }
204
205 pub(crate) fn node(&self) -> Node<'a> {
206 Node(self.0.node())
207 }
208}
209
210impl<'a> Search<'a> for Node<'a> {
211 fn first_occurrence(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
212 let mut cursor = self.cursor();
213 let mut stack = Vec::new();
214 let mut children = Vec::new();
215
216 stack.push(*self);
217
218 while let Some(node) = stack.pop() {
219 if pred(node.kind_id()) {
220 return Some(node);
221 }
222 cursor.reset(&node);
223 if cursor.goto_first_child() {
224 loop {
225 children.push(cursor.node());
226 if !cursor.goto_next_sibling() {
227 break;
228 }
229 }
230 for child in children.drain(..).rev() {
231 stack.push(child);
232 }
233 }
234 }
235
236 None
237 }
238
239 fn act_on_node(&self, action: &mut dyn FnMut(&Node<'a>)) {
240 let mut cursor = self.cursor();
241 let mut stack = Vec::new();
242 let mut children = Vec::new();
243
244 stack.push(*self);
245
246 while let Some(node) = stack.pop() {
247 action(&node);
248 cursor.reset(&node);
249 if cursor.goto_first_child() {
250 loop {
251 children.push(cursor.node());
252 if !cursor.goto_next_sibling() {
253 break;
254 }
255 }
256 for child in children.drain(..).rev() {
257 stack.push(child);
258 }
259 }
260 }
261 }
262
263 fn first_child(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
264 self.children().find(|&child| pred(child.kind_id()))
265 }
266
267 fn act_on_child(&self, action: &mut dyn FnMut(&Node<'a>)) {
268 for child in self.children() {
269 action(&child);
270 }
271 }
272}