Rizin
unix-like reverse engineering framework and cli tools
subtree.h File Reference
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include "./length.h"
#include "./array.h"
#include "./error_costs.h"
#include "./host.h"
#include "tree_sitter/api.h"
#include "tree_sitter/parser.h"

Go to the source code of this file.

Classes

struct  ExternalScannerState
 
struct  SubtreeInlineData
 
struct  SubtreeHeapData
 
union  Subtree
 
union  MutableSubtree
 
struct  SubtreePool
 

Macros

#define TS_TREE_STATE_NONE   USHRT_MAX
 
#define NULL_SUBTREE   ((Subtree) {.ptr = NULL})
 
#define SUBTREE_BITS
 
#define SUBTREE_SIZE
 
#define SUBTREE_GET(self, name)   (self.data.is_inline ? self.data.name : self.ptr->name)
 
#define ts_subtree_children(self)    ((self).data.is_inline ? NULL : (Subtree *)((self).ptr) - (self).ptr->child_count)
 

Typedefs

typedef struct SubtreeInlineData SubtreeInlineData
 

Functions

typedef Array (Subtree) SubtreeArray
 
typedef Array (MutableSubtree) MutableSubtreeArray
 
void ts_external_scanner_state_init (ExternalScannerState *, const char *, unsigned)
 
const char * ts_external_scanner_state_data (const ExternalScannerState *)
 
void ts_subtree_array_copy (SubtreeArray, SubtreeArray *)
 
void ts_subtree_array_clear (SubtreePool *, SubtreeArray *)
 
void ts_subtree_array_delete (SubtreePool *, SubtreeArray *)
 
void ts_subtree_array_remove_trailing_extras (SubtreeArray *, SubtreeArray *)
 
void ts_subtree_array_reverse (SubtreeArray *)
 
SubtreePool ts_subtree_pool_new (uint32_t capacity)
 
void ts_subtree_pool_delete (SubtreePool *)
 
Subtree ts_subtree_new_leaf (SubtreePool *, TSSymbol, Length, Length, uint32_t, TSStateId, bool, bool, bool, const TSLanguage *)
 
Subtree ts_subtree_new_error (SubtreePool *, int32_t, Length, Length, uint32_t, TSStateId, const TSLanguage *)
 
MutableSubtree ts_subtree_new_node (TSSymbol, SubtreeArray *, unsigned, const TSLanguage *)
 
Subtree ts_subtree_new_error_node (SubtreeArray *, bool, const TSLanguage *)
 
Subtree ts_subtree_new_missing_leaf (SubtreePool *, TSSymbol, Length, uint32_t, const TSLanguage *)
 
MutableSubtree ts_subtree_make_mut (SubtreePool *, Subtree)
 
void ts_subtree_retain (Subtree)
 
void ts_subtree_release (SubtreePool *, Subtree)
 
int ts_subtree_compare (Subtree, Subtree)
 
void ts_subtree_set_symbol (MutableSubtree *, TSSymbol, const TSLanguage *)
 
void ts_subtree_summarize (MutableSubtree, const Subtree *, uint32_t, const TSLanguage *)
 
void ts_subtree_summarize_children (MutableSubtree, const TSLanguage *)
 
void ts_subtree_balance (Subtree, SubtreePool *, const TSLanguage *)
 
Subtree ts_subtree_edit (Subtree, const TSInputEdit *edit, SubtreePool *)
 
char * ts_subtree_string (Subtree, const TSLanguage *, bool include_all)
 
void ts_subtree_print_dot_graph (Subtree, const TSLanguage *, FILE *)
 
Subtree ts_subtree_last_external_token (Subtree)
 
bool ts_subtree_external_scanner_state_eq (Subtree, Subtree)
 
static TSSymbol ts_subtree_symbol (Subtree self)
 
static bool ts_subtree_visible (Subtree self)
 
static bool ts_subtree_named (Subtree self)
 
static bool ts_subtree_extra (Subtree self)
 
static bool ts_subtree_has_changes (Subtree self)
 
static bool ts_subtree_missing (Subtree self)
 
static bool ts_subtree_is_keyword (Subtree self)
 
static TSStateId ts_subtree_parse_state (Subtree self)
 
static uint32_t ts_subtree_lookahead_bytes (Subtree self)
 
static size_t ts_subtree_alloc_size (uint32_t child_count)
 
static void ts_subtree_set_extra (MutableSubtree *self, bool is_extra)
 
static TSSymbol ts_subtree_leaf_symbol (Subtree self)
 
static TSStateId ts_subtree_leaf_parse_state (Subtree self)
 
static Length ts_subtree_padding (Subtree self)
 
static Length ts_subtree_size (Subtree self)
 
static Length ts_subtree_total_size (Subtree self)
 
static uint32_t ts_subtree_total_bytes (Subtree self)
 
static uint32_t ts_subtree_child_count (Subtree self)
 
static uint32_t ts_subtree_repeat_depth (Subtree self)
 
static uint32_t ts_subtree_node_count (Subtree self)
 
static uint32_t ts_subtree_visible_child_count (Subtree self)
 
