Rizin
unix-like reverse engineering framework and cli tools
subtree.c
Go to the documentation of this file.
1 #include <assert.h>
2 #include <ctype.h>
3 #include <limits.h>
4 #include <stdbool.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include "./alloc.h"
8 #include "./atomic.h"
9 #include "./subtree.h"
10 #include "./length.h"
11 #include "./language.h"
12 #include "./error_costs.h"
13 #include <stddef.h>
14 
15 typedef struct {
19 } Edit;
20 
21 #define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX
22 #define TS_MAX_TREE_POOL_SIZE 32
23 
24 static const ExternalScannerState empty_state = {{.short_data = {0}}, .length = 0};
25 
26 // ExternalScannerState
27 
28 void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length) {
29  self->length = length;
30  if (length > sizeof(self->short_data)) {
31  self->long_data = ts_malloc(length);
32  memcpy(self->long_data, data, length);
33  } else {
34  memcpy(self->short_data, data, length);
35  }
36 }
37 
39  ExternalScannerState result = *self;
40  if (self->length > sizeof(self->short_data)) {
41  result.long_data = ts_malloc(self->length);
42  memcpy(result.long_data, self->long_data, self->length);
43  }
44  return result;
45 }
46 
48  if (self->length > sizeof(self->short_data)) {
49  ts_free(self->long_data);
50  }
51 }
52 
54  if (self->length > sizeof(self->short_data)) {
55  return self->long_data;
56  } else {
57  return self->short_data;
58  }
59 }
60 
62  return a == b || (
63  a->length == b->length &&
65  );
66 }
67 
68 // SubtreeArray
69 
70 void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest) {
71  dest->size = self.size;
72  dest->capacity = self.capacity;
73  dest->contents = self.contents;
74  if (self.capacity > 0) {
75  dest->contents = ts_calloc(self.capacity, sizeof(Subtree));
76  memcpy(dest->contents, self.contents, self.size * sizeof(Subtree));
77  for (uint32_t i = 0; i < self.size; i++) {
78  ts_subtree_retain(dest->contents[i]);
79  }
80  }
81 }
82 
83 void ts_subtree_array_clear(SubtreePool *pool, SubtreeArray *self) {
84  for (uint32_t i = 0; i < self->size; i++) {
85  ts_subtree_release(pool, self->contents[i]);
86  }
87  array_clear(self);
88 }
89 
90 void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self) {
91  ts_subtree_array_clear(pool, self);
92  array_delete(self);
93 }
94 
96  SubtreeArray *self,
97  SubtreeArray *destination
98 ) {
99  array_clear(destination);
100  while (self->size > 0) {
101  Subtree last = self->contents[self->size - 1];
102  if (ts_subtree_extra(last)) {
103  self->size--;
104  array_push(destination, last);
105  } else {
106  break;
107  }
108  }
109  ts_subtree_array_reverse(destination);
110 }
111 
112 void ts_subtree_array_reverse(SubtreeArray *self) {
113  for (uint32_t i = 0, limit = self->size / 2; i < limit; i++) {
114  size_t reverse_index = self->size - 1 - i;
115  Subtree swap = self->contents[i];
116  self->contents[i] = self->contents[reverse_index];
117  self->contents[reverse_index] = swap;
118  }
119 }
120 
121 // SubtreePool
122 
124  SubtreePool self = {array_new(), array_new()};
125  array_reserve(&self.free_trees, capacity);
126  return self;
127 }
128 
130  if (self->free_trees.contents) {
131  for (unsigned i = 0; i < self->free_trees.size; i++) {
132  ts_free(self->free_trees.contents[i].ptr);
133  }
134  array_delete(&self->free_trees);
135  }
136  if (self->tree_stack.contents) array_delete(&self->tree_stack);
137 }
138 
140  if (self->free_trees.size > 0) {
141  return array_pop(&self->free_trees).ptr;
142  } else {
143  return ts_malloc(sizeof(SubtreeHeapData));
144  }
145 }
146 
148  if (self->free_trees.capacity > 0 && self->free_trees.size + 1 <= TS_MAX_TREE_POOL_SIZE) {
149  array_push(&self->free_trees, (MutableSubtree) {.ptr = tree});
150  } else {
151  ts_free(tree);
152  }
153 }
154 
155 // Subtree
156 
157 static inline bool ts_subtree_can_inline(Length padding, Length size, uint32_t lookahead_bytes) {
158  return
159  padding.bytes < TS_MAX_INLINE_TREE_LENGTH &&
160  padding.extent.row < 16 &&
162  size.extent.row == 0 &&
163  size.extent.column < TS_MAX_INLINE_TREE_LENGTH &&
164  lookahead_bytes < 16;
165 }
166 
168  SubtreePool *pool, TSSymbol symbol, Length padding, Length size,
169  uint32_t lookahead_bytes, TSStateId parse_state,
170  bool has_external_tokens, bool depends_on_column,
171  bool is_keyword, const TSLanguage *language
172 ) {
173  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
174  bool extra = symbol == ts_builtin_sym_end;
175 
176  bool is_inline = (
177  symbol <= UINT8_MAX &&
178  !has_external_tokens &&
179  ts_subtree_can_inline(padding, size, lookahead_bytes)
180  );
181 
182  if (is_inline) {
183  return (Subtree) {{
184  .parse_state = parse_state,
185  .symbol = symbol,
186  .padding_bytes = padding.bytes,
187  .padding_rows = padding.extent.row,
188  .padding_columns = padding.extent.column,
189  .size_bytes = size.bytes,
190  .lookahead_bytes = lookahead_bytes,
191  .visible = metadata.visible,
192  .named = metadata.named,
193  .extra = extra,
194  .has_changes = false,
195  .is_missing = false,
196  .is_keyword = is_keyword,
197  .is_inline = true,
198  }};
199  } else {
201  *data = (SubtreeHeapData) {
202  .ref_count = 1,
203  .padding = padding,
204  .size = size,
205  .lookahead_bytes = lookahead_bytes,
206  .error_cost = 0,
207  .child_count = 0,
208  .symbol = symbol,
209  .parse_state = parse_state,
210  .visible = metadata.visible,
211  .named = metadata.named,
212  .extra = extra,
213  .fragile_left = false,
214  .fragile_right = false,
215  .has_changes = false,
216  .has_external_tokens = has_external_tokens,
217  .depends_on_column = depends_on_column,
218  .is_missing = false,
219  .is_keyword = is_keyword,
220  {{.first_leaf = {.symbol = 0, .parse_state = 0}}}
221  };
222  return (Subtree) {.ptr = data};
223  }
224 }
225 
227  MutableSubtree *self,
228  TSSymbol symbol,
229  const TSLanguage *language
230 ) {
231  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
232  if (self->data.is_inline) {
233  assert(symbol < UINT8_MAX);
234  self->data.symbol = symbol;
235  self->data.named = metadata.named;
236  self->data.visible = metadata.visible;
237  } else {
238  self->ptr->symbol = symbol;
239  self->ptr->named = metadata.named;
240  self->ptr->visible = metadata.visible;
241  }
242 }
243 
245  SubtreePool *pool, int32_t lookahead_char, Length padding, Length size,
246  uint32_t bytes_scanned, TSStateId parse_state, const TSLanguage *language
247 ) {
248  Subtree result = ts_subtree_new_leaf(
249  pool, ts_builtin_sym_error, padding, size, bytes_scanned,
250  parse_state, false, false, false, language
251  );
252  SubtreeHeapData *data = (SubtreeHeapData *)result.ptr;
253  data->fragile_left = true;
254  data->fragile_right = true;
255  data->lookahead_char = lookahead_char;
256  return result;
257 }
258 
259 // Clone a subtree.
261  size_t alloc_size = ts_subtree_alloc_size(self.ptr->child_count);
262  Subtree *new_children = ts_malloc(alloc_size);
263  Subtree *old_children = ts_subtree_children(self);
264  memcpy(new_children, old_children, alloc_size);
265  SubtreeHeapData *result = (SubtreeHeapData *)&new_children[self.ptr->child_count];
266  if (self.ptr->child_count > 0) {
267  for (uint32_t i = 0; i < self.ptr->child_count; i++) {
268  ts_subtree_retain(new_children[i]);
269  }
270  } else if (self.ptr->has_external_tokens) {
272  &self.ptr->external_scanner_state
273  );
274  }
275  result->ref_count = 1;
276  return (MutableSubtree) {.ptr = result};
277 }
278 
279 // Get mutable version of a subtree.
280 //
281 // This takes ownership of the subtree. If the subtree has only one owner,
282 // this will directly convert it into a mutable version. Otherwise, it will
283 // perform a copy.
285  if (self.data.is_inline) return (MutableSubtree) {self.data};
286  if (self.ptr->ref_count == 1) return ts_subtree_to_mut_unsafe(self);
287  MutableSubtree result = ts_subtree_clone(self);
288  ts_subtree_release(pool, self);
289  return result;
290 }
291 
293  MutableSubtree self,
294  unsigned count,
295  const TSLanguage *language,
296  MutableSubtreeArray *stack
297 ) {
298  unsigned initial_stack_size = stack->size;
299 
300  MutableSubtree tree = self;
301  TSSymbol symbol = tree.ptr->symbol;
302  for (unsigned i = 0; i < count; i++) {
303  if (tree.ptr->ref_count > 1 || tree.ptr->child_count < 2) break;
304 
306  if (
307  child.data.is_inline ||
308  child.ptr->child_count < 2 ||
309  child.ptr->ref_count > 1 ||
310  child.ptr->symbol != symbol
311  ) break;
312 
314  if (
315  grandchild.data.is_inline ||
316  grandchild.ptr->child_count < 2 ||
317  grandchild.ptr->ref_count > 1 ||
318  grandchild.ptr->symbol != symbol
319  ) break;
320 
321  ts_subtree_children(tree)[0] = ts_subtree_from_mut(grandchild);
322  ts_subtree_children(child)[0] = ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1];
323  ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1] = ts_subtree_from_mut(child);
324  array_push(stack, tree);
325  tree = grandchild;
326  }
327 
328  while (stack->size > initial_stack_size) {
329  tree = array_pop(stack);
332  ts_subtree_summarize_children(grandchild, language);
333  ts_subtree_summarize_children(child, language);
334  ts_subtree_summarize_children(tree, language);
335  }
336 }
337 
338 void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *language) {
339  array_clear(&pool->tree_stack);
340 
341  if (ts_subtree_child_count(self) > 0 && self.ptr->ref_count == 1) {
343  }
344 
345  while (pool->tree_stack.size > 0) {
346  MutableSubtree tree = array_pop(&pool->tree_stack);
347 
348  if (tree.ptr->repeat_depth > 0) {
349  Subtree child1 = ts_subtree_children(tree)[0];
350  Subtree child2 = ts_subtree_children(tree)[tree.ptr->child_count - 1];
351  long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
352  if (repeat_delta > 0) {
353  unsigned n = repeat_delta;
354  for (unsigned i = n / 2; i > 0; i /= 2) {
355  ts_subtree__compress(tree, i, language, &pool->tree_stack);
356  n -= i;
357  }
358  }
359  }
360 
361  for (uint32_t i = 0; i < tree.ptr->child_count; i++) {
362  Subtree child = ts_subtree_children(tree)[i];
363  if (ts_subtree_child_count(child) > 0 && child.ptr->ref_count == 1) {
365  }
366  }
367  }
368 }
369 
370 // Assign all of the node's properties that depend on its children.
372  MutableSubtree self,
373  const TSLanguage *language
374 ) {
375  assert(!self.data.is_inline);
376 
377  self.ptr->named_child_count = 0;
378  self.ptr->visible_child_count = 0;
379  self.ptr->error_cost = 0;
380  self.ptr->repeat_depth = 0;
381  self.ptr->node_count = 1;
382  self.ptr->has_external_tokens = false;
383  self.ptr->depends_on_column = false;
384  self.ptr->dynamic_precedence = 0;
385 
386  uint32_t structural_index = 0;
387  const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);
388  uint32_t lookahead_end_byte = 0;
389 
390  const Subtree *children = ts_subtree_children(self);
391  for (uint32_t i = 0; i < self.ptr->child_count; i++) {
392  Subtree child = children[i];
393 
394  if (
395  self.ptr->size.extent.row == 0 &&
397  ) {
398  self.ptr->depends_on_column = true;
399  }
400 
401  if (i == 0) {
402  self.ptr->padding = ts_subtree_padding(child);
403  self.ptr->size = ts_subtree_size(child);
404  } else {
405  self.ptr->size = length_add(self.ptr->size, ts_subtree_total_size(child));
406  }
407 
408  uint32_t child_lookahead_end_byte =
409  self.ptr->padding.bytes +
410  self.ptr->size.bytes +
412  if (child_lookahead_end_byte > lookahead_end_byte) {
413  lookahead_end_byte = child_lookahead_end_byte;
414  }
415 
417  self.ptr->error_cost += ts_subtree_error_cost(child);
418  }
419 
420  uint32_t grandchild_count = ts_subtree_child_count(child);
421  if (
422  self.ptr->symbol == ts_builtin_sym_error ||
423  self.ptr->symbol == ts_builtin_sym_error_repeat
424  ) {
425  if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
426  if (ts_subtree_visible(child)) {
427  self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
428  } else if (grandchild_count > 0) {
429  self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
430  }
431  }
432  }
433 
434  self.ptr->dynamic_precedence += ts_subtree_dynamic_precedence(child);
435  self.ptr->node_count += ts_subtree_node_count(child);
436 
437  if (alias_sequence && alias_sequence[structural_index] != 0 && !ts_subtree_extra(child)) {
438  self.ptr->visible_child_count++;
439  if (ts_language_symbol_metadata(language, alias_sequence[structural_index]).named) {
440  self.ptr->named_child_count++;
441  }
442  } else if (ts_subtree_visible(child)) {
443  self.ptr->visible_child_count++;
444  if (ts_subtree_named(child)) self.ptr->named_child_count++;
445  } else if (grandchild_count > 0) {
446  self.ptr->visible_child_count += child.ptr->visible_child_count;
447  self.ptr->named_child_count += child.ptr->named_child_count;
448  }
449 
450  if (ts_subtree_has_external_tokens(child)) self.ptr->has_external_tokens = true;
451 
452  if (ts_subtree_is_error(child)) {
453  self.ptr->fragile_left = self.ptr->fragile_right = true;
454  self.ptr->parse_state = TS_TREE_STATE_NONE;
455  }
456 
457  if (!ts_subtree_extra(child)) structural_index++;
458  }
459 
460  self.ptr->lookahead_bytes = lookahead_end_byte - self.ptr->size.bytes - self.ptr->padding.bytes;
461 
462  if (
463  self.ptr->symbol == ts_builtin_sym_error ||
464  self.ptr->symbol == ts_builtin_sym_error_repeat
465  ) {
466  self.ptr->error_cost +=
468  ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
469  ERROR_COST_PER_SKIPPED_LINE * self.ptr->size.extent.row;
470  }
471 
472  if (self.ptr->child_count > 0) {
473  Subtree first_child = children[0];
474  Subtree last_child = children[self.ptr->child_count - 1];
475 
476  self.ptr->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
477  self.ptr->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
478 
479  if (ts_subtree_fragile_left(first_child)) self.ptr->fragile_left = true;
480  if (ts_subtree_fragile_right(last_child)) self.ptr->fragile_right = true;
481 
482  if (
483  self.ptr->child_count >= 2 &&
484  !self.ptr->visible &&
485  !self.ptr->named &&
486  ts_subtree_symbol(first_child) == self.ptr->symbol
487  ) {
488  if (ts_subtree_repeat_depth(first_child) > ts_subtree_repeat_depth(last_child)) {
489  self.ptr->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;
490  } else {
491  self.ptr->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;
492  }
493  }
494  }
495 }
496 
497 // Create a new parent node with the given children.
498 //
499 // This takes ownership of the children array.
501  TSSymbol symbol,
502  SubtreeArray *children,
503  unsigned production_id,
504  const TSLanguage *language
505 ) {
506  TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
507  bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
508 
509  // Allocate the node's data at the end of the array of children.
510  size_t new_byte_size = ts_subtree_alloc_size(children->size);
511  if (children->capacity * sizeof(Subtree) < new_byte_size) {
512  children->contents = ts_realloc(children->contents, new_byte_size);
513  children->capacity = new_byte_size / sizeof(Subtree);
514  }
515  SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];
516 
517  *data = (SubtreeHeapData) {
518  .ref_count = 1,
519  .symbol = symbol,
520  .child_count = children->size,
521  .visible = metadata.visible,
522  .named = metadata.named,
523  .has_changes = false,
524  .fragile_left = fragile,
525  .fragile_right = fragile,
526  .is_keyword = false,
527  {{
528  .node_count = 0,
529  .production_id = production_id,
530  .first_leaf = {.symbol = 0, .parse_state = 0},
531  }}
532  };
533  MutableSubtree result = {.ptr = data};
534  ts_subtree_summarize_children(result, language);
535  return result;
536 }
537 
538 // Create a new error node contaning the given children.
539 //
540 // This node is treated as 'extra'. Its children are prevented from having
541 // having any effect on the parse state.
543  SubtreeArray *children,
544  bool extra,
545  const TSLanguage *language
546 ) {
548  ts_builtin_sym_error, children, 0, language
549  );
550  result.ptr->extra = extra;
551  return ts_subtree_from_mut(result);
552 }
553 
554 // Create a new 'missing leaf' node.
555 //
556 // This node is treated as 'extra'. Its children are prevented from having
557 // having any effect on the parse state.
559  SubtreePool *pool,
560  TSSymbol symbol,
561  Length padding,
562  uint32_t lookahead_bytes,
563  const TSLanguage *language
564 ) {
565  Subtree result = ts_subtree_new_leaf(
566  pool, symbol, padding, length_zero(), lookahead_bytes,
567  0, false, false, false, language
568  );
569  if (result.data.is_inline) {
570  result.data.is_missing = true;
571  } else {
572  ((SubtreeHeapData *)result.ptr)->is_missing = true;
573  }
574  return result;
575 }
576 
578  if (self.data.is_inline) return;
579  assert(self.ptr->ref_count > 0);
580  atomic_inc((volatile uint32_t *)&self.ptr->ref_count);
581  assert(self.ptr->ref_count != 0);
582 }
583 
585  if (self.data.is_inline) return;
586  array_clear(&pool->tree_stack);
587 
588  assert(self.ptr->ref_count > 0);
589  if (atomic_dec((volatile uint32_t *)&self.ptr->ref_count) == 0) {
591  }
592 
593  while (pool->tree_stack.size > 0) {
594  MutableSubtree tree = array_pop(&pool->tree_stack);
595  if (tree.ptr->child_count > 0) {
596  Subtree *children = ts_subtree_children(tree);
597  for (uint32_t i = 0; i < tree.ptr->child_count; i++) {
598  Subtree child = children[i];
599  if (child.data.is_inline) continue;
600  assert(child.ptr->ref_count > 0);
601  if (atomic_dec((volatile uint32_t *)&child.ptr->ref_count) == 0) {
603  }
604  }
605  ts_free(children);
606  } else {
607  if (tree.ptr->has_external_tokens) {
609  }
610  ts_subtree_pool_free(pool, tree.ptr);
611  }
612  }
613 }
614 
616  if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) return -1;
617  if (ts_subtree_symbol(right) < ts_subtree_symbol(left)) return 1;
618  if (ts_subtree_child_count(left) < ts_subtree_child_count(right)) return -1;
619  if (ts_subtree_child_count(right) < ts_subtree_child_count(left)) return 1;
620  for (uint32_t i = 0, n = ts_subtree_child_count(left); i < n; i++) {
621  Subtree left_child = ts_subtree_children(left)[i];
622  Subtree right_child = ts_subtree_children(right)[i];
623  switch (ts_subtree_compare(left_child, right_child)) {
624  case -1: return -1;
625  case 1: return 1;
626  default: break;
627  }
628  }
629  return 0;
630 }
631 
632 static inline void ts_subtree_set_has_changes(MutableSubtree *self) {
633  if (self->data.is_inline) {
634  self->data.has_changes = true;
635  } else {
636  self->ptr->has_changes = true;
637  }
638 }
639 
641  typedef struct {
642  Subtree *tree;
643  Edit edit;
644  } StackEntry;
645 
648  .tree = &self,
649  .edit = (Edit) {
650  .start = {edit->start_byte, edit->start_point},
651  .old_end = {edit->old_end_byte, edit->old_end_point},
652  .new_end = {edit->new_end_byte, edit->new_end_point},
653  },
654  }));
655 
656  while (stack.size) {
658  Edit edit = entry.edit;
659  bool is_noop = edit.old_end.bytes == edit.start.bytes && edit.new_end.bytes == edit.start.bytes;
660  bool is_pure_insertion = edit.old_end.bytes == edit.start.bytes;
661  bool invalidate_first_row = ts_subtree_depends_on_column(*entry.tree);
662 
663  Length size = ts_subtree_size(*entry.tree);
664  Length padding = ts_subtree_padding(*entry.tree);
665  uint32_t lookahead_bytes = ts_subtree_lookahead_bytes(*entry.tree);
666  uint32_t end_byte = padding.bytes + size.bytes + lookahead_bytes;
667  if (edit.start.bytes > end_byte || (is_noop && edit.start.bytes == end_byte)) continue;
668 
669  // If the edit is entirely within the space before this subtree, then shift this
670  // subtree over according to the edit without changing its size.
671  if (edit.old_end.bytes <= padding.bytes) {
672  padding = length_add(edit.new_end, length_sub(padding, edit.old_end));
673  }
674 
675  // If the edit starts in the space before this subtree and extends into this subtree,
676  // shrink the subtree's content to compensate for the change in the space before it.
677  else if (edit.start.bytes < padding.bytes) {
678  size = length_sub(size, length_sub(edit.old_end, padding));
679  padding = edit.new_end;
680  }
681 
682  // If the edit is a pure insertion right at the start of the subtree,
683  // shift the subtree over according to the insertion.
684  else if (edit.start.bytes == padding.bytes && is_pure_insertion) {
685  padding = edit.new_end;
686  }
687 
688  // If the edit is within this subtree, resize the subtree to reflect the edit.
689  else {
690  uint32_t total_bytes = padding.bytes + size.bytes;
691  if (edit.start.bytes < total_bytes ||
692  (edit.start.bytes == total_bytes && is_pure_insertion)) {
693  size = length_add(
694  length_sub(edit.new_end, padding),
695  length_sub(size, length_sub(edit.old_end, padding))
696  );
697  }
698  }
699 
700  MutableSubtree result = ts_subtree_make_mut(pool, *entry.tree);
701 
702  if (result.data.is_inline) {
703  if (ts_subtree_can_inline(padding, size, lookahead_bytes)) {
704  result.data.padding_bytes = padding.bytes;
705  result.data.padding_rows = padding.extent.row;
706  result.data.padding_columns = padding.extent.column;
707  result.data.size_bytes = size.bytes;
708  } else {
710  data->ref_count = 1;
711  data->padding = padding;
712  data->size = size;
713  data->lookahead_bytes = lookahead_bytes;
714  data->error_cost = 0;
715  data->child_count = 0;
716  data->symbol = result.data.symbol;
717  data->parse_state = result.data.parse_state;
718  data->visible = result.data.visible;
719  data->named = result.data.named;
720  data->extra = result.data.extra;
721  data->fragile_left = false;
722  data->fragile_right = false;
723  data->has_changes = false;
724  data->has_external_tokens = false;
725  data->depends_on_column = false;
726  data->is_missing = result.data.is_missing;
727  data->is_keyword = result.data.is_keyword;
728  result.ptr = data;
729  }
730  } else {
731  result.ptr->padding = padding;
732  result.ptr->size = size;
733  }
734 
736  *entry.tree = ts_subtree_from_mut(result);
737 
738  Length child_left, child_right = length_zero();
739  for (uint32_t i = 0, n = ts_subtree_child_count(*entry.tree); i < n; i++) {
740  Subtree *child = &ts_subtree_children(*entry.tree)[i];
741  Length child_size = ts_subtree_total_size(*child);
742  child_left = child_right;
743  child_right = length_add(child_left, child_size);
744 
745  // If this child ends before the edit, it is not affected.
746  if (child_right.bytes + ts_subtree_lookahead_bytes(*child) < edit.start.bytes) continue;
747 
748  // Keep editing child nodes until a node is reached that starts after the edit.
749  // Also, if this node's validity depends on its column position, then continue
750  // invaliditing child nodes until reaching a line break.
751  if ((
752  (child_left.bytes > edit.old_end.bytes) ||
753  (child_left.bytes == edit.old_end.bytes && child_size.bytes > 0 && i > 0)
754  ) && (
755  !invalidate_first_row ||
756  child_left.extent.row > entry.tree->ptr->padding.extent.row
757  )) {
758  break;
759  }
760 
761  // Transform edit into the child's coordinate space.
762  Edit child_edit = {
763  .start = length_sub(edit.start, child_left),
764  .old_end = length_sub(edit.old_end, child_left),
765  .new_end = length_sub(edit.new_end, child_left),
766  };
767 
768  // Clamp child_edit to the child's bounds.
769  if (edit.start.bytes < child_left.bytes) child_edit.start = length_zero();
770  if (edit.old_end.bytes < child_left.bytes) child_edit.old_end = length_zero();
771  if (edit.new_end.bytes < child_left.bytes) child_edit.new_end = length_zero();
772  if (edit.old_end.bytes > child_right.bytes) child_edit.old_end = child_size;
773 
774  // Interpret all inserted text as applying to the *first* child that touches the edit.
775  // Subsequent children are only never have any text inserted into them; they are only
776  // shrunk to compensate for the edit.
777  if (
778  child_right.bytes > edit.start.bytes ||
779  (child_right.bytes == edit.start.bytes && is_pure_insertion)
780  ) {
781  edit.new_end = edit.start;
782  }
783 
784  // Children that occur before the edit are not reshaped by the edit.
785  else {
786  child_edit.old_end = child_edit.start;
787  child_edit.new_end = child_edit.start;
788  }
789 
790  // Queue processing of this child's subtree.
792  .tree = child,
793  .edit = child_edit,
794  }));
795  }
796  }
797 
799  return self;
800 }
801 
803  if (!ts_subtree_has_external_tokens(tree)) return NULL_SUBTREE;
804  while (tree.ptr->child_count > 0) {
805  for (uint32_t i = tree.ptr->child_count - 1; i + 1 > 0; i--) {
806  Subtree child = ts_subtree_children(tree)[i];
807  if (ts_subtree_has_external_tokens(child)) {
808  tree = child;
809  break;
810  }
811  }
812  }
813  return tree;
814 }
815 
816 static size_t ts_subtree__write_char_to_string(char *s, size_t n, int32_t c) {
817  if (c == -1)
818  return snprintf(s, n, "INVALID");
819  else if (c == '\0')
820  return snprintf(s, n, "'\\0'");
821  else if (c == '\n')
822  return snprintf(s, n, "'\\n'");
823  else if (c == '\t')
824  return snprintf(s, n, "'\\t'");
825  else if (c == '\r')
826  return snprintf(s, n, "'\\r'");
827  else if (0 < c && c < 128 && isprint(c))
828  return snprintf(s, n, "'%c'", c);
829  else
830  return snprintf(s, n, "%d", c);
831 }
832 
833 static void ts_subtree__write_dot_string(FILE *f, const char *string) {
834  for (const char *c = string; *c; c++) {
835  if (*c == '"') {
836  fputs("\\\"", f);
837  } else if (*c == '\n') {
838  fputs("\\n", f);
839  } else {
840  fputc(*c, f);
841  }
842  }
843 }
844 
845 static const char *ROOT_FIELD = "__ROOT__";
846 
848  Subtree self, char *string, size_t limit,
849  const TSLanguage *language, bool include_all,
850  TSSymbol alias_symbol, bool alias_is_named, const char *field_name
851 ) {
852  if (!self.ptr) return snprintf(string, limit, "(NULL)");
853 
854  char *cursor = string;
855  char **writer = (limit > 1) ? &cursor : &string;
856  bool is_root = field_name == ROOT_FIELD;
857  bool is_visible =
858  include_all ||
859  ts_subtree_missing(self) ||
860  (
861  alias_symbol
862  ? alias_is_named
863  : ts_subtree_visible(self) && ts_subtree_named(self)
864  );
865 
866  if (is_visible) {
867  if (!is_root) {
868  cursor += snprintf(*writer, limit, " ");
869  if (field_name) {
870  cursor += snprintf(*writer, limit, "%s: ", field_name);
871  }
872  }
873 
874  if (ts_subtree_is_error(self) && ts_subtree_child_count(self) == 0 && self.ptr->size.bytes > 0) {
875  cursor += snprintf(*writer, limit, "(UNEXPECTED ");
876  cursor += ts_subtree__write_char_to_string(*writer, limit, self.ptr->lookahead_char);
877  } else {
878  TSSymbol symbol = alias_symbol ? alias_symbol : ts_subtree_symbol(self);
879  const char *symbol_name = ts_language_symbol_name(language, symbol);
880  if (ts_subtree_missing(self)) {
881  cursor += snprintf(*writer, limit, "(MISSING ");
882  if (alias_is_named || ts_subtree_named(self)) {
883  cursor += snprintf(*writer, limit, "%s", symbol_name);
884  } else {
885  cursor += snprintf(*writer, limit, "\"%s\"", symbol_name);
886  }
887  } else {
888  cursor += snprintf(*writer, limit, "(%s", symbol_name);
889  }
890  }
891  } else if (is_root) {
892  TSSymbol symbol = ts_subtree_symbol(self);
893  const char *symbol_name = ts_language_symbol_name(language, symbol);
894  cursor += snprintf(*writer, limit, "(\"%s\")", symbol_name);
895  }
896 
897  if (ts_subtree_child_count(self)) {
898  const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);
899  const TSFieldMapEntry *field_map, *field_map_end;
901  language,
902  self.ptr->production_id,
903  &field_map,
904  &field_map_end
905  );
906 
907  uint32_t structural_child_index = 0;
908  for (uint32_t i = 0; i < self.ptr->child_count; i++) {
909  Subtree child = ts_subtree_children(self)[i];
910  if (ts_subtree_extra(child)) {
911  cursor += ts_subtree__write_to_string(
912  child, *writer, limit,
913  language, include_all,
914  0, false, NULL
915  );
916  } else {
917  TSSymbol alias_symbol = alias_sequence
918  ? alias_sequence[structural_child_index]
919  : 0;
920  bool alias_is_named = alias_symbol
921  ? ts_language_symbol_metadata(language, alias_symbol).named
922  : false;
923 
924  const char *child_field_name = is_visible ? NULL : field_name;
925  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
926  if (!i->inherited && i->child_index == structural_child_index) {
927  child_field_name = language->field_names[i->field_id];
928  break;
929  }
930  }
931 
932  cursor += ts_subtree__write_to_string(
933  child, *writer, limit,
934  language, include_all,
935  alias_symbol, alias_is_named, child_field_name
936  );
937  structural_child_index++;
938  }
939  }
940  }
941 
942  if (is_visible) cursor += snprintf(*writer, limit, ")");
943 
944  return cursor - string;
945 }
946 
948  Subtree self,
949  const TSLanguage *language,
950  bool include_all
951 ) {
952  char scratch_string[1];
954  self, scratch_string, 1,
955  language, include_all,
956  0, false, ROOT_FIELD
957  ) + 1;
958  char *result = ts_malloc(size * sizeof(char));
960  self, result, size,
961  language, include_all,
962  0, false, ROOT_FIELD
963  );
964  return result;
965 }
966 
967 void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,
968  const TSLanguage *language, TSSymbol alias_symbol,
969  FILE *f) {
971  TSSymbol symbol = alias_symbol ? alias_symbol : subtree_symbol;
972  uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);
973  fprintf(f, "tree_%p [label=\"", (void *)self);
975  fprintf(f, "\"");
976 
977  if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");
978  if (ts_subtree_extra(*self)) fprintf(f, ", fontcolor=gray");
979 
980  fprintf(f, ", tooltip=\""
981  "range: %u - %u\n"
982  "state: %d\n"
983  "error-cost: %u\n"
984  "has-changes: %u\n"
985  "depends-on-column: %u\n"
986  "repeat-depth: %u\n"
987  "lookahead-bytes: %u",
988  start_offset, end_offset,
989  ts_subtree_parse_state(*self),
990  ts_subtree_error_cost(*self),
991  ts_subtree_has_changes(*self),
995  );
996 
997  if (ts_subtree_is_error(*self) && ts_subtree_child_count(*self) == 0) {
998  fprintf(f, "\ncharacter: '%c'", self->ptr->lookahead_char);
999  }
1000 
1001  fprintf(f, "\"]\n");
1002 
1003  uint32_t child_start_offset = start_offset;
1004  uint32_t child_info_offset =
1005  language->max_alias_sequence_length *
1006  ts_subtree_production_id(*self);
1007  for (uint32_t i = 0, n = ts_subtree_child_count(*self); i < n; i++) {
1008  const Subtree *child = &ts_subtree_children(*self)[i];
1009  TSSymbol alias_symbol = 0;
1010  if (!ts_subtree_extra(*child) && child_info_offset) {
1011  alias_symbol = language->alias_sequences[child_info_offset];
1012  child_info_offset++;
1013  }
1014  ts_subtree__print_dot_graph(child, child_start_offset, language, alias_symbol, f);
1015  fprintf(f, "tree_%p -> tree_%p [tooltip=%u]\n", (void *)self, (void *)child, i);
1016  child_start_offset += ts_subtree_total_bytes(*child);
1017  }
1018 }
1019 
1020 void ts_subtree_print_dot_graph(Subtree self, const TSLanguage *language, FILE *f) {
1021  fprintf(f, "digraph tree {\n");
1022  fprintf(f, "edge [arrowhead=none]\n");
1023  ts_subtree__print_dot_graph(&self, 0, language, 0, f);
1024  fprintf(f, "}\n");
1025 }
1026 
1028  const ExternalScannerState *state1 = &empty_state;
1029  const ExternalScannerState *state2 = &empty_state;
1030  if (self.ptr && ts_subtree_has_external_tokens(self) && !self.ptr->child_count) {
1031  state1 = &self.ptr->external_scanner_state;
1032  }
1033  if (other.ptr && ts_subtree_has_external_tokens(other) && !other.ptr->child_count) {
1034  state2 = &other.ptr->external_scanner_state;
1035  }
1036  return ts_external_scanner_state_eq(state1, state2);
1037 }
#define ts_realloc
Definition: alloc.h:27
#define ts_malloc
Definition: alloc.h:21
#define ts_free
Definition: alloc.h:30
#define ts_calloc
Definition: alloc.h:24
lzma_index ** i
Definition: index.h:629
const char * ts_language_symbol_name(const TSLanguage *, TSSymbol)
Definition: language.c:59
#define array_new()
Definition: array.h:25
#define Array(T)
Definition: array.h:15
#define array_push(self, element)
Definition: array.h:43
#define array_pop(self)
Definition: array.h:82
#define array_reserve(self, new_capacity)
Definition: array.h:37
#define array_delete(self)
Definition: array.h:41
#define array_clear(self)
Definition: array.h:35
#define NULL
Definition: cris-opc.c:27
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 count
Definition: sflib.h:98
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 long
Definition: sflib.h:79
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 length
Definition: sflib.h:133
#define ERROR_COST_PER_SKIPPED_TREE
Definition: error_costs.h:7
#define ERROR_COST_PER_SKIPPED_LINE
Definition: error_costs.h:8
#define ERROR_COST_PER_RECOVERY
Definition: error_costs.h:5
#define ERROR_COST_PER_SKIPPED_CHAR
Definition: error_costs.h:9
voidpf void uLong size
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
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
#define ts_builtin_sym_error_repeat
Definition: language.h:11
static const TSSymbol * ts_language_alias_sequence(const TSLanguage *self, uint32_t production_id)
Definition: language.h:227
static Length length_zero(void)
Definition: length.h:39
static Length length_add(Length len1, Length len2)
Definition: length.h:25
static Length length_sub(Length len1, Length len2)
Definition: length.h:32
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
char * dest
Definition: lz4.h:697
assert(limit<=UINT32_MAX/2)
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
int n
Definition: mipsasm.c:19
string FILE
Definition: benchmark.py:21
#define swap(a, b)
Definition: qsort.h:111
@ field_name
Definition: parser.c:1737
uint16_t TSStateId
Definition: parser.h:16
#define ts_builtin_sym_end
Definition: parser.h:13
uint16_t TSSymbol
Definition: parser.h:19
#define ts_builtin_sym_error
Definition: parser.h:12
static RzSocket * s
Definition: rtr.c:28
#define isprint(c)
Definition: safe-ctype.h:137
int int32_t
Definition: sftypes.h:33
unsigned int uint32_t
Definition: sftypes.h:29
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
#define UINT8_MAX
Definition: subtree.c:15
Length new_end
Definition: subtree.c:18
Length old_end
Definition: subtree.c:17
Length start
Definition: subtree.c:16
char short_data[24]
Definition: subtree.h:34
Definition: length.h:9
uint32_t bytes
Definition: length.h:10
TSPoint extent
Definition: length.h:11
uint32_t visible_child_count
Definition: subtree.h:135
uint32_t named_child_count
Definition: subtree.h:136
TSSymbol symbol
Definition: subtree.h:118
uint32_t repeat_depth
Definition: subtree.h:138
bool depends_on_column
Definition: subtree.h:128
bool fragile_right
Definition: subtree.h:125
bool fragile_left
Definition: subtree.h:124
bool is_keyword
Definition: subtree.h:130
bool has_changes
Definition: subtree.h:126
int32_t lookahead_char
Definition: subtree.h:151
volatile uint32_t ref_count
Definition: subtree.h:112
Length size
Definition: subtree.h:114
uint32_t lookahead_bytes
Definition: subtree.h:115
bool is_missing
Definition: subtree.h:129
TSStateId parse_state
Definition: subtree.h:119
ExternalScannerState external_scanner_state
Definition: subtree.h:148
Length padding
Definition: subtree.h:113
uint32_t child_count
Definition: subtree.h:117
bool has_external_tokens
Definition: subtree.h:127
uint32_t error_cost
Definition: subtree.h:116
struct SubtreeHeapData::@621::@623::@625 first_leaf
uint16_t parse_state
Definition: subtree.h:97
SUBTREE_BITS uint8_t symbol
Definition: subtree.h:96
MutableSubtreeArray tree_stack
Definition: subtree.h:172
uint32_t old_end_byte
Definition: api.h:85
uint32_t start_byte
Definition: api.h:84
uint32_t new_end_byte
Definition: api.h:86
TSPoint old_end_point
Definition: api.h:88
TSPoint start_point
Definition: api.h:87
TSPoint new_end_point
Definition: api.h:89
const char *const * field_names
Definition: parser.h:106
const TSSymbol * alias_sequences
Definition: parser.h:112
uint16_t max_alias_sequence_length
Definition: parser.h:100
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57
bool visible
Definition: parser.h:36
Definition: zipcmp.c:77
Definition: z80asm.h:140
void writer(void *n)
Definition: main.c:22
static void ts_subtree_set_has_changes(MutableSubtree *self)
Definition: subtree.c:632
void ts_subtree_array_reverse(SubtreeArray *self)
Definition: subtree.c:112
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other)
Definition: subtree.c:1027
Subtree ts_subtree_edit(Subtree self, const TSInputEdit *edit, SubtreePool *pool)
Definition: subtree.c:640
static void ts_subtree_pool_free(SubtreePool *self, SubtreeHeapData *tree)
Definition: subtree.c:147
MutableSubtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, unsigned production_id, const TSLanguage *language)
Definition: subtree.c:500
static const ExternalScannerState empty_state
Definition: subtree.c:24
void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *language)
Definition: subtree.c:371
static void ts_subtree__compress(MutableSubtree self, unsigned count, const TSLanguage *language, MutableSubtreeArray *stack)
Definition: subtree.c:292
void ts_subtree_release(SubtreePool *pool, Subtree self)
Definition: subtree.c:584
Subtree ts_subtree_new_leaf(SubtreePool *pool, TSSymbol symbol, Length padding, Length size, uint32_t lookahead_bytes, TSStateId parse_state, bool has_external_tokens, bool depends_on_column, bool is_keyword, const TSLanguage *language)
Definition: subtree.c:167
void ts_subtree_print_dot_graph(Subtree self, const TSLanguage *language, FILE *f)
Definition: subtree.c:1020
static SubtreeHeapData * ts_subtree_pool_allocate(SubtreePool *self)
Definition: subtree.c:139
#define TS_MAX_INLINE_TREE_LENGTH
Definition: subtree.c:21
Subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLanguage *language)
Definition: subtree.c:542
#define TS_MAX_TREE_POOL_SIZE
Definition: subtree.c:22
static size_t ts_subtree__write_char_to_string(char *s, size_t n, int32_t c)
Definition: subtree.c:816
bool ts_external_scanner_state_eq(const ExternalScannerState *a, const ExternalScannerState *b)
Definition: subtree.c:61
static size_t ts_subtree__write_to_string(Subtree self, char *string, size_t limit, const TSLanguage *language, bool include_all, TSSymbol alias_symbol, bool alias_is_named, const char *field_name)
Definition: subtree.c:847
MutableSubtree ts_subtree_make_mut(SubtreePool *pool, Subtree self)
Definition: subtree.c:284
void ts_subtree_retain(Subtree self)
Definition: subtree.c:577
static void ts_subtree__write_dot_string(FILE *f, const char *string)
Definition: subtree.c:833
void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self)
Definition: subtree.c:90
void ts_subtree_array_remove_trailing_extras(SubtreeArray *self, SubtreeArray *destination)
Definition: subtree.c:95
const char * ts_external_scanner_state_data(const ExternalScannerState *self)
Definition: subtree.c:53
void ts_subtree_set_symbol(MutableSubtree *self, TSSymbol symbol, const TSLanguage *language)
Definition: subtree.c:226
void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *language)
Definition: subtree.c:338
Subtree ts_subtree_last_external_token(Subtree tree)
Definition: subtree.c:802
void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset, const TSLanguage *language, TSSymbol alias_symbol, FILE *f)
Definition: subtree.c:967
Subtree ts_subtree_new_error(SubtreePool *pool, int32_t lookahead_char, Length padding, Length size, uint32_t bytes_scanned, TSStateId parse_state, const TSLanguage *language)
Definition: subtree.c:244
ExternalScannerState ts_external_scanner_state_copy(const ExternalScannerState *self)
Definition: subtree.c:38
SubtreePool ts_subtree_pool_new(uint32_t capacity)
Definition: subtree.c:123
void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
Definition: subtree.c:70
void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length)
Definition: subtree.c:28
int ts_subtree_compare(Subtree left, Subtree right)
Definition: subtree.c:615
Subtree ts_subtree_new_missing_leaf(SubtreePool *pool, TSSymbol symbol, Length padding, uint32_t lookahead_bytes, const TSLanguage *language)
Definition: subtree.c:558
static bool ts_subtree_can_inline(Length padding, Length size, uint32_t lookahead_bytes)
Definition: subtree.c:157
char * ts_subtree_string(Subtree self, const TSLanguage *language, bool include_all)
Definition: subtree.c:947
void ts_subtree_array_clear(SubtreePool *pool, SubtreeArray *self)
Definition: subtree.c:83
MutableSubtree ts_subtree_clone(Subtree self)
Definition: subtree.c:260
void ts_subtree_pool_delete(SubtreePool *self)
Definition: subtree.c:129
void ts_external_scanner_state_delete(ExternalScannerState *self)
Definition: subtree.c:47
static const char * ROOT_FIELD
Definition: subtree.c:845
static size_t ts_subtree_alloc_size(uint32_t child_count)
Definition: subtree.h:227
static bool ts_subtree_fragile_left(Subtree self)
Definition: subtree.h:322
#define ts_subtree_children(self)
Definition: subtree.h:233
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
static Subtree ts_subtree_from_mut(MutableSubtree self)
Definition: subtree.h:350
static bool ts_subtree_has_external_tokens(Subtree self)
Definition: subtree.h:330
static Length ts_subtree_total_size(Subtree self)
Definition: subtree.h:274
static MutableSubtree ts_subtree_to_mut_unsafe(Subtree self)
Definition: subtree.h:356
static uint32_t ts_subtree_total_bytes(Subtree self)
Definition: subtree.h:278
static uint32_t ts_subtree_error_cost(Subtree self)
Definition: subtree.h:302
#define TS_TREE_STATE_NONE
Definition: subtree.h:18
static int32_t ts_subtree_dynamic_precedence(Subtree self)
Definition: subtree.h:310
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216
static bool ts_subtree_is_error(Subtree self)
Definition: subtree.h:342
static bool ts_subtree_has_changes(Subtree self)
Definition: subtree.h:217
static bool ts_subtree_missing(Subtree self)
Definition: subtree.h:218
static uint16_t ts_subtree_production_id(Subtree self)
Definition: subtree.h:314
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static uint32_t ts_subtree_repeat_depth(Subtree self)
Definition: subtree.h:286
static TSSymbol ts_subtree_leaf_symbol(Subtree self)
Definition: subtree.h:244
static bool ts_subtree_depends_on_column(Subtree self)
Definition: subtree.h:334
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215
static TSStateId ts_subtree_parse_state(Subtree self)
Definition: subtree.h:220
static uint32_t ts_subtree_lookahead_bytes(Subtree self)
Definition: subtree.h:221
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
#define NULL_SUBTREE
Definition: subtree.h:19
static TSStateId ts_subtree_leaf_parse_state(Subtree self)
Definition: subtree.h:250
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256
static uint32_t ts_subtree_node_count(Subtree self)
Definition: subtree.h:290
static bool ts_subtree_fragile_right(Subtree self)
Definition: subtree.h:326
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213
static uint32_t atomic_dec(volatile uint32_t *p)
Definition: atomic.h:52
static uint32_t atomic_inc(volatile uint32_t *p)
Definition: atomic.h:48
#define subtree_symbol(subtree, structural_child_index)
SubtreeHeapData * ptr
Definition: subtree.h:164
SubtreeInlineData data
Definition: subtree.h:163
const SubtreeHeapData * ptr
Definition: subtree.h:158
SubtreeInlineData data
Definition: subtree.h:157
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4