Rizin
unix-like reverse engineering framework and cli tools
tree_cursor.c
Go to the documentation of this file.
1 #include "tree_sitter/api.h"
2 #include "./alloc.h"
3 #include "./tree_cursor.h"
4 #include "./language.h"
5 #include "./tree.h"
6 
7 typedef struct {
9  const TSTree *tree;
15 
16 // CursorChildIterator
17 
19  TreeCursorEntry *last_entry = array_back(&self->stack);
20  if (ts_subtree_child_count(*last_entry->subtree) == 0) {
21  return (CursorChildIterator) {NULL_SUBTREE, self->tree, length_zero(), 0, 0, NULL};
22  }
23  const TSSymbol *alias_sequence = ts_language_alias_sequence(
24  self->tree->language,
25  last_entry->subtree->ptr->production_id
26  );
27  return (CursorChildIterator) {
28  .tree = self->tree,
29  .parent = *last_entry->subtree,
30  .position = last_entry->position,
31  .child_index = 0,
32  .structural_child_index = 0,
33  .alias_sequence = alias_sequence,
34  };
35 }
36 
38  CursorChildIterator *self,
39  TreeCursorEntry *result,
40  bool *visible
41 ) {
42  if (!self->parent.ptr || self->child_index == self->parent.ptr->child_count) return false;
43  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
44  *result = (TreeCursorEntry) {
45  .subtree = child,
46  .position = self->position,
47  .child_index = self->child_index,
48  .structural_child_index = self->structural_child_index,
49  };
50  *visible = ts_subtree_visible(*child);
51  bool extra = ts_subtree_extra(*child);
52  if (!extra && self->alias_sequence) {
53  *visible |= self->alias_sequence[self->structural_child_index];
54  self->structural_child_index++;
55  }
56 
57  self->position = length_add(self->position, ts_subtree_size(*child));
58  self->child_index++;
59 
60  if (self->child_index < self->parent.ptr->child_count) {
61  Subtree next_child = ts_subtree_children(self->parent)[self->child_index];
62  self->position = length_add(self->position, ts_subtree_padding(next_child));
63  }
64 
65  return true;
66 }
67 
68 // TSTreeCursor - lifecycle
69 
71  TSTreeCursor self = {NULL, NULL, {0, 0}};
72  ts_tree_cursor_init((TreeCursor *)&self, node);
73  return self;
74 }
75 
77  ts_tree_cursor_init((TreeCursor *)_self, node);
78 }
79 
81  self->tree = node.tree;
82  array_clear(&self->stack);
83  array_push(&self->stack, ((TreeCursorEntry) {
84  .subtree = (const Subtree *)node.id,
85  .position = {
86  ts_node_start_byte(node),
87  ts_node_start_point(node)
88  },
89  .child_index = 0,
90  .structural_child_index = 0,
91  }));
92 }
93 
95  TreeCursor *self = (TreeCursor *)_self;
96  array_delete(&self->stack);
97 }
98 
99 // TSTreeCursor - walking the tree
100 
102  TreeCursor *self = (TreeCursor *)_self;
103 
104  bool did_descend;
105  do {
106  did_descend = false;
107 
108  bool visible;
111  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
112  if (visible) {
113  array_push(&self->stack, entry);
114  return true;
115  }
116 
117  if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
118  array_push(&self->stack, entry);
119  did_descend = true;
120  break;
121  }
122  }
123  } while (did_descend);
124 
125  return false;
126 }
127 
129  TreeCursor *self = (TreeCursor *)_self;
130  uint32_t initial_size = self->stack.size;
131  uint32_t visible_child_index = 0;
132 
133  bool did_descend;
134  do {
135  did_descend = false;
136 
137  bool visible;
140  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
141  uint32_t end_byte = entry.position.bytes + ts_subtree_size(*entry.subtree).bytes;
142  bool at_goal = end_byte >= goal_byte;
143  uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
144 
145  if (at_goal) {
146  if (visible) {
147  array_push(&self->stack, entry);
148  return visible_child_index;
149  }
150 
151  if (visible_child_count > 0) {
152  array_push(&self->stack, entry);
153  did_descend = true;
154  break;
155  }
156  } else if (visible) {
157  visible_child_index++;
158  } else {
159  visible_child_index += visible_child_count;
160  }
161  }
162  } while (did_descend);
163 
164  self->stack.size = initial_size;
165  return -1;
166 }
167 
169  TreeCursor *self = (TreeCursor *)_self;
170  uint32_t initial_size = self->stack.size;
171  uint32_t visible_child_index = 0;
172 
173  bool did_descend;
174  do {
175  did_descend = false;
176 
177  bool visible;
180  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
181  TSPoint end_point = point_add(entry.position.extent, ts_subtree_size(*entry.subtree).extent);
182  bool at_goal = point_gte(end_point, goal_point);
183  uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
184  if (at_goal) {
185  if (visible) {
186  array_push(&self->stack, entry);
187  return visible_child_index;
188  }
189  if (visible_child_count > 0) {
190  array_push(&self->stack, entry);
191  did_descend = true;
192  break;
193  }
194  } else if (visible) {
195  visible_child_index++;
196  } else {
197  visible_child_index += visible_child_count;
198  }
199  }
200  } while (did_descend);
201 
202  self->stack.size = initial_size;
203  return -1;
204 }
205 
207  TreeCursor *self = (TreeCursor *)_self;
208  uint32_t initial_size = self->stack.size;
209 
210  while (self->stack.size > 1) {
211  TreeCursorEntry entry = array_pop(&self->stack);
213  iterator.child_index = entry.child_index;
214  iterator.structural_child_index = entry.structural_child_index;
215  iterator.position = entry.position;
216 
217  bool visible = false;
219  if (visible && self->stack.size + 1 < initial_size) break;
220 
221  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
222  if (visible) {
223  array_push(&self->stack, entry);
224  return true;
225  }
226 
227  if (ts_subtree_visible_child_count(*entry.subtree)) {
228  array_push(&self->stack, entry);
230  return true;
231  }
232  }
233  }
234 
235  self->stack.size = initial_size;
236  return false;
237 }
238 
240  TreeCursor *self = (TreeCursor *)_self;
241  for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
242  TreeCursorEntry *entry = &self->stack.contents[i];
243  if (ts_subtree_visible(*entry->subtree)) {
244  self->stack.size = i + 1;
245  return true;
246  }
247  if (i > 0 && !ts_subtree_extra(*entry->subtree)) {
248  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
250  self->tree->language,
251  parent_entry->subtree->ptr->production_id,
252  entry->structural_child_index
253  )) {
254  self->stack.size = i + 1;
255  return true;
256  }
257  }
258  }
259  return false;
260 }
261 
263  const TreeCursor *self = (const TreeCursor *)_self;
264  TreeCursorEntry *last_entry = array_back(&self->stack);
265  TSSymbol alias_symbol = 0;
266  if (self->stack.size > 1 && !ts_subtree_extra(*last_entry->subtree)) {
267  TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];
268  alias_symbol = ts_language_alias_at(
269  self->tree->language,
270  parent_entry->subtree->ptr->production_id,
271  last_entry->structural_child_index
272  );
273  }
274  return ts_node_new(
275  self->tree,
276  last_entry->subtree,
277  last_entry->position,
278  alias_symbol
279  );
280 }
281 
282 // Private - Get various facts about the current node that are needed
283 // when executing tree queries.
285  const TSTreeCursor *_self,
287  bool *has_later_siblings,
288  bool *has_later_named_siblings,
289  bool *can_have_later_siblings_with_this_field,
290  TSSymbol *supertypes,
291  unsigned *supertype_count
292 ) {
293  const TreeCursor *self = (const TreeCursor *)_self;
294  unsigned max_supertypes = *supertype_count;
295  *field_id = 0;
296  *supertype_count = 0;
297  *has_later_siblings = false;
298  *has_later_named_siblings = false;
299  *can_have_later_siblings_with_this_field = false;
300 
301  // Walk up the tree, visiting the current node and its invisible ancestors,
302  // because fields can refer to nodes through invisible *wrapper* nodes,
303  for (unsigned i = self->stack.size - 1; i > 0; i--) {
304  TreeCursorEntry *entry = &self->stack.contents[i];
305  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
306 
307  const TSSymbol *alias_sequence = ts_language_alias_sequence(
308  self->tree->language,
309  parent_entry->subtree->ptr->production_id
310  );
311 
312  #define subtree_symbol(subtree, structural_child_index) \
313  (( \
314  !ts_subtree_extra(subtree) && \
315  alias_sequence && \
316  alias_sequence[structural_child_index] \
317  ) ? \
318  alias_sequence[structural_child_index] : \
319  ts_subtree_symbol(subtree))
320 
321  // Stop walking up when a visible ancestor is found.
322  TSSymbol entry_symbol = subtree_symbol(
323  *entry->subtree,
324  entry->structural_child_index
325  );
327  self->tree->language,
328  entry_symbol
329  );
330  if (i != self->stack.size - 1 && entry_metadata.visible) break;
331 
332  // Record any supertypes
333  if (entry_metadata.supertype && *supertype_count < max_supertypes) {
334  supertypes[*supertype_count] = entry_symbol;
335  (*supertype_count)++;
336  }
337 
338  // Determine if the current node has later siblings.
339  if (!*has_later_siblings) {
340  unsigned sibling_count = parent_entry->subtree->ptr->child_count;
341  unsigned structural_child_index = entry->structural_child_index;
342  if (!ts_subtree_extra(*entry->subtree)) structural_child_index++;
343  for (unsigned j = entry->child_index + 1; j < sibling_count; j++) {
344  Subtree sibling = ts_subtree_children(*parent_entry->subtree)[j];
346  self->tree->language,
347  subtree_symbol(sibling, structural_child_index)
348  );
349  if (sibling_metadata.visible) {
350  *has_later_siblings = true;
351  if (*has_later_named_siblings) break;
352  if (sibling_metadata.named) {
353  *has_later_named_siblings = true;
354  break;
355  }
356  } else if (ts_subtree_visible_child_count(sibling) > 0) {
357  *has_later_siblings = true;
358  if (*has_later_named_siblings) break;
359  if (sibling.ptr->named_child_count > 0) {
360  *has_later_named_siblings = true;
361  break;
362  }
363  }
364  if (!ts_subtree_extra(sibling)) structural_child_index++;
365  }
366  }
367 
368  #undef subtree_symbol
369 
370  if (!ts_subtree_extra(*entry->subtree)) {
371  const TSFieldMapEntry *field_map, *field_map_end;
373  self->tree->language,
374  parent_entry->subtree->ptr->production_id,
375  &field_map, &field_map_end
376  );
377 
378  // Look for a field name associated with the current node.
379  if (!*field_id) {
380  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
381  if (!i->inherited && i->child_index == entry->structural_child_index) {
382  *field_id = i->field_id;
383  break;
384  }
385  }
386  }
387 
388  // Determine if the current node can have later siblings with the same field name.
389  if (*field_id) {
390  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
391  if (
392  i->field_id == *field_id &&
393  i->child_index > entry->structural_child_index
394  ) {
395  *can_have_later_siblings_with_this_field = true;
396  break;
397  }
398  }
399  }
400  }
401  }
402 }
403 
405  const TreeCursor *self = (const TreeCursor *)_self;
406  for (int i = (int)self->stack.size - 2; i >= 0; i--) {
407  TreeCursorEntry *entry = &self->stack.contents[i];
408  bool is_visible = true;
409  TSSymbol alias_symbol = 0;
410  if (i > 0) {
411  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
412  alias_symbol = ts_language_alias_at(
413  self->tree->language,
414  parent_entry->subtree->ptr->production_id,
415  entry->structural_child_index
416  );
417  is_visible = (alias_symbol != 0) || ts_subtree_visible(*entry->subtree);
418  }
419  if (is_visible) {
420  return ts_node_new(
421  self->tree,
422  entry->subtree,
423  entry->position,
424  alias_symbol
425  );
426  }
427  }
428  return ts_node_new(NULL, NULL, length_zero(), 0);
429 }
430 
432  const TreeCursor *self = (const TreeCursor *)_self;
433 
434  // Walk up the tree, visiting the current node and its invisible ancestors.
435  for (unsigned i = self->stack.size - 1; i > 0; i--) {
436  TreeCursorEntry *entry = &self->stack.contents[i];
437  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
438 
439  // Stop walking up when another visible node is found.
440  if (i != self->stack.size - 1) {
441  if (ts_subtree_visible(*entry->subtree)) break;
442  if (
443  !ts_subtree_extra(*entry->subtree) &&
445  self->tree->language,
446  parent_entry->subtree->ptr->production_id,
447  entry->structural_child_index
448  )
449  ) break;
450  }
451 
452  if (ts_subtree_extra(*entry->subtree)) break;
453 
454  const TSFieldMapEntry *field_map, *field_map_end;
456  self->tree->language,
457  parent_entry->subtree->ptr->production_id,
458  &field_map, &field_map_end
459  );
460  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
461  if (!i->inherited && i->child_index == entry->structural_child_index) {
462  return i->field_id;
463  }
464  }
465  }
466  return 0;
467 }
468 
471  if (id) {
472  const TreeCursor *self = (const TreeCursor *)_self;
473  return self->tree->language->field_names[id];
474  } else {
475  return NULL;
476  }
477 }
478 
480  const TreeCursor *cursor = (const TreeCursor *)_cursor;
481  TSTreeCursor res = {NULL, NULL, {0, 0}};
482  TreeCursor *copy = (TreeCursor *)&res;
483  copy->tree = cursor->tree;
484  array_init(&copy->stack);
485  array_push_all(&copy->stack, &cursor->stack);
486  return res;
487 }
const MCPhysReg * iterator
lzma_index ** i
Definition: index.h:629
#define array_init(self)
Definition: array.h:22
#define array_back(self)
Definition: array.h:33
#define array_push_all(self, other)
Definition: array.h:54
#define array_push(self, element)
Definition: array.h:43
#define array_pop(self)
Definition: array.h:82
#define array_delete(self)
Definition: array.h:41
#define array_clear(self)
Definition: array.h:35
#define NULL
Definition: cris-opc.c:27
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:38
static void ts_language_field_map(const TSLanguage *self, uint32_t production_id, const TSFieldMapEntry **start, const TSFieldMapEntry **end)
Definition: language.h:246
static const TSSymbol * ts_language_alias_sequence(const TSLanguage *self, uint32_t production_id)
Definition: language.h:227
static TSSymbol ts_language_alias_at(const TSLanguage *self, uint32_t production_id, uint32_t child_index)
Definition: language.h:236
static Length length_zero(void)
Definition: length.h:39
static Length length_add(Length len1, Length len2)
Definition: length.h:25
TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias)
Definition: node.c:17
int id
Definition: op.c:540
static TSPoint point_add(TSPoint a, TSPoint b)
Definition: point.h:14
static bool point_gte(TSPoint a, TSPoint b)
Definition: point.h:40
@ field_id
Definition: parser.c:1736
uint16_t TSFieldId
Definition: parser.h:20
uint16_t TSSymbol
Definition: parser.h:19
long int64_t
Definition: sftypes.h:32
unsigned int uint32_t
Definition: sftypes.h:29
const TSSymbol * alias_sequence
Definition: tree_cursor.c:13
uint32_t structural_child_index
Definition: tree_cursor.c:12
const TSTree * tree
Definition: tree_cursor.c:9
uint32_t child_index
Definition: tree_cursor.c:11
Definition: length.h:9
uint32_t bytes
Definition: length.h:10
TSPoint extent
Definition: length.h:11
uint32_t named_child_count
Definition: subtree.h:136
uint32_t child_count
Definition: subtree.h:117
uint16_t production_id
Definition: subtree.h:140
Definition: api.h:92
const TSTree * tree
Definition: api.h:95
Definition: api.h:55
bool visible
Definition: parser.h:36
bool supertype
Definition: parser.h:38
const void * tree
Definition: api.h:99
Definition: tree.h:15
const Subtree * subtree
Definition: tree_cursor.h:7
Length position
Definition: tree_cursor.h:8
uint32_t structural_child_index
Definition: tree_cursor.h:10
const TSTree * tree
Definition: tree_cursor.h:14
Definition: zipcmp.c:77
zip_uint64_t size
Definition: zipcmp.c:79
#define ts_subtree_children(self)
Definition: subtree.h:233
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static uint32_t ts_subtree_visible_child_count(Subtree self)
Definition: subtree.h:294
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
#define NULL_SUBTREE
Definition: subtree.h:19
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256
int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *_self, TSPoint goal_point)
Definition: tree_cursor.c:168
void ts_tree_cursor_delete(TSTreeCursor *_self)
Definition: tree_cursor.c:94
TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self)
Definition: tree_cursor.c:404
void ts_tree_cursor_init(TreeCursor *self, TSNode node)
Definition: tree_cursor.c:80
static CursorChildIterator ts_tree_cursor_iterate_children(const TreeCursor *self)
Definition: tree_cursor.c:18
bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self)
Definition: tree_cursor.c:206
TSTreeCursor ts_tree_cursor_new(TSNode node)
Definition: tree_cursor.c:70
TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self)
Definition: tree_cursor.c:262
TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *_cursor)
Definition: tree_cursor.c:479
void ts_tree_cursor_reset(TSTreeCursor *_self, TSNode node)
Definition: tree_cursor.c:76
void ts_tree_cursor_current_status(const TSTreeCursor *_self, TSFieldId *field_id, bool *has_later_siblings, bool *has_later_named_siblings, bool *can_have_later_siblings_with_this_field, TSSymbol *supertypes, unsigned *supertype_count)
Definition: tree_cursor.c:284
TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self)
Definition: tree_cursor.c:431
const char * ts_tree_cursor_current_field_name(const TSTreeCursor *_self)
Definition: tree_cursor.c:469
static bool ts_tree_cursor_child_iterator_next(CursorChildIterator *self, TreeCursorEntry *result, bool *visible)
Definition: tree_cursor.c:37
bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self)
Definition: tree_cursor.c:101
int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t goal_byte)
Definition: tree_cursor.c:128
#define subtree_symbol(subtree, structural_child_index)
bool ts_tree_cursor_goto_parent(TSTreeCursor *_self)
Definition: tree_cursor.c:239
const SubtreeHeapData * ptr
Definition: subtree.h:158