static uint32_t ts_subtree_error_cost (Subtree self)
 
static int32_t ts_subtree_dynamic_precedence (Subtree self)
 
static uint16_t ts_subtree_production_id (Subtree self)
 
static bool ts_subtree_fragile_left (Subtree self)
 
static bool ts_subtree_fragile_right (Subtree self)
 
static bool ts_subtree_has_external_tokens (Subtree self)
 
static bool ts_subtree_depends_on_column (Subtree self)
 
static bool ts_subtree_is_fragile (Subtree self)
 
static bool ts_subtree_is_error (Subtree self)
 
static bool ts_subtree_is_eof (Subtree self)
 
static Subtree ts_subtree_from_mut (MutableSubtree self)
 
static MutableSubtree ts_subtree_to_mut_unsafe (Subtree self)
 

Macro Definition Documentation

◆ NULL_SUBTREE

#define NULL_SUBTREE   ((Subtree) {.ptr = NULL})

Definition at line 19 of file subtree.h.

◆ SUBTREE_BITS

#define SUBTREE_BITS
Value:
bool visible : 1; \
bool named : 1; \
bool extra : 1; \
bool has_changes : 1; \
bool is_missing : 1; \
bool is_keyword : 1;

Definition at line 52 of file subtree.h.

◆ SUBTREE_GET

#define SUBTREE_GET (   self,
  name 
)    (self.data.is_inline ? self.data.name : self.ptr->name)

Definition at line 211 of file subtree.h.

◆ SUBTREE_SIZE

#define SUBTREE_SIZE
Value:
uint8_t padding_columns; \
uint8_t padding_rows : 4; \
uint8_t lookahead_bytes : 4; \
uint8_t padding_bytes; \
uint8_t size_bytes;
unsigned char uint8_t
Definition: sftypes.h:31

Definition at line 60 of file subtree.h.

◆ ts_subtree_children

#define ts_subtree_children (   self)     ((self).data.is_inline ? NULL : (Subtree *)((self).ptr) - (self).ptr->child_count)

Definition at line 233 of file subtree.h.

◆ TS_TREE_STATE_NONE

#define TS_TREE_STATE_NONE   USHRT_MAX

Definition at line 18 of file subtree.h.

Typedef Documentation

◆ SubtreeInlineData

Definition at line 1 of file subtree.h.

Function Documentation

◆ Array() [1/2]

typedef Array ( MutableSubtree  )

◆ Array() [2/2]

typedef Array ( Subtree  )

◆ ts_external_scanner_state_data()

const char* ts_external_scanner_state_data ( const ExternalScannerState self)

Definition at line 53 of file subtree.c.

53  {
54  if (self->length > sizeof(self->short_data)) {
55  return self->long_data;
56  } else {
57  return self->short_data;
58  }
59 }
uint32_t length
Definition: subtree.h:36
char short_data[24]
Definition: subtree.h:34

Referenced by ts_external_scanner_state_eq(), ts_parser__restore_external_scanner(), and ts_stack_print_dot_graph().

◆ ts_external_scanner_state_init()

void ts_external_scanner_state_init ( ExternalScannerState self,
const char *  data,
unsigned  length 
)

Definition at line 28 of file subtree.c.

28  {
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 }
#define ts_malloc
Definition: alloc.h:21
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
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References length, memcpy(), and ts_malloc.

Referenced by ts_parser__lex().

◆ ts_subtree_alloc_size()

static size_t ts_subtree_alloc_size ( uint32_t  child_count)
inlinestatic

Definition at line 227 of file subtree.h.

227  {
228  return child_count * sizeof(Subtree) + sizeof(SubtreeHeapData);
229 }

Referenced by stack__iter(), ts_subtree_clone(), and ts_subtree_new_node().

◆ ts_subtree_array_clear()

void ts_subtree_array_clear ( SubtreePool pool,
SubtreeArray *  self 
)

Definition at line 83 of file subtree.c.

83  {
84  for (uint32_t i = 0; i < self->size; i++) {
85  ts_subtree_release(pool, self->contents[i]);
86  }
87  array_clear(self);
88 }
lzma_index ** i
Definition: index.h:629
#define array_clear(self)
Definition: array.h:35
unsigned int uint32_t
Definition: sftypes.h:29
void ts_subtree_release(SubtreePool *pool, Subtree self)
Definition: subtree.c:584

References array_clear, i, and ts_subtree_release().

Referenced by ts_parser__reduce(), and ts_subtree_array_delete().

◆ ts_subtree_array_copy()

void ts_subtree_array_copy ( SubtreeArray  self,
SubtreeArray *  dest 
)

Definition at line 70 of file subtree.c.

70  {
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 }
#define ts_calloc
Definition: alloc.h:24
char * dest
Definition: lz4.h:697
void ts_subtree_retain(Subtree self)
Definition: subtree.c:577

References dest, i, memcpy(), ts_calloc, and ts_subtree_retain().

Referenced by stack__iter().

◆ ts_subtree_array_delete()

void ts_subtree_array_delete ( SubtreePool pool,
SubtreeArray *  self 
)

Definition at line 90 of file subtree.c.

