Rizin
unix-like reverse engineering framework and cli tools
get_changed_ranges.c File Reference
#include "./get_changed_ranges.h"
#include "./subtree.h"
#include "./language.h"
#include "./error_costs.h"
#include "./tree_cursor.h"
#include <assert.h>

Go to the source code of this file.

Classes

struct  Iterator
 

Enumerations

enum  IteratorComparison { IteratorDiffers , IteratorMayDiffer , IteratorMatches }
 

Functions

static void ts_range_array_add (TSRangeArray *self, Length start, Length end)
 
bool ts_range_array_intersects (const TSRangeArray *self, unsigned start_index, uint32_t start_byte, uint32_t end_byte)
 
void ts_range_array_get_changed_ranges (const TSRange *old_ranges, unsigned old_range_count, const TSRange *new_ranges, unsigned new_range_count, TSRangeArray *differences)
 
static Iterator iterator_new (TreeCursor *cursor, const Subtree *tree, const TSLanguage *language)
 
static bool iterator_done (Iterator *self)
 
static Length iterator_start_position (Iterator *self)
 
static Length iterator_end_position (Iterator *self)
 
static bool iterator_tree_is_visible (const Iterator *self)
 
static void iterator_get_visible_state (const Iterator *self, Subtree *tree, TSSymbol *alias_symbol, uint32_t *start_byte)
 
static void iterator_ascend (Iterator *self)
 
static bool iterator_descend (Iterator *self, uint32_t goal_position)
 
static void iterator_advance (Iterator *self)
 
static IteratorComparison iterator_compare (const Iterator *old_iter, const Iterator *new_iter)
 
unsigned ts_subtree_get_changed_ranges (const Subtree *old_tree, const Subtree *new_tree, TreeCursor *cursor1, TreeCursor *cursor2, const TSLanguage *language, const TSRangeArray *included_range_differences, TSRange **ranges)
 

Enumeration Type Documentation

◆ IteratorComparison

Enumerator
IteratorDiffers 
IteratorMayDiffer 
IteratorMatches 

Definition at line 298 of file get_changed_ranges.c.

