1use 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 #[allow(dead_code)]
96 pub(crate) fn previous_sibling(&self) -> Option<Node<'a>> {
97 self.0.prev_sibling().map(Node)
98 }
99
100 pub(crate) fn next_sibling(&self) -> Option<Node<'a>> {
101 self.0.next_sibling().map(Node)
102 }
103
104 #[inline(always)]
105 pub(crate) fn is_child(&self, id: u16) -> bool {
106 self.0
107 .children(&mut self.0.walk())
108 .any(|child| child.kind_id() == id)
109 }
110
111 pub(crate) fn child_count(&self) -> usize {
112 self.0.child_count()
113 }
114
115 pub(crate) fn child_by_field_name(&self, name: &str) -> Option<Node<'_>> {
116 self.0.child_by_field_name(name).map(Node)
117 }
118
119 pub(crate) fn child(&self, pos: usize) -> Option<Node<'a>> {
120 self.0.child(pos).map(Node)
121 }
122
123 pub(crate) fn children(&self) -> impl ExactSizeIterator<Item = Node<'a>> + use<'a> {
124 let mut cursor = self.cursor();
125 cursor.goto_first_child();
126 (0..self.child_count()).map(move |_| {
127 let result = cursor.node();
128 cursor.goto_next_sibling();
129 result
130 })
131 }
132
133 pub(crate) fn cursor(&self) -> Cursor<'a> {
134 Cursor(self.0.walk())
135 }
136
137 #[allow(dead_code)]
138 pub(crate) fn get_parent(&self, level: usize) -> Option<Node<'a>> {
139 let mut level = level;
140 let mut node = *self;
141 while level != 0 {
142 node = node.parent()?;
143 level -= 1;
144 }
145
146 Some(node)
147 }
148
149 pub(crate) fn count_specific_ancestors<T: crate::ParserTrait>(
150 &self,
151 check: fn(&Node) -> bool,
152 stop: fn(&Node) -> bool,
153 ) -> usize {
154 let mut count = 0;
155 let mut node = *self;
156 while let Some(parent) = node.parent() {
157 if stop(&parent) {
158 break;
159 }
160 if check(&parent) && !T::Checker::is_else_if(&parent) {
161 count += 1;
162 }
163 node = parent;
164 }
165 count
166 }
167
168 pub(crate) fn has_ancestors(&self, typ: fn(&Node) -> bool, typs: fn(&Node) -> bool) -> bool {
169 let mut res = false;
170 let mut node = *self;
171 if let Some(parent) = node.parent()
172 && typ(&parent)
173 {
174 node = parent;
175 }
176 if let Some(parent) = node.parent()
177 && typs(&parent)
178 {
179 res = true;
180 }
181 res
182 }
183}
184
185#[derive(Clone)]
187pub struct Cursor<'a>(TreeCursor<'a>);
188
189impl<'a> Cursor<'a> {
190 pub(crate) fn reset(&mut self, node: &Node<'a>) {
191 self.0.reset(node.0);
192 }
193
194 pub(crate) fn goto_next_sibling(&mut self) -> bool {
195 self.0.goto_next_sibling()
196 }
197
198 pub(crate) fn goto_first_child(&mut self) -> bool {
199 self.0.goto_first_child()
200 }
201
202 pub(crate) fn node(&self) -> Node<'a> {
203 Node(self.0.node())
204 }
205}
206
207impl<'a> Search<'a> for Node<'a> {
208 fn first_occurrence(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
209 let mut cursor = self.cursor();
210 let mut stack = Vec::new();
211 let mut children = Vec::new();
212
213 stack.push(*self);
214
215 while let Some(node) = stack.pop() {
216 if pred(node.kind_id()) {
217 return Some(node);
218 }
219 cursor.reset(&node);
220 if cursor.goto_first_child() {
221 loop {
222 children.push(cursor.node());
223 if !cursor.goto_next_sibling() {
224 break;
225 }
226 }
227 for child in children.drain(..).rev() {
228 stack.push(child);
229 }
230 }
231 }
232
233 None
234 }
235
236 fn act_on_node(&self, action: &mut dyn FnMut(&Node<'a>)) {
237 let mut cursor = self.cursor();
238 let mut stack = Vec::new();
239 let mut children = Vec::new();
240
241 stack.push(*self);
242
243 while let Some(node) = stack.pop() {
244 action(&node);
245 cursor.reset(&node);
246 if cursor.goto_first_child() {
247 loop {
248 children.push(cursor.node());
249 if !cursor.goto_next_sibling() {
250 break;
251 }
252 }
253 for child in children.drain(..).rev() {
254 stack.push(child);
255 }
256 }
257 }
258 }
259
260 fn first_child(&self, pred: fn(u16) -> bool) -> Option<Node<'a>> {
261 self.children().find(|&child| pred(child.kind_id()))
262 }
263
264 fn act_on_child(&self, action: &mut dyn FnMut(&Node<'a>)) {
265 for child in self.children() {
266 action(&child);
267 }
268 }
269}