90  {
91  ts_subtree_array_clear(pool, self);
92  array_delete(self);
93 }
#define array_delete(self)
Definition: array.h:41
void ts_subtree_array_clear(SubtreePool *pool, SubtreeArray *self)
Definition: subtree.c:83

References array_delete, and ts_subtree_array_clear().

Referenced by stack__iter(), ts_parser__recover(), ts_parser__recover_to_state(), and ts_parser__reduce().

◆ ts_subtree_array_remove_trailing_extras()

void ts_subtree_array_remove_trailing_extras ( SubtreeArray *  self,
SubtreeArray *  destination 
)

Definition at line 95 of file subtree.c.

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 }
#define array_push(self, element)
Definition: array.h:43
void ts_subtree_array_reverse(SubtreeArray *self)
Definition: subtree.c:112
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216

References array_clear, array_push, ts_subtree_array_reverse(), and ts_subtree_extra().

Referenced by ts_parser__recover_to_state(), and ts_parser__reduce().

◆ ts_subtree_array_reverse()

void ts_subtree_array_reverse ( SubtreeArray *  self)

Definition at line 112 of file subtree.c.

112  {
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 }
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
#define swap(a, b)
Definition: qsort.h:111

References i, limit, and swap.

Referenced by stack__iter(), and ts_subtree_array_remove_trailing_extras().

◆ ts_subtree_balance()

void ts_subtree_balance ( Subtree  self,
SubtreePool pool,
const TSLanguage language 
)

Definition at line 338 of file subtree.c.

338  {
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 }
#define array_pop(self)
Definition: array.h:82
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
int n
Definition: mipsasm.c:19
uint32_t repeat_depth
Definition: subtree.h:138
volatile uint32_t ref_count
Definition: subtree.h:112
uint32_t child_count
Definition: subtree.h:117
MutableSubtreeArray tree_stack
Definition: subtree.h:172
static void ts_subtree__compress(MutableSubtree self, unsigned count, const TSLanguage *language, MutableSubtreeArray *stack)
Definition: subtree.c:292
#define ts_subtree_children(self)
Definition: subtree.h:233
static MutableSubtree ts_subtree_to_mut_unsafe(Subtree self)
Definition: subtree.h:356
static uint32_t ts_subtree_repeat_depth(Subtree self)
Definition: subtree.h:286
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
SubtreeHeapData * ptr
Definition: subtree.h:164
const SubtreeHeapData * ptr
Definition: subtree.h:158

References array_clear, array_pop, array_push, SubtreeHeapData::child_count, i, long, n, Subtree::ptr, MutableSubtree::ptr, SubtreeHeapData::ref_count, SubtreeHeapData::repeat_depth, SubtreePool::tree_stack, ts_subtree__compress(), ts_subtree_child_count(), ts_subtree_children, ts_subtree_repeat_depth(), and ts_subtree_to_mut_unsafe().

Referenced by ts_parser_parse().

◆ ts_subtree_child_count()

◆ ts_subtree_compare()

int ts_subtree_compare ( Subtree  left,
Subtree  right 
)

Definition at line 615 of file subtree.c.

615  {
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 }
int ts_subtree_compare(Subtree left, Subtree right)
Definition: subtree.c:615
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213

References i, n, ts_subtree_child_count(), ts_subtree_children, and ts_subtree_symbol().

Referenced by ts_parser__select_tree().

◆ ts_subtree_depends_on_column()

static bool ts_subtree_depends_on_column ( Subtree  self)
inlinestatic

Definition at line 334 of file subtree.h.

334  {
335  return self.data.is_inline ? false : self.ptr->depends_on_column;
336 }
#define false

References false.

Referenced by ts_subtree__print_dot_graph(), ts_subtree_edit(), and ts_subtree_summarize_children().

◆ ts_subtree_dynamic_precedence()

static int32_t ts_subtree_dynamic_precedence ( Subtree  self)
inlinestatic

Definition at line 310 of file subtree.h.

310  {
311  return (self.data.is_inline || self.ptr->child_count == 0) ? 0 : self.ptr->dynamic_precedence;
312 }

Referenced by stack_node_add_link(), stack_node_new(), ts_parser__select_tree(), ts_stack_print_dot_graph(), and ts_subtree_summarize_children().

◆ ts_subtree_edit()

Subtree ts_subtree_edit ( Subtree  self,
const TSInputEdit edit,
SubtreePool pool 
)

Definition at line 640 of file subtree.c.