298  {
IteratorComparison
@ IteratorDiffers
@ IteratorMatches
@ IteratorMayDiffer

Function Documentation

◆ iterator_advance()

static void iterator_advance ( Iterator self)
static

Definition at line 253 of file get_changed_ranges.c.

253  {
254  if (self->in_padding) {
255  self->in_padding = false;
256  if (iterator_tree_is_visible(self)) {
257  self->visible_depth++;
258  } else {
259  iterator_descend(self, 0);
260  }
261  return;
262  }
263 
264  for (;;) {
265  if (iterator_tree_is_visible(self)) self->visible_depth--;
266  TreeCursorEntry entry = array_pop(&self->cursor.stack);
267  if (iterator_done(self)) return;
268 
269  const Subtree *parent = array_back(&self->cursor.stack)->subtree;
270  uint32_t child_index = entry.child_index + 1;
271  if (ts_subtree_child_count(*parent) > child_index) {
272  Length position = length_add(entry.position, ts_subtree_total_size(*entry.subtree));
273  uint32_t structural_child_index = entry.structural_child_index;
274  if (!ts_subtree_extra(*entry.subtree)) structural_child_index++;
275  const Subtree *next_child = &ts_subtree_children(*parent)[child_index];
276 
277  array_push(&self->cursor.stack, ((TreeCursorEntry) {
278  .subtree = next_child,
279  .position = position,
280  .child_index = child_index,
281  .structural_child_index = structural_child_index,
282  }));
283 
284  if (iterator_tree_is_visible(self)) {
285  if (ts_subtree_padding(*next_child).bytes > 0) {
286  self->in_padding = true;
287  } else {
288  self->visible_depth++;
289  }
290  } else {
291  iterator_descend(self, 0);
292  }
293  break;
294  }
295  }
296 }
#define array_back(self)
Definition: array.h:33
#define array_push(self, element)
Definition: array.h:43
#define array_pop(self)
Definition: array.h:82
static bool iterator_done(Iterator *self)
static bool iterator_tree_is_visible(const Iterator *self)
static bool iterator_descend(Iterator *self, uint32_t goal_position)
static Length length_add(Length len1, Length len2)
Definition: length.h:25
unsigned int uint32_t
Definition: sftypes.h:29
TreeCursor cursor
Definition: length.h:9
uint32_t bytes
Definition: length.h:10
Definition: zipcmp.c:77
#define ts_subtree_children(self)
Definition: subtree.h:233
static Length ts_subtree_total_size(Subtree self)
Definition: subtree.h:274
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256

References array_back, array_pop, array_push, Length::bytes, iterator_descend(), iterator_done(), iterator_tree_is_visible(), length_add(), ts_subtree_child_count(), ts_subtree_children, ts_subtree_extra(), ts_subtree_padding(), and ts_subtree_total_size().

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_ascend()

static void iterator_ascend ( Iterator self)
static

Definition at line 203 of file get_changed_ranges.c.

203  {
204  if (iterator_done(self)) return;
205  if (iterator_tree_is_visible(self) && !self->in_padding) self->visible_depth--;
206  if (array_back(&self->cursor.stack)->child_index > 0) self->in_padding = false;
207  self->cursor.stack.size--;
208 }

References array_back, iterator_done(), and iterator_tree_is_visible().

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_compare()

static IteratorComparison iterator_compare ( const Iterator old_iter,
const Iterator new_iter 
)
static

Definition at line 304 of file get_changed_ranges.c.

307  {
308  Subtree old_tree = NULL_SUBTREE;
309  Subtree new_tree = NULL_SUBTREE;
310  uint32_t old_start = 0;
311  uint32_t new_start = 0;
312  TSSymbol old_alias_symbol = 0;
313  TSSymbol new_alias_symbol = 0;
314  iterator_get_visible_state(old_iter, &old_tree, &old_alias_symbol, &old_start);
315  iterator_get_visible_state(new_iter, &new_tree, &new_alias_symbol, &new_start);
316 
317  if (!old_tree.ptr && !new_tree.ptr) return IteratorMatches;
318  if (!old_tree.ptr || !new_tree.ptr) return IteratorDiffers;
319 
320  if (
321  old_alias_symbol == new_alias_symbol &&
322  ts_subtree_symbol(old_tree) == ts_subtree_symbol(new_tree)
323  ) {
324  if (old_start == new_start &&
325  !ts_subtree_has_changes(old_tree) &&
327  ts_subtree_size(old_tree).bytes == ts_subtree_size(new_tree).bytes &&
330  (ts_subtree_parse_state(old_tree) == ERROR_STATE) ==
331  (ts_subtree_parse_state(new_tree) == ERROR_STATE)) {
332  return IteratorMatches;
333  } else {
334  return IteratorMayDiffer;
335  }
336  }
337 
338  return IteratorDiffers;
339 }
static ut8 bytes[32]
Definition: asm_arc.c:23
#define ERROR_STATE
Definition: error_costs.h:4
static void iterator_get_visible_state(const Iterator *self, Subtree *tree, TSSymbol *alias_symbol, uint32_t *start_byte)
uint16_t TSSymbol
Definition: parser.h:19
#define ts_builtin_sym_error
Definition: parser.h:12
#define TS_TREE_STATE_NONE
Definition: subtree.h:18
static bool ts_subtree_has_changes(Subtree self)
Definition: subtree.h:217
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static TSStateId ts_subtree_parse_state(Subtree self)
Definition: subtree.h:220
#define NULL_SUBTREE
Definition: subtree.h:19
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213
const SubtreeHeapData * ptr
Definition: subtree.h:158

References bytes, ERROR_STATE, iterator_get_visible_state(), IteratorDiffers, IteratorMatches, IteratorMayDiffer, NULL_SUBTREE, Subtree::ptr, ts_builtin_sym_error, ts_subtree_has_changes(), ts_subtree_parse_state(), ts_subtree_size(), ts_subtree_symbol(), and TS_TREE_STATE_NONE.

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_descend()

static bool iterator_descend ( Iterator self,
uint32_t  goal_position 
)
static

Definition at line 210 of file get_changed_ranges.c.

210  {
211  if (self->in_padding) return false;
212 
213  bool did_descend;
214  do {
215  did_descend = false;
216  TreeCursorEntry entry = *array_back(&self->cursor.stack);
217  Length position = entry.position;
218  uint32_t structural_child_index = 0;
219  for (uint32_t i = 0, n = ts_subtree_child_count(*entry.subtree); i < n; i++) {
220  const Subtree *child = &ts_subtree_children(*entry.subtree)[i];
221  Length child_left = length_add(position, ts_subtree_padding(*child));
222  Length child_right = length_add(child_left, ts_subtree_size(*child));
223 
224  if (child_right.bytes > goal_position) {
225  array_push(&self->cursor.stack, ((TreeCursorEntry) {
226  .subtree = child,
227  .position = position,
228  .child_index = i,
229  .structural_child_index = structural_child_index,
230  }));
231 
232  if (iterator_tree_is_visible(self)) {
233  if (child_left.bytes > goal_position) {
234  self->in_padding = true;
235  } else {
236  self->visible_depth++;
237  }
238  return true;
239  }
240 
241  did_descend = true;
242  break;
243  }
244 
245  position = child_right;
246  if (!ts_subtree_extra(*child)) structural_child_index++;
247  }
248  } while (did_descend);
249 
250  return false;
251 }
lzma_index ** i
Definition: index.h:629
int n
Definition: mipsasm.c:19

References array_back, array_push, Length::bytes, i, iterator_tree_is_visible(), length_add(), n, ts_subtree_child_count(), ts_subtree_children, ts_subtree_extra(), ts_subtree_padding(), and ts_subtree_size().

Referenced by iterator_advance(), and ts_subtree_get_changed_ranges().

◆ iterator_done()

static bool iterator_done ( Iterator self)
static

Definition at line 133 of file get_changed_ranges.c.

133  {
134  return self->cursor.stack.size == 0;
135 }

Referenced by iterator_advance(), iterator_ascend(), and ts_subtree_get_changed_ranges().

◆ iterator_end_position()

static Length iterator_end_position ( Iterator self)
static

Definition at line 146 of file get_changed_ranges.c.

146  {
147  TreeCursorEntry entry = *array_back(&self->cursor.stack);
148  Length result = length_add(entry.position, ts_subtree_padding(*entry.subtree));
149  if (self->in_padding) {
150  return result;
151  } else {
152  return length_add(result, ts_subtree_size(*entry.subtree));
153  }
154 }

References array_back, length_add(), ts_subtree_padding(), and ts_subtree_size().

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_get_visible_state()

static void iterator_get_visible_state ( const Iterator self,
Subtree tree,
TSSymbol alias_symbol,
uint32_t start_byte 
)
static

Definition at line 170 of file get_changed_ranges.c.

175  {
176  uint32_t i = self->cursor.stack.size - 1;
177 
178  if (self->in_padding) {
179  if (i == 0) return;
180  i--;
181  }
182 
183  for (; i + 1 > 0; i--) {
184  TreeCursorEntry entry = self->cursor.stack.contents[i];
185 
186  if (i > 0) {
187  const Subtree *parent = self->cursor.stack.contents[i - 1].subtree;
188  *alias_symbol = ts_language_alias_at(
189  self->language,
190  parent->ptr->production_id,
191  entry.structural_child_index
192  );
193  }
194 
195  if (ts_subtree_visible(*entry.subtree) || *alias_symbol) {
196  *tree = *entry.subtree;
197  *start_byte = entry.position.bytes;
198  break;
199  }
200  }
201 }
static TSSymbol ts_language_alias_at(const TSLanguage *self, uint32_t production_id, uint32_t child_index)
Definition: language.h:236
const TSLanguage * language
uint16_t production_id
Definition: subtree.h:140
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214

References i, SubtreeHeapData::production_id, Subtree::ptr, ts_language_alias_at(), and ts_subtree_visible().

Referenced by iterator_compare().

◆ iterator_new()

static Iterator iterator_new ( TreeCursor cursor,
const Subtree tree,
const TSLanguage language 
)
static

Definition at line 113 of file get_changed_ranges.c.

117  {
118  array_clear(&cursor->stack);
119  array_push(&cursor->stack, ((TreeCursorEntry) {
120  .subtree = tree,
121  .position = length_zero(),
122  .child_index = 0,
123  .structural_child_index = 0,
124  }));
125  return (Iterator) {
126  .cursor = *cursor,
127  .language = language,
128  .visible_depth = 1,
129  .in_padding = false,
130  };
131 }
#define array_clear(self)
Definition: array.h:35

References array_clear, and array_push.

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_start_position()

static Length iterator_start_position ( Iterator self)
static

Definition at line 137 of file get_changed_ranges.c.

137  {
138  TreeCursorEntry entry = *array_back(&self->cursor.stack);
139  if (self->in_padding) {
140  return entry.position;
141  } else {
142  return length_add(entry.position, ts_subtree_padding(*entry.subtree));
143  }
144 }

References array_back, length_add(), and ts_subtree_padding().

Referenced by ts_subtree_get_changed_ranges().

◆ iterator_tree_is_visible()

static bool iterator_tree_is_visible ( const Iterator self)
static

Definition at line 156 of file get_changed_ranges.c.

156  {
157  TreeCursorEntry entry = *array_back(&self->cursor.stack);
158  if (ts_subtree_visible(*entry.subtree)) return true;
159  if (self->cursor.stack.size > 1) {
160  Subtree parent = *self->cursor.stack.contents[self->cursor.stack.size - 2].subtree;
161  return ts_language_alias_at(
162  self->language,
163  parent.ptr->production_id,
164  entry.structural_child_index
165  ) != 0;
166  }
167  return false;
168 }

References array_back, SubtreeHeapData::production_id, Subtree::ptr, ts_language_alias_at(), and ts_subtree_visible().

Referenced by iterator_advance(), iterator_ascend(), and iterator_descend().

◆ ts_range_array_add()

static void ts_range_array_add ( TSRangeArray *  self,
Length  start,
Length  end 
)
static

Definition at line 10 of file get_changed_ranges.c.

14  {
15  if (self->size > 0) {
16  TSRange *last_range = array_back(self);
17  if (start.bytes <= last_range->end_byte) {
18  last_range->end_byte = end.bytes;
19  last_range->end_point = end.extent;
20  return;
21  }
22  }
23 
24  if (start.bytes < end.bytes) {
25  TSRange range = { start.extent, end.extent, start.bytes, end.bytes };
26  array_push(self, range);
27  }
28 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
Definition: api.h:60
TSPoint end_point
Definition: api.h:62
uint32_t end_byte
Definition: api.h:64

References array_back, array_push, test_evm::end, TSRange::end_byte, TSRange::end_point, capstone::range, and start.

Referenced by ts_range_array_get_changed_ranges(), and ts_subtree_get_changed_ranges().

◆ ts_range_array_get_changed_ranges()

void ts_range_array_get_changed_ranges ( const TSRange old_ranges,
unsigned  old_range_count,
const TSRange new_ranges,
unsigned  new_range_count,
TSRangeArray *  differences 
)

Definition at line 46 of file get_changed_ranges.c.

50  {
51  unsigned new_index = 0;
52  unsigned old_index = 0;
53  Length current_position = length_zero();
54  bool in_old_range = false;
55  bool in_new_range = false;
56 
57  while (old_index < old_range_count || new_index < new_range_count) {
58  const TSRange *old_range = &old_ranges[old_index];
59  const TSRange *new_range = &new_ranges[new_index];
60 
61  Length next_old_position;
62  if (in_old_range) {
63  next_old_position = (Length) {old_range->end_byte, old_range->end_point};
64  } else if (old_index < old_range_count) {
65  next_old_position = (Length) {old_range->start_byte, old_range->start_point};
66  } else {
67  next_old_position = LENGTH_MAX;
68  }
69 
70  Length next_new_position;
71  if (in_new_range) {
72  next_new_position = (Length) {new_range->end_byte, new_range->end_point};
73  } else if (new_index < new_range_count) {
74  next_new_position = (Length) {new_range->start_byte, new_range->start_point};
75  } else {
76  next_new_position = LENGTH_MAX;
77  }
78 
79  if (next_old_position.bytes < next_new_position.bytes) {
80  if (in_old_range != in_new_range) {
81  ts_range_array_add(differences, current_position, next_old_position);
82  }
83  if (in_old_range) old_index++;
84  current_position = next_old_position;
85  in_old_range = !in_old_range;
86  } else if (next_new_position.bytes < next_old_position.bytes) {
87  if (in_old_range != in_new_range) {
88  ts_range_array_add(differences, current_position, next_new_position);
89  }
90  if (in_new_range) new_index++;
91  current_position = next_new_position;
92  in_new_range = !in_new_range;
93  } else {
94  if (in_old_range != in_new_range) {
95  ts_range_array_add(differences, current_position, next_new_position);
96  }
97  if (in_old_range) old_index++;
98  if (in_new_range) new_index++;
99  in_old_range = !in_old_range;
100  in_new_range = !in_new_range;
101  current_position = next_new_position;
102  }
103  }
104 }
static void ts_range_array_add(TSRangeArray *self, Length start, Length end)
static Length length_zero(void)
Definition: length.h:39
static const Length LENGTH_MAX
Definition: length.h:15
uint32_t start_byte
Definition: api.h:63
TSPoint start_point
Definition: api.h:61

References Length::bytes, TSRange::end_byte, TSRange::end_point, LENGTH_MAX, length_zero(), TSRange::start_byte, TSRange::start_point, and ts_range_array_add().

Referenced by ts_parser_parse(), and ts_tree_get_changed_ranges().

◆ ts_range_array_intersects()

bool ts_range_array_intersects ( const TSRangeArray *  self,
unsigned  start_index,
uint32_t  start_byte,
uint32_t  end_byte 
)

Definition at line 30 of file get_changed_ranges.c.

35  {
36  for (unsigned i = start_index; i < self->size; i++) {
37  TSRange *range = &self->contents[i];
38  if (range->end_byte > start_byte) {
39  if (range->start_byte >= end_byte) break;
40  return true;
41  }
42  }
43  return false;
44 }

References i, and capstone::range.

Referenced by ts_parser__has_included_range_difference(), and ts_subtree_get_changed_ranges().

◆ ts_subtree_get_changed_ranges()

unsigned ts_subtree_get_changed_ranges ( const Subtree old_tree,
const Subtree new_tree,
TreeCursor cursor1,
TreeCursor cursor2,
const TSLanguage language,
const TSRangeArray *  included_range_differences,
TSRange **  ranges 
)

Definition at line 357 of file get_changed_ranges.c.

363  {
364  TSRangeArray results = array_new();
365 
366  Iterator old_iter = iterator_new(cursor1, old_tree, language);
367  Iterator new_iter = iterator_new(cursor2, new_tree, language);
368 
369  unsigned included_range_difference_index = 0;
370 
371  Length position = iterator_start_position(&old_iter);
372  Length next_position = iterator_start_position(&new_iter);
373  if (position.bytes < next_position.bytes) {
374  ts_range_array_add(&results, position, next_position);
375  position = next_position;
376  } else if (position.bytes > next_position.bytes) {
377  ts_range_array_add(&results, next_position, position);
378  next_position = position;
379  }
380 
381  do {
382  #ifdef DEBUG_GET_CHANGED_RANGES
383  printf("At [%-2u, %-2u] Compare ", position.extent.row + 1, position.extent.column);
384  iterator_print_state(&old_iter);
385  printf("\tvs\t");
386  iterator_print_state(&new_iter);
387  puts("");
388  #endif
389 
390  // Compare the old and new subtrees.
391  IteratorComparison comparison = iterator_compare(&old_iter, &new_iter);
392 
393  // Even if the two subtrees appear to be identical, they could differ
394  // internally if they contain a range of text that was previously
395  // excluded from the parse, and is now included, or vice-versa.
396  if (comparison == IteratorMatches && ts_range_array_intersects(
397  included_range_differences,
398  included_range_difference_index,
399  position.bytes,
400  iterator_end_position(&old_iter).bytes
401  )) {
402  comparison = IteratorMayDiffer;
403  }
404 
405  bool is_changed = false;
406  switch (comparison) {
407  // If the subtrees are definitely identical, move to the end
408  // of both subtrees.
409  case IteratorMatches:
410  next_position = iterator_end_position(&old_iter);
411  break;
412 
413  // If the subtrees might differ internally, descend into both
414  // subtrees, finding the first child that spans the current position.
415  case IteratorMayDiffer:
416  if (iterator_descend(&old_iter, position.bytes)) {
417  if (!iterator_descend(&new_iter, position.bytes)) {
418  is_changed = true;
419  next_position = iterator_end_position(&old_iter);
420  }
421  } else if (iterator_descend(&new_iter, position.bytes)) {
422  is_changed = true;
423  next_position = iterator_end_position(&new_iter);
424  } else {
425  next_position = length_min(
426  iterator_end_position(&old_iter),
427  iterator_end_position(&new_iter)
428  );
429  }
430  break;
431 
432  // If the subtrees are different, record a change and then move
433  // to the end of both subtrees.
434  case IteratorDiffers:
435  is_changed = true;
436  next_position = length_min(
437  iterator_end_position(&old_iter),
438  iterator_end_position(&new_iter)
439  );
440  break;
441  }
442 
443  // Ensure that both iterators are caught up to the current position.
444  while (
445  !iterator_done(&old_iter) &&
446  iterator_end_position(&old_iter).bytes <= next_position.bytes
447  ) iterator_advance(&old_iter);
448  while (
449  !iterator_done(&new_iter) &&
450  iterator_end_position(&new_iter).bytes <= next_position.bytes
451  ) iterator_advance(&new_iter);
452 
453  // Ensure that both iterators are at the same depth in the tree.
454  while (old_iter.visible_depth > new_iter.visible_depth) {
455  iterator_ascend(&old_iter);
456  }
457  while (new_iter.visible_depth > old_iter.visible_depth) {
458  iterator_ascend(&new_iter);
459  }
460 
461  if (is_changed) {
462  #ifdef DEBUG_GET_CHANGED_RANGES
463  printf(
464  " change: [[%u, %u] - [%u, %u]]\n",
465  position.extent.row + 1, position.extent.column,
466  next_position.extent.row + 1, next_position.extent.column
467  );
468  #endif
469 
470  ts_range_array_add(&results, position, next_position);
471  }
472 
473  position = next_position;
474 
475  // Keep track of the current position in the included range differences
476  // array in order to avoid scanning the entire array on each iteration.
477  while (included_range_difference_index < included_range_differences->size) {
478  const TSRange *range = &included_range_differences->contents[
479  included_range_difference_index
480  ];
481  if (range->end_byte <= position.bytes) {
482  included_range_difference_index++;
483  } else {
484  break;
485  }
486  }
487  } while (!iterator_done(&old_iter) && !iterator_done(&new_iter));
488 
489  Length old_size = ts_subtree_total_size(*old_tree);
490  Length new_size = ts_subtree_total_size(*new_tree);
491  if (old_size.bytes < new_size.bytes) {
492  ts_range_array_add(&results, old_size, new_size);
493  } else if (new_size.bytes < old_size.bytes) {
494  ts_range_array_add(&results, new_size, old_size);
495  }
496 
497  *cursor1 = old_iter.cursor;
498  *cursor2 = new_iter.cursor;
499  *ranges = results.contents;
500  return results.size;
501 }
#define array_new()
Definition: array.h:25
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
static void iterator_ascend(Iterator *self)
static IteratorComparison iterator_compare(const Iterator *old_iter, const Iterator *new_iter)
static void iterator_advance(Iterator *self)
static Length iterator_end_position(Iterator *self)
static Iterator iterator_new(TreeCursor *cursor, const Subtree *tree, const TSLanguage *language)
static Length iterator_start_position(Iterator *self)
bool ts_range_array_intersects(const TSRangeArray *self, unsigned start_index, uint32_t start_byte, uint32_t end_byte)
voidpf void uLong size
Definition: ioapi.h:138
static Length length_min(Length len1, Length len2)
Definition: length.h:21
unsigned visible_depth
TSPoint extent
Definition: length.h:11
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57

References array_new, bytes, Length::bytes, TSPoint::column, Iterator::cursor, Length::extent, iterator_advance(), iterator_ascend(), iterator_compare(), iterator_descend(), iterator_done(), iterator_end_position(), iterator_new(), iterator_start_position(), IteratorDiffers, IteratorMatches, IteratorMayDiffer, length_min(), printf(), capstone::range, TSPoint::row, ts_range_array_add(), ts_range_array_intersects(), ts_subtree_total_size(), and Iterator::visible_depth.

Referenced by ts_tree_get_changed_ranges().