640  {
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 }
#define array_new()
Definition: array.h:25
#define Array(T)
Definition: array.h:15
voidpf void uLong size
Definition: ioapi.h:138
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
Definition: subtree.c:15
Length new_end
Definition: subtree.c:18
Length old_end
Definition: subtree.c:17
Length start
Definition: subtree.c:16
Definition: length.h:9
uint32_t bytes
Definition: length.h:10
TSPoint extent
Definition: length.h:11
TSSymbol symbol
Definition: subtree.h:118
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
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
Length padding
Definition: subtree.h:113
bool has_external_tokens
Definition: subtree.h:127
uint32_t error_cost
Definition: subtree.h:116
uint16_t parse_state
Definition: subtree.h:97
SUBTREE_BITS uint8_t symbol
Definition: subtree.h:96
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
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57
Definition: zipcmp.c:77
Definition: z80asm.h:140
static void ts_subtree_set_has_changes(MutableSubtree *self)
Definition: subtree.c:632
static SubtreeHeapData * ts_subtree_pool_allocate(SubtreePool *self)
Definition: subtree.c:139
MutableSubtree ts_subtree_make_mut(SubtreePool *pool, Subtree self)
Definition: subtree.c:284
static bool ts_subtree_can_inline(Length padding, Length size, uint32_t lookahead_bytes)
Definition: subtree.c:157
static Subtree ts_subtree_from_mut(MutableSubtree self)
Definition: subtree.h:350
static Length ts_subtree_total_size(Subtree self)
Definition: subtree.h:274
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static bool ts_subtree_depends_on_column(Subtree self)
Definition: subtree.h:334
static uint32_t ts_subtree_lookahead_bytes(Subtree self)
Definition: subtree.h:221
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256
SubtreeInlineData data
Definition: subtree.h:163

References Array, array_delete, array_new, array_pop, array_push, Length::bytes, SubtreeHeapData::child_count, TSPoint::column, MutableSubtree::data, SubtreeHeapData::depends_on_column, SubtreeHeapData::error_cost, Length::extent, SubtreeHeapData::extra, SubtreeHeapData::fragile_left, SubtreeHeapData::fragile_right, SubtreeHeapData::has_changes, SubtreeHeapData::has_external_tokens, i, SubtreeInlineData::is_inline, SubtreeHeapData::is_keyword, SubtreeHeapData::is_missing, length_add(), length_sub(), length_zero(), SubtreeHeapData::lookahead_bytes, n, SubtreeHeapData::named, Edit::new_end, TSInputEdit::new_end_byte, TSInputEdit::new_end_point, Edit::old_end, TSInputEdit::old_end_byte, TSInputEdit::old_end_point, SubtreeHeapData::padding, SubtreeInlineData::parse_state, SubtreeHeapData::parse_state, MutableSubtree::ptr, SubtreeHeapData::ref_count, TSPoint::row, SubtreeHeapData::size, Edit::start, TSInputEdit::start_byte, TSInputEdit::start_point, SubtreeInlineData::symbol, SubtreeHeapData::symbol, ts_subtree_can_inline(), ts_subtree_child_count(), ts_subtree_children, ts_subtree_depends_on_column(), ts_subtree_from_mut(), ts_subtree_lookahead_bytes(), ts_subtree_make_mut(), ts_subtree_padding(), ts_subtree_pool_allocate(), ts_subtree_set_has_changes(), ts_subtree_size(), ts_subtree_total_size(), and SubtreeHeapData::visible.

Referenced by ts_tree_edit().

◆ ts_subtree_error_cost()

static uint32_t ts_subtree_error_cost ( Subtree  self)
inlinestatic

Definition at line 302 of file subtree.h.

302  {
303  if (ts_subtree_missing(self)) {
305  } else {
306  return self.data.is_inline ? 0 : self.ptr->error_cost;
307  }
308 }
#define ERROR_COST_PER_RECOVERY
Definition: error_costs.h:5
#define ERROR_COST_PER_MISSING_TREE
Definition: error_costs.h:6
static bool ts_subtree_missing(Subtree self)
Definition: subtree.h:218

References ERROR_COST_PER_MISSING_TREE, ERROR_COST_PER_RECOVERY, and ts_subtree_missing().

Referenced by stack__subtree_is_equivalent(), stack_node_new(), ts_node_has_error(), ts_parser__better_version_exists(), ts_parser__select_tree(), ts_parser_parse(), ts_stack_has_advanced_since_error(), ts_stack_print_dot_graph(), ts_subtree__print_dot_graph(), and ts_subtree_summarize_children().

◆ ts_subtree_external_scanner_state_eq()

bool ts_subtree_external_scanner_state_eq ( Subtree  self,
Subtree  other 
)

Definition at line 1027 of file subtree.c.

1027  {
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 }
ExternalScannerState external_scanner_state
Definition: subtree.h:148
static const ExternalScannerState empty_state
Definition: subtree.c:24
bool ts_external_scanner_state_eq(const ExternalScannerState *a, const ExternalScannerState *b)
Definition: subtree.c:61
static bool ts_subtree_has_external_tokens(Subtree self)
Definition: subtree.h:330

References SubtreeHeapData::child_count, empty_state, SubtreeHeapData::external_scanner_state, Subtree::ptr, ts_external_scanner_state_eq(), and ts_subtree_has_external_tokens().

Referenced by stack__subtree_is_equivalent(), ts_parser__get_cached_token(), ts_parser__reuse_node(), and ts_stack_can_merge().

◆ ts_subtree_extra()

◆ ts_subtree_fragile_left()

static bool ts_subtree_fragile_left ( Subtree  self)
inlinestatic

Definition at line 322 of file subtree.h.

322  {
323  return self.data.is_inline ? false : self.ptr->fragile_left;
324 }

References false.

Referenced by ts_subtree_summarize_children().

◆ ts_subtree_fragile_right()

static bool ts_subtree_fragile_right ( Subtree  self)
inlinestatic

Definition at line 326 of file subtree.h.

326  {
327  return self.data.is_inline ? false : self.ptr->fragile_right;
328 }

References false.

Referenced by ts_subtree_summarize_children().

◆ ts_subtree_from_mut()

static Subtree ts_subtree_from_mut ( MutableSubtree  self)
inlinestatic

Definition at line 350 of file subtree.h.

350  {
351  Subtree result;
352  result.data = self.data;
353  return result;
354 }
SubtreeInlineData data
Definition: subtree.h:157

References Subtree::data.

Referenced by ts_parser__accept(), ts_parser__advance(), ts_parser__recover(), ts_parser__reduce(), ts_parser__select_children(), ts_parser__shift(), ts_subtree__compress(), ts_subtree_edit(), and ts_subtree_new_error_node().

◆ ts_subtree_has_changes()

static bool ts_subtree_has_changes ( Subtree  self)
inlinestatic

Definition at line 217 of file subtree.h.

217 { return SUBTREE_GET(self, has_changes); }

References SUBTREE_GET.

Referenced by iterator_compare(), ts_node_has_changes(), ts_parser__reuse_node(), and ts_subtree__print_dot_graph().

◆ ts_subtree_has_external_tokens()

static bool ts_subtree_has_external_tokens ( Subtree  self)
inlinestatic

Definition at line 330 of file subtree.h.

330  {
331  return self.data.is_inline ? false : self.ptr->has_external_tokens;
332 }

References false.

Referenced by reusable_node_advance(), ts_parser__recover(), ts_parser__shift(), ts_subtree_external_scanner_state_eq(), ts_subtree_last_external_token(), and ts_subtree_summarize_children().

◆ ts_subtree_is_eof()

static bool ts_subtree_is_eof ( Subtree  self)
inlinestatic

Definition at line 346 of file subtree.h.

346  {
347  return ts_subtree_symbol(self) == ts_builtin_sym_end;
348 }
#define ts_builtin_sym_end
Definition: parser.h:13

References ts_builtin_sym_end, and ts_subtree_symbol().

Referenced by ts_parser__accept(), ts_parser__recover(), and ts_parser__reuse_node().

◆ ts_subtree_is_error()

◆ ts_subtree_is_fragile()

static bool ts_subtree_is_fragile ( Subtree  self)
inlinestatic

Definition at line 338 of file subtree.h.

338  {
339  return self.data.is_inline ? false : (self.ptr->fragile_left || self.ptr->fragile_right);
340 }

References false.

Referenced by ts_parser__reuse_node().

◆ ts_subtree_is_keyword()

static bool ts_subtree_is_keyword ( Subtree  self)
inlinestatic

Definition at line 219 of file subtree.h.

219 { return SUBTREE_GET(self, is_keyword); }

References SUBTREE_GET.

Referenced by ts_parser__advance(), and ts_parser__can_reuse_first_leaf().

◆ ts_subtree_last_external_token()

Subtree ts_subtree_last_external_token ( Subtree  tree)

Definition at line 802 of file subtree.c.

802  {
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 }
#define NULL_SUBTREE
Definition: subtree.h:19

References SubtreeHeapData::child_count, i, NULL_SUBTREE, Subtree::ptr, ts_subtree_children, and ts_subtree_has_external_tokens().

Referenced by reusable_node_advance(), ts_parser__recover(), and ts_parser__shift().

◆ ts_subtree_leaf_parse_state()

static TSStateId ts_subtree_leaf_parse_state ( Subtree  self)
inlinestatic

Definition at line 250 of file subtree.h.

250  {
251  if (self.data.is_inline) return self.data.parse_state;
252  if (self.ptr->child_count == 0) return self.ptr->parse_state;
253  return self.ptr->first_leaf.parse_state;
254 }

Referenced by ts_parser__can_reuse_first_leaf(), and ts_subtree_summarize_children().

◆ ts_subtree_leaf_symbol()

static TSSymbol ts_subtree_leaf_symbol ( Subtree  self)
inlinestatic

Definition at line 244 of file subtree.h.

244  {
245  if (self.data.is_inline) return self.data.symbol;
246  if (self.ptr->child_count == 0) return self.ptr->symbol;
247  return self.ptr->first_leaf.symbol;
248 }

Referenced by ts_parser__advance(), ts_parser__can_reuse_first_leaf(), ts_parser__handle_error(), ts_parser__reuse_node(), and ts_subtree_summarize_children().

◆ ts_subtree_lookahead_bytes()

static uint32_t ts_subtree_lookahead_bytes ( Subtree  self)
inlinestatic

Definition at line 221 of file subtree.h.

221 { return SUBTREE_GET(self, lookahead_bytes); }

References SUBTREE_GET.

Referenced by ts_parser__handle_error(), ts_subtree__print_dot_graph(), ts_subtree_edit(), and ts_subtree_summarize_children().

◆ ts_subtree_make_mut()

MutableSubtree ts_subtree_make_mut ( SubtreePool pool,
Subtree  self 
)

Definition at line 284 of file subtree.c.

284  {
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 }
MutableSubtree ts_subtree_clone(Subtree self)
Definition: subtree.c:260

References MutableSubtree::data, ts_subtree_clone(), ts_subtree_release(), and ts_subtree_to_mut_unsafe().

Referenced by ts_parser__advance(), ts_parser__recover(), ts_parser__shift(), and ts_subtree_edit().

◆ ts_subtree_missing()

static bool ts_subtree_missing ( Subtree  self)
inlinestatic

Definition at line 218 of file subtree.h.

218 { return SUBTREE_GET(self, is_missing); }

References SUBTREE_GET.

Referenced by ts_node_is_missing(), ts_parser__reuse_node(), ts_subtree__write_to_string(), and ts_subtree_error_cost().

◆ ts_subtree_named()

static bool ts_subtree_named ( Subtree  self)
inlinestatic

◆ ts_subtree_new_error()

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 at line 244 of file subtree.c.

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 }
int32_t lookahead_char
Definition: subtree.h:151
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

References SubtreeHeapData::fragile_left, SubtreeHeapData::fragile_right, SubtreeHeapData::lookahead_char, Subtree::ptr, ts_builtin_sym_error, and ts_subtree_new_leaf().

Referenced by ts_parser__lex().

◆ ts_subtree_new_error_node()

Subtree ts_subtree_new_error_node ( SubtreeArray *  children,
bool  extra,
const TSLanguage language 
)

Definition at line 542 of file subtree.c.

546  {
548  ts_builtin_sym_error, children, 0, language
549  );
550  result.ptr->extra = extra;
551  return ts_subtree_from_mut(result);
552 }
MutableSubtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, unsigned production_id, const TSLanguage *language)
Definition: subtree.c:500

References SubtreeHeapData::extra, MutableSubtree::ptr, ts_builtin_sym_error, ts_subtree_from_mut(), and ts_subtree_new_node().

Referenced by ts_parser__recover(), and ts_parser__recover_to_state().

◆ ts_subtree_new_leaf()

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 at line 167 of file subtree.c.

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 }
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:38
#define UINT8_MAX
bool visible
Definition: parser.h:36

References Length::bytes, TSPoint::column, Length::extent, TSSymbolMetadata::named, SubtreeHeapData::ref_count, TSPoint::row, ts_builtin_sym_end, ts_language_symbol_metadata(), ts_subtree_can_inline(), ts_subtree_pool_allocate(), UINT8_MAX, and TSSymbolMetadata::visible.

Referenced by ts_parser__lex(), ts_subtree_new_error(), and ts_subtree_new_missing_leaf().

◆ ts_subtree_new_missing_leaf()

Subtree ts_subtree_new_missing_leaf ( SubtreePool pool,
TSSymbol  symbol,
Length  padding,
uint32_t  lookahead_bytes,
const TSLanguage language 
)

Definition at line 558 of file subtree.c.

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 }

References Subtree::data, SubtreeInlineData::is_inline, length_zero(), Subtree::ptr, and ts_subtree_new_leaf().

Referenced by ts_parser__handle_error().

◆ ts_subtree_new_node()

MutableSubtree ts_subtree_new_node ( TSSymbol  symbol,
SubtreeArray *  children,
unsigned  production_id,
const TSLanguage language 
)

Definition at line 500 of file subtree.c.

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 }
#define ts_realloc
Definition: alloc.h:27
#define ts_builtin_sym_error_repeat
Definition: language.h:11
void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *language)
Definition: subtree.c:371
static size_t ts_subtree_alloc_size(uint32_t child_count)
Definition: subtree.h:227

References TSSymbolMetadata::named, MutableSubtree::ptr, SubtreeHeapData::ref_count, ts_builtin_sym_error, ts_builtin_sym_error_repeat, ts_language_symbol_metadata(), ts_realloc, ts_subtree_alloc_size(), ts_subtree_summarize_children(), and TSSymbolMetadata::visible.

Referenced by ts_parser__accept(), ts_parser__recover(), ts_parser__reduce(), ts_parser__select_children(), and ts_subtree_new_error_node().

◆ ts_subtree_node_count()

static uint32_t ts_subtree_node_count ( Subtree  self)
inlinestatic

Definition at line 290 of file subtree.h.

290  {
291  return (self.data.is_inline || self.ptr->child_count == 0) ? 1 : self.ptr->node_count;
292 }

Referenced by stack_node_add_link(), stack_node_new(), and ts_subtree_summarize_children().

◆ ts_subtree_padding()

static Length ts_subtree_padding ( Subtree  self)
inlinestatic

Definition at line 256 of file subtree.h.

256  {
257  if (self.data.is_inline) {
258  Length result = {self.data.padding_bytes, {self.data.padding_rows, self.data.padding_columns}};
259  return result;
260  } else {
261  return self.ptr->padding;
262  }
263 }

Referenced by iterator_advance(), iterator_descend(), iterator_end_position(), iterator_start_position(), stack__subtree_is_equivalent(), ts_node_child_iterator_next(), ts_subtree_edit(), ts_subtree_summarize_children(), ts_subtree_total_size(), ts_tree_cursor_child_iterator_next(), and ts_tree_root_node().

◆ ts_subtree_parse_state()

static TSStateId ts_subtree_parse_state ( Subtree  self)
inlinestatic

Definition at line 220 of file subtree.h.

220 { return SUBTREE_GET(self, parse_state); }

References SUBTREE_GET.

Referenced by iterator_compare(), ts_parser__breakdown_lookahead(), ts_parser__can_reuse_first_leaf(), and ts_subtree__print_dot_graph().

◆ ts_subtree_pool_delete()

void ts_subtree_pool_delete ( SubtreePool self)

Definition at line 129 of file subtree.c.

129  {
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 }
#define ts_free
Definition: alloc.h:30
MutableSubtreeArray free_trees
Definition: subtree.h:171

References array_delete, i, and ts_free.

Referenced by ts_parser_delete(), ts_tree_delete(), and ts_tree_edit().

◆ ts_subtree_pool_new()

SubtreePool ts_subtree_pool_new ( uint32_t  capacity)

Definition at line 123 of file subtree.c.

123  {
124  SubtreePool self = {array_new(), array_new()};
125  array_reserve(&self.free_trees, capacity);
126  return self;
127 }
#define array_reserve(self, new_capacity)
Definition: array.h:37

References array_new, and array_reserve.

Referenced by ts_parser_new(), ts_tree_delete(), and ts_tree_edit().

◆ ts_subtree_print_dot_graph()

void ts_subtree_print_dot_graph ( Subtree  self,
const TSLanguage language,
FILE *  f 
)

Definition at line 1020 of file subtree.c.

1020  {
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 }
#define f(i)
Definition: sha256.c:46
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

References f, and ts_subtree__print_dot_graph().

Referenced by ts_tree_print_dot_graph().

◆ ts_subtree_production_id()

static uint16_t ts_subtree_production_id ( Subtree  self)
inlinestatic

Definition at line 314 of file subtree.h.

314  {
315  if (ts_subtree_child_count(self) > 0) {
316  return self.ptr->production_id;
317  } else {
318  return 0;
319  }
320 }

References ts_subtree_child_count().

Referenced by ts_subtree__print_dot_graph().

◆ ts_subtree_release()

void ts_subtree_release ( SubtreePool pool,
Subtree  self 
)

Definition at line 584 of file subtree.c.

584  {
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 }
assert(limit<=UINT32_MAX/2)
static void ts_subtree_pool_free(SubtreePool *self, SubtreeHeapData *tree)
Definition: subtree.c:147
void ts_external_scanner_state_delete(ExternalScannerState *self)
Definition: subtree.c:47
static uint32_t atomic_dec(volatile uint32_t *p)
Definition: atomic.h:52

References array_clear, array_pop, array_push, assert(), atomic_dec(), SubtreeHeapData::child_count, Subtree::data, SubtreeHeapData::external_scanner_state, SubtreeHeapData::has_external_tokens, i, SubtreeInlineData::is_inline, Subtree::ptr, MutableSubtree::ptr, SubtreeHeapData::ref_count, SubtreePool::tree_stack, ts_external_scanner_state_delete(), ts_free, ts_subtree_children, ts_subtree_pool_free(), and ts_subtree_to_mut_unsafe().

Referenced by stack_head_delete(), stack_node_add_link(), stack_node_release(), ts_parser__accept(), ts_parser__advance(), ts_parser__breakdown_lookahead(), ts_parser__breakdown_top_of_stack(), ts_parser__recover(), ts_parser__reduce(), ts_parser__set_cached_token(), ts_parser_delete(), ts_parser_reset(), ts_stack_set_last_external_token(), ts_subtree_array_clear(), ts_subtree_make_mut(), and ts_tree_delete().

◆ ts_subtree_repeat_depth()

static uint32_t ts_subtree_repeat_depth ( Subtree  self)
inlinestatic

Definition at line 286 of file subtree.h.

286  {
287  return self.data.is_inline ? 0 : self.ptr->repeat_depth;
288 }

Referenced by ts_subtree__print_dot_graph(), ts_subtree_balance(), and ts_subtree_summarize_children().

◆ ts_subtree_retain()

void ts_subtree_retain ( Subtree  self)

Definition at line 577 of file subtree.c.

577  {
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 }
static uint32_t atomic_inc(volatile uint32_t *p)
Definition: atomic.h:48

References assert(), and atomic_inc().

Referenced by stack__iter(), stack_node_add_link(), ts_parser__accept(), ts_parser__breakdown_lookahead(), ts_parser__breakdown_top_of_stack(), ts_parser__get_cached_token(), ts_parser__recover_to_state(), ts_parser__reuse_node(), ts_parser__set_cached_token(), ts_parser_parse(), ts_stack__add_version(), ts_stack_copy_version(), ts_stack_set_last_external_token(), ts_subtree_array_copy(), ts_subtree_clone(), and ts_tree_copy().

◆ ts_subtree_set_extra()

static void ts_subtree_set_extra ( MutableSubtree self,
bool  is_extra 
)
inlinestatic

Definition at line 236 of file subtree.h.

236  {
237  if (self->data.is_inline) {
238  self->data.extra = is_extra;
239  } else {
240  self->ptr->extra = is_extra;
241  }
242 }

Referenced by ts_parser__recover(), and ts_parser__shift().

◆ ts_subtree_set_symbol()

void ts_subtree_set_symbol ( MutableSubtree self,
TSSymbol  symbol,
const TSLanguage language 
)

Definition at line 226 of file subtree.c.

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 }

References assert(), TSSymbolMetadata::named, ts_language_symbol_metadata(), UINT8_MAX, and TSSymbolMetadata::visible.

Referenced by ts_parser__advance().

◆ ts_subtree_size()

static Length ts_subtree_size ( Subtree  self)
inlinestatic

◆ ts_subtree_string()

char* ts_subtree_string ( Subtree  self,
const TSLanguage language,
bool  include_all 
)

Definition at line 947 of file subtree.c.

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 }
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
static const char * ROOT_FIELD
Definition: subtree.c:845

References ROOT_FIELD, ts_malloc, and ts_subtree__write_to_string().

Referenced by ts_node_string().

◆ ts_subtree_summarize()

void ts_subtree_summarize ( MutableSubtree  ,
const Subtree ,
uint32_t  ,
const TSLanguage  
)

◆ ts_subtree_summarize_children()

void ts_subtree_summarize_children ( MutableSubtree  self,
const TSLanguage language 
)

Definition at line 371 of file subtree.c.

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 }
#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_SKIPPED_CHAR
Definition: error_costs.h:9
static const TSSymbol * ts_language_alias_sequence(const TSLanguage *self, uint32_t production_id)
Definition: language.h:227
uint16_t TSSymbol
Definition: parser.h:19
uint32_t visible_child_count
Definition: subtree.h:135
uint32_t named_child_count
Definition: subtree.h:136
struct SubtreeHeapData::@621::@623::@625 first_leaf
static bool ts_subtree_fragile_left(Subtree self)
Definition: subtree.h:322
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
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_is_error(Subtree self)
Definition: subtree.h:342
static TSSymbol ts_subtree_leaf_symbol(Subtree self)
Definition: subtree.h:244
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215
static TSStateId ts_subtree_leaf_parse_state(Subtree self)
Definition: subtree.h:250
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

References assert(), SubtreeHeapData::depends_on_column, ERROR_COST_PER_RECOVERY, ERROR_COST_PER_SKIPPED_CHAR, ERROR_COST_PER_SKIPPED_LINE, ERROR_COST_PER_SKIPPED_TREE, SubtreeHeapData::first_leaf, i, length_add(), SubtreeHeapData::named_child_count, Subtree::ptr, ts_builtin_sym_error, ts_builtin_sym_error_repeat, ts_language_alias_sequence(), ts_language_symbol_metadata(), ts_subtree_child_count(), ts_subtree_children, ts_subtree_depends_on_column(), ts_subtree_dynamic_precedence(), ts_subtree_error_cost(), ts_subtree_extra(), ts_subtree_fragile_left(), ts_subtree_fragile_right(), ts_subtree_has_external_tokens(), ts_subtree_is_error(), ts_subtree_leaf_parse_state(), ts_subtree_leaf_symbol(), ts_subtree_lookahead_bytes(), ts_subtree_named(), ts_subtree_node_count(), ts_subtree_padding(), ts_subtree_repeat_depth(), ts_subtree_size(), ts_subtree_symbol(), ts_subtree_total_size(), ts_subtree_visible(), TS_TREE_STATE_NONE, and SubtreeHeapData::visible_child_count.

Referenced by ts_subtree__compress(), and ts_subtree_new_node().

◆ ts_subtree_symbol()

◆ ts_subtree_to_mut_unsafe()

static MutableSubtree ts_subtree_to_mut_unsafe ( Subtree  self)
inlinestatic

Definition at line 356 of file subtree.h.

356  {
357  MutableSubtree result;
358  result.data = self.data;
359  return result;
360 }

References MutableSubtree::data.

Referenced by ts_subtree__compress(), ts_subtree_balance(), ts_subtree_make_mut(), and ts_subtree_release().

◆ ts_subtree_total_bytes()

◆ ts_subtree_total_size()

◆ ts_subtree_visible()

◆ ts_subtree_visible_child_count()

static uint32_t ts_subtree_visible_child_count ( Subtree  self)
inlinestatic

Definition at line 294 of file subtree.h.

294  {
295  if (ts_subtree_child_count(self) > 0) {
296  return self.ptr->visible_child_count;
297  } else {
298  return 0;
299  }
300 }

References ts_subtree_child_count().

Referenced by ts_tree_cursor_current_status(), ts_tree_cursor_goto_first_child(), ts_tree_cursor_goto_first_child_for_byte(), ts_tree_cursor_goto_first_child_for_point(), and ts_tree_cursor_goto_next_sibling().