Rizin
unix-like reverse engineering framework and cli tools
node.c File Reference
#include <stdbool.h>
#include "./subtree.h"
#include "./tree.h"
#include "./language.h"

Go to the source code of this file.

Classes

struct  NodeChildIterator
 

Functions

TSNode ts_node_new (const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias)
 
static TSNode ts_node__null (void)
 
uint32_t ts_node_start_byte (TSNode self)
 
TSPoint ts_node_start_point (TSNode self)
 
static uint32_t ts_node__alias (const TSNode *self)
 
static Subtree ts_node__subtree (TSNode self)
 
static NodeChildIterator ts_node_iterate_children (const TSNode *node)
 
static bool ts_node_child_iterator_done (NodeChildIterator *self)
 
static bool ts_node_child_iterator_next (NodeChildIterator *self, TSNode *result)
 
static bool ts_node__is_relevant (TSNode self, bool include_anonymous)
 
static uint32_t ts_node__relevant_child_count (TSNode self, bool include_anonymous)
 
static TSNode ts_node__child (TSNode self, uint32_t child_index, bool include_anonymous)
 
static bool ts_subtree_has_trailing_empty_descendant (Subtree self, Subtree other)
 
static TSNode ts_node__prev_sibling (TSNode self, bool include_anonymous)
 
static TSNode ts_node__next_sibling (TSNode self, bool include_anonymous)
 
static TSNode ts_node__first_child_for_byte (TSNode self, uint32_t goal, bool include_anonymous)
 
static TSNode ts_node__descendant_for_byte_range (TSNode self, uint32_t range_start, uint32_t range_end, bool include_anonymous)
 
static TSNode ts_node__descendant_for_point_range (TSNode self, TSPoint range_start, TSPoint range_end, bool include_anonymous)
 
uint32_t ts_node_end_byte (TSNode self)
 
TSPoint ts_node_end_point (TSNode self)
 
TSSymbol ts_node_symbol (TSNode self)
 
const char * ts_node_type (TSNode self)
 
char * ts_node_string (TSNode self)
 
bool ts_node_eq (TSNode self, TSNode other)
 
bool ts_node_is_null (TSNode self)
 
bool ts_node_is_extra (TSNode self)
 
bool ts_node_is_named (TSNode self)
 
bool ts_node_is_missing (TSNode self)
 
bool ts_node_has_changes (TSNode self)
 
bool ts_node_has_error (TSNode self)
 
TSNode ts_node_parent (TSNode self)
 
TSNode ts_node_child (TSNode self, uint32_t child_index)
 
TSNode ts_node_named_child (TSNode self, uint32_t child_index)
 
TSNode ts_node_child_by_field_id (TSNode self, TSFieldId field_id)
 
const char * ts_node_field_name_for_child (TSNode self, uint32_t child_index)
 
TSNode ts_node_child_by_field_name (TSNode self, const char *name, uint32_t name_length)
 
uint32_t ts_node_child_count (TSNode self)
 
uint32_t ts_node_named_child_count (TSNode self)
 
TSNode ts_node_next_sibling (TSNode self)
 
TSNode ts_node_next_named_sibling (TSNode self)
 
TSNode ts_node_prev_sibling (TSNode self)
 
TSNode ts_node_prev_named_sibling (TSNode self)
 
TSNode ts_node_first_child_for_byte (TSNode self, uint32_t byte)
 
TSNode ts_node_first_named_child_for_byte (TSNode self, uint32_t byte)
 
TSNode ts_node_descendant_for_byte_range (TSNode self, uint32_t start, uint32_t end)
 
TSNode ts_node_named_descendant_for_byte_range (TSNode self, uint32_t start, uint32_t end)
 
TSNode ts_node_descendant_for_point_range (TSNode self, TSPoint start, TSPoint end)
 
TSNode ts_node_named_descendant_for_point_range (TSNode self, TSPoint start, TSPoint end)
 
void ts_node_edit (TSNode *self, const TSInputEdit *edit)
 

Function Documentation

◆ ts_node__alias()

static uint32_t ts_node__alias ( const TSNode self)
inlinestatic

Definition at line 44 of file node.c.

44  {
45  return self->context[3];
46 }

Referenced by ts_node__is_relevant(), ts_node_is_named(), ts_node_symbol(), and ts_node_type().

◆ ts_node__child()

static TSNode ts_node__child ( TSNode  self,
uint32_t  child_index,
bool  include_anonymous 
)
inlinestatic

Definition at line 136 of file node.c.

140  {
141  TSNode result = self;
142  bool did_descend = true;
143 
144  while (did_descend) {
145  did_descend = false;
146 
147  TSNode child;
148  uint32_t index = 0;
150  while (ts_node_child_iterator_next(&iterator, &child)) {
151  if (ts_node__is_relevant(child, include_anonymous)) {
152  if (index == child_index) {
153  return child;
154  }
155  index++;
156  } else {
157  uint32_t grandchild_index = child_index - index;
158  uint32_t grandchild_count = ts_node__relevant_child_count(child, include_anonymous);
159  if (grandchild_index < grandchild_count) {
160  did_descend = true;
161  result = child;
162  child_index = grandchild_index;
163  break;
164  }
165  index += grandchild_count;
166  }
167  }
168  }
169 
170  return ts_node__null();
171 }
const MCPhysReg * iterator
static bool ts_node__is_relevant(TSNode self, bool include_anonymous)
Definition: node.c:106
static bool ts_node_child_iterator_next(NodeChildIterator *self, TSNode *result)
Definition: node.c:77
static NodeChildIterator ts_node_iterate_children(const TSNode *node)
Definition: node.c:54
static uint32_t ts_node__relevant_child_count(TSNode self, bool include_anonymous)
Definition: node.c:120
static TSNode ts_node__null(void)
Definition: node.c:30
unsigned int uint32_t
Definition: sftypes.h:29
Definition: api.h:92

References ts_node__is_relevant(), ts_node__null(), ts_node__relevant_child_count(), ts_node_child_iterator_next(), and ts_node_iterate_children().

Referenced by ts_node_child(), and ts_node_named_child().

◆ ts_node__descendant_for_byte_range()

static TSNode ts_node__descendant_for_byte_range ( TSNode  self,
uint32_t  range_start,
uint32_t  range_end,
bool  include_anonymous 
)
inlinestatic

Definition at line 326 of file node.c.

331  {
332  TSNode node = self;
333  TSNode last_visible_node = self;
334 
335  bool did_descend = true;
336  while (did_descend) {
337  did_descend = false;
338 
339  TSNode child;
341  while (ts_node_child_iterator_next(&iterator, &child)) {
342  uint32_t node_end = iterator.position.bytes;
343 
344  // The end of this node must extend far enough forward to touch
345  // the end of the range and exceed the start of the range.
346  if (node_end < range_end) continue;
347  if (node_end <= range_start) continue;
348 
349  // The start of this node must extend far enough backward to
350  // touch the start of the range.
351  if (range_start < ts_node_start_byte(child)) break;
352 
353  node = child;
354  if (ts_node__is_relevant(node, include_anonymous)) {
355  last_visible_node = node;
356  }
357  did_descend = true;
358  break;
359  }
360  }
361 
362  return last_visible_node;
363 }
uint32_t ts_node_start_byte(TSNode self)
Definition: node.c:36

References ts_node__is_relevant(), ts_node_child_iterator_next(), ts_node_iterate_children(), and ts_node_start_byte().

Referenced by ts_node_descendant_for_byte_range(), and ts_node_named_descendant_for_byte_range().

◆ ts_node__descendant_for_point_range()

static TSNode ts_node__descendant_for_point_range ( TSNode  self,
TSPoint  range_start,
TSPoint  range_end,
bool  include_anonymous 
)
inlinestatic

Definition at line 365 of file node.c.

370  {
371  TSNode node = self;
372  TSNode last_visible_node = self;
373 
374  bool did_descend = true;
375  while (did_descend) {
376  did_descend = false;
377 
378  TSNode child;
380  while (ts_node_child_iterator_next(&iterator, &child)) {
381  TSPoint node_end = iterator.position.extent;
382 
383  // The end of this node must extend far enough forward to touch
384  // the end of the range and exceed the start of the range.
385  if (point_lt(node_end, range_end)) continue;
386  if (point_lte(node_end, range_start)) continue;
387 
388  // The start of this node must extend far enough backward to
389  // touch the start of the range.
390  if (point_lt(range_start, ts_node_start_point(child))) break;
391 
392  node = child;
393  if (ts_node__is_relevant(node, include_anonymous)) {
394  last_visible_node = node;
395  }
396  did_descend = true;
397  break;
398  }
399  }
400 
401  return last_visible_node;
402 }
TSPoint ts_node_start_point(TSNode self)
Definition: node.c:40
static bool point_lt(TSPoint a, TSPoint b)
Definition: point.h:32
static bool point_lte(TSPoint a, TSPoint b)
Definition: point.h:28
Definition: api.h:55

References point_lt(), point_lte(), ts_node__is_relevant(), ts_node_child_iterator_next(), ts_node_iterate_children(), and ts_node_start_point().

Referenced by ts_node_descendant_for_point_range(), and ts_node_named_descendant_for_point_range().

◆ ts_node__first_child_for_byte()

static TSNode ts_node__first_child_for_byte ( TSNode  self,
uint32_t  goal,
bool  include_anonymous 
)
inlinestatic

Definition at line 297 of file node.c.

301  {
302  TSNode node = self;
303  bool did_descend = true;
304 
305  while (did_descend) {
306  did_descend = false;
307 
308  TSNode child;
310  while (ts_node_child_iterator_next(&iterator, &child)) {
311  if (ts_node_end_byte(child) > goal) {
312  if (ts_node__is_relevant(child, include_anonymous)) {
313  return child;
314  } else if (ts_node_child_count(child) > 0) {
315  did_descend = true;
316  node = child;
317  break;
318  }
319  }
320  }
321  }
322 
323  return ts_node__null();
324 }
uint32_t ts_node_child_count(TSNode self)
Definition: node.c:602
uint32_t ts_node_end_byte(TSNode self)
Definition: node.c:406

References ts_node__is_relevant(), ts_node__null(), ts_node_child_count(), ts_node_child_iterator_next(), ts_node_end_byte(), and ts_node_iterate_children().

Referenced by ts_node_first_child_for_byte(), and ts_node_first_named_child_for_byte().

◆ ts_node__is_relevant()

static bool ts_node__is_relevant ( TSNode  self,
bool  include_anonymous 
)
inlinestatic

Definition at line 106 of file node.c.

106  {
107  Subtree tree = ts_node__subtree(self);
108  if (include_anonymous) {
109  return ts_subtree_visible(tree) || ts_node__alias(&self);
110  } else {
111  TSSymbol alias = ts_node__alias(&self);
112  if (alias) {
113  return ts_language_symbol_metadata(self.tree->language, alias).named;
114  } else {
115  return ts_subtree_visible(tree) && ts_subtree_named(tree);
116  }
117  }
118 }
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:38
static Subtree ts_node__subtree(TSNode self)
Definition: node.c:48
static uint32_t ts_node__alias(const TSNode *self)
Definition: node.c:44
uint16_t TSSymbol
Definition: parser.h:19
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215

References TSSymbolMetadata::named, ts_language_symbol_metadata(), ts_node__alias(), ts_node__subtree(), ts_subtree_named(), and ts_subtree_visible().

Referenced by ts_node__child(), ts_node__descendant_for_byte_range(), ts_node__descendant_for_point_range(), ts_node__first_child_for_byte(), ts_node__next_sibling(), ts_node__prev_sibling(), ts_node_child_by_field_id(), and ts_node_parent().

◆ ts_node__next_sibling()

static TSNode ts_node__next_sibling ( TSNode  self,
bool  include_anonymous 
)
inlinestatic

Definition at line 246 of file node.c.

246  {
247  uint32_t target_end_byte = ts_node_end_byte(self);
248 
249  TSNode node = ts_node_parent(self);
250  TSNode later_node = ts_node__null();
251  bool later_node_is_relevant = false;
252 
253  while (!ts_node_is_null(node)) {
254  TSNode later_child = ts_node__null();
255  bool later_child_is_relevant = false;
256  TSNode child_containing_target = ts_node__null();
257 
258  TSNode child;
260  while (ts_node_child_iterator_next(&iterator, &child)) {
261  if (iterator.position.bytes < target_end_byte) continue;
262  if (ts_node_start_byte(child) <= ts_node_start_byte(self)) {
263  if (ts_node__subtree(child).ptr != ts_node__subtree(self).ptr) {
264  child_containing_target = child;
265  }
266  } else if (ts_node__is_relevant(child, include_anonymous)) {
267  later_child = child;
268  later_child_is_relevant = true;
269  break;
270  } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {
271  later_child = child;
272  later_child_is_relevant = false;
273  break;
274  }
275  }
276 
277  if (!ts_node_is_null(child_containing_target)) {
278  if (!ts_node_is_null(later_child)) {
279  later_node = later_child;
280  later_node_is_relevant = later_child_is_relevant;
281  }
282  node = child_containing_target;
283  } else if (later_child_is_relevant) {
284  return later_child;
285  } else if (!ts_node_is_null(later_child)) {
286  node = later_child;
287  } else if (later_node_is_relevant) {
288  return later_node;
289  } else {
290  node = later_node;
291  }
292  }
293 
294  return ts_node__null();
295 }
bool ts_node_is_null(TSNode self)
Definition: node.c:434
TSNode ts_node_parent(TSNode self)
Definition: node.c:461

References ts_node__is_relevant(), ts_node__null(), ts_node__relevant_child_count(), ts_node__subtree(), ts_node_child_iterator_next(), ts_node_end_byte(), ts_node_is_null(), ts_node_iterate_children(), ts_node_parent(), and ts_node_start_byte().

Referenced by ts_node_next_named_sibling(), and ts_node_next_sibling().

◆ ts_node__null()

static TSNode ts_node__null ( void  )
inlinestatic

Definition at line 30 of file node.c.

30  {
31  return ts_node_new(NULL, NULL, length_zero(), 0);
32 }
#define NULL
Definition: cris-opc.c:27
static Length length_zero(void)
Definition: length.h:39
TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias)
Definition: node.c:17

References length_zero(), NULL, and ts_node_new().

Referenced by ts_node__child(), ts_node__first_child_for_byte(), ts_node__next_sibling(), ts_node__prev_sibling(), ts_node_child_by_field_id(), and ts_node_parent().

◆ ts_node__prev_sibling()

static TSNode ts_node__prev_sibling ( TSNode  self,
bool  include_anonymous 
)
inlinestatic

Definition at line 187 of file node.c.

187  {
188  Subtree self_subtree = ts_node__subtree(self);
189  bool self_is_empty = ts_subtree_total_bytes(self_subtree) == 0;
190  uint32_t target_end_byte = ts_node_end_byte(self);
191 
192  TSNode node = ts_node_parent(self);
193  TSNode earlier_node = ts_node__null();
194  bool earlier_node_is_relevant = false;
195 
196  while (!ts_node_is_null(node)) {
197  TSNode earlier_child = ts_node__null();
198  bool earlier_child_is_relevant = false;
199  bool found_child_containing_target = false;
200 
201  TSNode child;
203  while (ts_node_child_iterator_next(&iterator, &child)) {
204  if (child.id == self.id) break;
205  if (iterator.position.bytes > target_end_byte) {
206  found_child_containing_target = true;
207  break;
208  }
209 
210  if (iterator.position.bytes == target_end_byte &&
211  (!self_is_empty ||
213  found_child_containing_target = true;
214  break;
215  }
216 
217  if (ts_node__is_relevant(child, include_anonymous)) {
218  earlier_child = child;
219  earlier_child_is_relevant = true;
220  } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {
221  earlier_child = child;
222  earlier_child_is_relevant = false;
223  }
224  }
225 
226  if (found_child_containing_target) {
227  if (!ts_node_is_null(earlier_child)) {
228  earlier_node = earlier_child;
229  earlier_node_is_relevant = earlier_child_is_relevant;
230  }
231  node = child;
232  } else if (earlier_child_is_relevant) {
233  return earlier_child;
234  } else if (!ts_node_is_null(earlier_child)) {
235  node = earlier_child;
236  } else if (earlier_node_is_relevant) {
237  return earlier_node;
238  } else {
239  node = earlier_node;
240  }
241  }
242 
243  return ts_node__null();
244 }
static bool ts_subtree_has_trailing_empty_descendant(Subtree self, Subtree other)
Definition: node.c:173
const void * id
Definition: api.h:94
static uint32_t ts_subtree_total_bytes(Subtree self)
Definition: subtree.h:278

References TSNode::id, ts_node__is_relevant(), ts_node__null(), ts_node__relevant_child_count(), ts_node__subtree(), ts_node_child_iterator_next(), ts_node_end_byte(), ts_node_is_null(), ts_node_iterate_children(), ts_node_parent(), ts_subtree_has_trailing_empty_descendant(), and ts_subtree_total_bytes().

Referenced by ts_node_prev_named_sibling(), and ts_node_prev_sibling().

◆ ts_node__relevant_child_count()

static uint32_t ts_node__relevant_child_count ( TSNode  self,
bool  include_anonymous 
)
inlinestatic

Definition at line 120 of file node.c.

123  {
124  Subtree tree = ts_node__subtree(self);
125  if (ts_subtree_child_count(tree) > 0) {
126  if (include_anonymous) {
127  return tree.ptr->visible_child_count;
128  } else {
129  return tree.ptr->named_child_count;
130  }
131  } else {
132  return 0;
133  }
134 }
uint32_t visible_child_count
Definition: subtree.h:135
uint32_t named_child_count
Definition: subtree.h:136
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
const SubtreeHeapData * ptr
Definition: subtree.h:158

References SubtreeHeapData::named_child_count, Subtree::ptr, ts_node__subtree(), ts_subtree_child_count(), and SubtreeHeapData::visible_child_count.

Referenced by ts_node__child(), ts_node__next_sibling(), and ts_node__prev_sibling().

◆ ts_node__subtree()

◆ ts_node_child()

TSNode ts_node_child ( TSNode  self,
uint32_t  child_index 
)

Get the node's child at the given index, where zero represents the first child.

Definition at line 492 of file node.c.

492  {
493  return ts_node__child(self, child_index, true);
494 }
static TSNode ts_node__child(TSNode self, uint32_t child_index, bool include_anonymous)
Definition: node.c:136

References ts_node__child().

Referenced by DEFINE_HANDLE_TS_FCN_AND_SYMBOL(), handle_cmd_substitution_arg(), ts_node_child_by_field_id(), and ts_node_child_wasm().

◆ ts_node_child_by_field_id()

TSNode ts_node_child_by_field_id ( TSNode  self,
TSFieldId  field_id 
)

Get the node's child with the given numerical field id.

You can convert a field name to an id using the ts_language_field_id_for_name function.

Definition at line 500 of file node.c.

500  {
501 recur:
502  if (!field_id || ts_node_child_count(self) == 0) return ts_node__null();
503 
504  const TSFieldMapEntry *field_map, *field_map_end;
506  self.tree->language,
507  ts_node__subtree(self).ptr->production_id,
508  &field_map,
509  &field_map_end
510  );
511  if (field_map == field_map_end) return ts_node__null();
512 
513  // The field mappings are sorted by their field id. Scan all
514  // the mappings to find the ones for the given field id.
515  while (field_map->field_id < field_id) {
516  field_map++;
517  if (field_map == field_map_end) return ts_node__null();
518  }
519  while (field_map_end[-1].field_id > field_id) {
520  field_map_end--;
521  if (field_map == field_map_end) return ts_node__null();
522  }
523 
524  TSNode child;
526  while (ts_node_child_iterator_next(&iterator, &child)) {
527  if (!ts_subtree_extra(ts_node__subtree(child))) {
528  uint32_t index = iterator.structural_child_index - 1;
529  if (index < field_map->child_index) continue;
530 
531  // Hidden nodes' fields are "inherited" by their visible parent.
532  if (field_map->inherited) {
533 
534  // If this is the *last* possible child node for this field,
535  // then perform a tail call to avoid recursion.
536  if (field_map + 1 == field_map_end) {
537  self = child;
538  goto recur;
539  }
540 
541  // Otherwise, descend into this child, but if it doesn't contain
542  // the field, continue searching subsequent children.
543  else {
544  TSNode result = ts_node_child_by_field_id(child, field_id);
545  if (result.id) return result;
546  field_map++;
547  if (field_map == field_map_end) return ts_node__null();
548  }
549  }
550 
551  else if (ts_node__is_relevant(child, true)) {
552  return child;
553  }
554 
555  // If the field refers to a hidden node with visible children,
556  // return the first visible child.
557  else if (ts_node_child_count(child) > 0 ) {
558  return ts_node_child(child, 0);
559  }
560 
561  // Otherwise, continue searching subsequent children.
562  else {
563  field_map++;
564  if (field_map == field_map_end) return ts_node__null();
565  }
566  }
567  }
568 
569  return ts_node__null();
570 }
static void ts_language_field_map(const TSLanguage *self, uint32_t production_id, const TSFieldMapEntry **start, const TSFieldMapEntry **end)
Definition: language.h:246
TSNode ts_node_child(TSNode self, uint32_t child_index)
Definition: node.c:492
TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id)
Definition: node.c:500
@ field_id
Definition: parser.c:1736
bool inherited
Definition: parser.h:27
TSFieldId field_id
Definition: parser.h:25
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216

References field_id, TSFieldMapEntry::field_id, TSNode::id, TSFieldMapEntry::inherited, ts_language_field_map(), ts_node__is_relevant(), ts_node__null(), ts_node__subtree(), ts_node_child(), ts_node_child_by_field_id(), ts_node_child_count(), ts_node_child_iterator_next(), ts_node_iterate_children(), and ts_subtree_extra().

Referenced by ts_node_child_by_field_id(), ts_node_child_by_field_id_wasm(), ts_node_child_by_field_name(), and ts_query_cursor__advance().

◆ ts_node_child_by_field_name()

TSNode ts_node_child_by_field_name ( TSNode  self,
const char *  field_name,
uint32_t  field_name_length 
)

Get the node's child with the given field name.

Definition at line 589 of file node.c.

593  {
595  self.tree->language,
596  name,
597  name_length
598  );
599  return ts_node_child_by_field_id(self, field_id);
600 }
TSFieldId ts_language_field_id_for_name(const TSLanguage *, const char *, uint32_t)
Definition: language.c:119
uint16_t TSFieldId
Definition: parser.h:20
Definition: z80asm.h:102

References field_id, ts_language_field_id_for_name(), and ts_node_child_by_field_id().

Referenced by DEFINE_HANDLE_TS_FCN_AND_SYMBOL(), parse_declaration_node(), parse_enum_node(), parse_parameter_declaration_node(), parse_struct_node(), parse_type_abstract_declarator_node(), parse_type_declarator_node(), parse_type_descriptor_single(), parse_typedef_node(), and parse_union_node().

◆ ts_node_child_count()

uint32_t ts_node_child_count ( TSNode  self)

Get the node's number of children.

Definition at line 602 of file node.c.

602  {
603  Subtree tree = ts_node__subtree(self);
604  if (ts_subtree_child_count(tree) > 0) {
605  return tree.ptr->visible_child_count;
606  } else {
607  return 0;
608  }
609 }

References Subtree::ptr, ts_node__subtree(), ts_subtree_child_count(), and SubtreeHeapData::visible_child_count.

Referenced by ts_node__first_child_for_byte(), ts_node_child_by_field_id(), ts_node_child_count_wasm(), and ts_node_children_wasm().

◆ ts_node_child_iterator_done()

static bool ts_node_child_iterator_done ( NodeChildIterator self)
inlinestatic

Definition at line 73 of file node.c.

73  {
74  return self->child_index == self->parent.ptr->child_count;
75 }

Referenced by ts_node_child_iterator_next().

◆ ts_node_child_iterator_next()

static bool ts_node_child_iterator_next ( NodeChildIterator self,
TSNode result 
)
inlinestatic

Definition at line 77 of file node.c.

80  {
81  if (!self->parent.ptr || ts_node_child_iterator_done(self)) return false;
82  const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];
83  TSSymbol alias_symbol = 0;
84  if (!ts_subtree_extra(*child)) {
85  if (self->alias_sequence) {
86  alias_symbol = self->alias_sequence[self->structural_child_index];
87  }
88  self->structural_child_index++;
89  }
90  if (self->child_index > 0) {
91  self->position = length_add(self->position, ts_subtree_padding(*child));
92  }
93  *result = ts_node_new(
94  self->tree,
95  child,
96  self->position,
97  alias_symbol
98  );
99  self->position = length_add(self->position, ts_subtree_size(*child));
100  self->child_index++;
101  return true;
102 }
static Length length_add(Length len1, Length len2)
Definition: length.h:25
static bool ts_node_child_iterator_done(NodeChildIterator *self)
Definition: node.c:73
uint32_t child_index
Definition: node.c:10
const TSSymbol * alias_sequence
Definition: node.c:12
Subtree parent
Definition: node.c:7
const TSTree * tree
Definition: node.c:8
Length position
Definition: node.c:9
#define ts_subtree_children(self)
Definition: subtree.h:233
static Length ts_subtree_size(Subtree self)
Definition: subtree.h:265
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256

References length_add(), ts_node_child_iterator_done(), ts_node_new(), ts_subtree_children, ts_subtree_extra(), ts_subtree_padding(), and ts_subtree_size().

Referenced by ts_node__child(), ts_node__descendant_for_byte_range(), ts_node__descendant_for_point_range(), ts_node__first_child_for_byte(), ts_node__next_sibling(), ts_node__prev_sibling(), ts_node_child_by_field_id(), and ts_node_parent().

◆ ts_node_descendant_for_byte_range()

TSNode ts_node_descendant_for_byte_range ( TSNode  self,
uint32_t  start,
uint32_t  end 
)

Get the smallest node within this node that spans the given range of bytes or (row, column) positions.

Definition at line 644 of file node.c.

648  {
649  return ts_node__descendant_for_byte_range(self, start, end, true);
650 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static TSNode ts_node__descendant_for_byte_range(TSNode self, uint32_t range_start, uint32_t range_end, bool include_anonymous)
Definition: node.c:326

References test_evm::end, start, and ts_node__descendant_for_byte_range().

Referenced by ts_node_descendant_for_index_wasm().

◆ ts_node_descendant_for_point_range()

TSNode ts_node_descendant_for_point_range ( TSNode  self,
TSPoint  start,
TSPoint  end 
)

Definition at line 660 of file node.c.

664  {
665  return ts_node__descendant_for_point_range(self, start, end, true);
666 }
static TSNode ts_node__descendant_for_point_range(TSNode self, TSPoint range_start, TSPoint range_end, bool include_anonymous)
Definition: node.c:365

References test_evm::end, start, and ts_node__descendant_for_point_range().

Referenced by ts_node_descendant_for_position_wasm().

◆ ts_node_edit()

void ts_node_edit ( TSNode self,
const TSInputEdit edit 
)

Edit the node to keep it in-sync with source code that has been edited.

This function is only rarely needed. When you edit a syntax tree with the ts_tree_edit function, all of the nodes that you retrieve from the tree afterward will already reflect the edit. You only need to use ts_node_edit when you have a TSNode instance that you want to keep and continue to use after an edit.

Definition at line 676 of file node.c.

676  {
677  uint32_t start_byte = ts_node_start_byte(*self);
678  TSPoint start_point = ts_node_start_point(*self);
679 
680  if (start_byte >= edit->old_end_byte) {
681  start_byte = edit->new_end_byte + (start_byte - edit->old_end_byte);
682  start_point = point_add(edit->new_end_point, point_sub(start_point, edit->old_end_point));
683  } else if (start_byte > edit->start_byte) {
684  start_byte = edit->new_end_byte;
685  start_point = edit->new_end_point;
686  }
687 
688  self->context[0] = start_byte;
689  self->context[1] = start_point.row;
690  self->context[2] = start_point.column;
691 }
static TSPoint point_sub(TSPoint a, TSPoint b)
Definition: point.h:21
static TSPoint point_add(TSPoint a, TSPoint b)
Definition: point.h:14
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 new_end_point
Definition: api.h:89
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57

References TSPoint::column, TSInputEdit::new_end_byte, TSInputEdit::new_end_point, TSInputEdit::old_end_byte, TSInputEdit::old_end_point, point_add(), point_sub(), TSPoint::row, TSInputEdit::start_byte, ts_node_start_byte(), and ts_node_start_point().

◆ ts_node_end_byte()

◆ ts_node_end_point()

TSPoint ts_node_end_point ( TSNode  self)

◆ ts_node_eq()

bool ts_node_eq ( TSNode  self,
TSNode  other 
)

Check if two nodes are identical.

Definition at line 430 of file node.c.

430  {
431  return self.tree == other.tree && self.id == other.id;
432 }
const TSTree * tree
Definition: api.h:95

References TSNode::id, and TSNode::tree.

◆ ts_node_field_name_for_child()

const char* ts_node_field_name_for_child ( TSNode  self,
uint32_t  child_index 
)

Get the field name for node's child at the given index, where zero represents the first child. Returns NULL, if no field is found.

Definition at line 572 of file node.c.

572  {
573  const TSFieldMapEntry *field_map_start = NULL, *field_map_end = NULL;
575  self.tree->language,
576  ts_node__subtree(self).ptr->production_id,
577  &field_map_start,
578  &field_map_end
579  );
580 
581  for (const TSFieldMapEntry *i = field_map_start; i < field_map_end; i++) {
582  if (i->child_index == child_index) {
583  return self.tree->language->field_names[i->field_id];
584  }
585  }
586  return NULL;
587 }
lzma_index ** i
Definition: index.h:629

References i, NULL, ts_language_field_map(), and ts_node__subtree().

◆ ts_node_first_child_for_byte()

TSNode ts_node_first_child_for_byte ( TSNode  self,
uint32_t  byte 
)

Get the node's first child that extends beyond the given byte offset.

Definition at line 636 of file node.c.

636  {
637  return ts_node__first_child_for_byte(self, byte, true);
638 }
static TSNode ts_node__first_child_for_byte(TSNode self, uint32_t goal, bool include_anonymous)
Definition: node.c:297

References ts_node__first_child_for_byte().

◆ ts_node_first_named_child_for_byte()

TSNode ts_node_first_named_child_for_byte ( TSNode  self,
uint32_t  byte 
)

Get the node's first named child that extends beyond the given byte offset.

Definition at line 640 of file node.c.

640  {
641  return ts_node__first_child_for_byte(self, byte, false);
642 }

References ts_node__first_child_for_byte().

◆ ts_node_has_changes()

bool ts_node_has_changes ( TSNode  self)

Check if a syntax node has been edited.

Definition at line 453 of file node.c.

453  {
455 }
static bool ts_subtree_has_changes(Subtree self)
Definition: subtree.h:217

References ts_node__subtree(), and ts_subtree_has_changes().

Referenced by ts_node_has_changes_wasm().

◆ ts_node_has_error()

bool ts_node_has_error ( TSNode  self)

Check if the node is a syntax error or contains any syntax errors.

Definition at line 457 of file node.c.

457  {
458  return ts_subtree_error_cost(ts_node__subtree(self)) > 0;
459 }
static uint32_t ts_subtree_error_cost(Subtree self)
Definition: subtree.h:302

References ts_node__subtree(), and ts_subtree_error_cost().

Referenced by core_cmd_tsrzcmd(), find_autocmplt_type_quoted_arg(), substitute_args_do(), and ts_node_has_error_wasm().

◆ ts_node_is_extra()

bool ts_node_is_extra ( TSNode  self)

Check if the node is extra. Extra nodes represent things like comments, which are not required the grammar, but can appear anywhere.

Definition at line 438 of file node.c.

438  {
439  return ts_subtree_extra(ts_node__subtree(self));
440 }

References ts_node__subtree(), and ts_subtree_extra().

◆ ts_node_is_missing()

bool ts_node_is_missing ( TSNode  self)

Check if the node is missing. Missing nodes are inserted by the parser in order to recover from certain kinds of syntax errors.

Definition at line 449 of file node.c.

449  {
450  return ts_subtree_missing(ts_node__subtree(self));
451 }
static bool ts_subtree_missing(Subtree self)
Definition: subtree.h:218

References ts_node__subtree(), and ts_subtree_missing().

Referenced by ts_node_is_missing_wasm(), and ts_tree_cursor_current_node_is_missing_wasm().

◆ ts_node_is_named()

◆ ts_node_is_null()

◆ ts_node_iterate_children()

static NodeChildIterator ts_node_iterate_children ( const TSNode node)
inlinestatic

Definition at line 54 of file node.c.

54  {
55  Subtree subtree = ts_node__subtree(*node);
56  if (ts_subtree_child_count(subtree) == 0) {
57  return (NodeChildIterator) {NULL_SUBTREE, node->tree, length_zero(), 0, 0, NULL};
58  }
59  const TSSymbol *alias_sequence = ts_language_alias_sequence(
60  node->tree->language,
61  subtree.ptr->production_id
62  );
63  return (NodeChildIterator) {
64  .tree = node->tree,
65  .parent = subtree,
66  .position = {ts_node_start_byte(*node), ts_node_start_point(*node)},
67  .child_index = 0,
68  .structural_child_index = 0,
69  .alias_sequence = alias_sequence,
70  };
71 }
static const TSSymbol * ts_language_alias_sequence(const TSLanguage *self, uint32_t production_id)
Definition: language.h:227
uint16_t production_id
Definition: subtree.h:140
const TSLanguage * language
Definition: tree.h:17
#define NULL_SUBTREE
Definition: subtree.h:19

References TSTree::language, length_zero(), NULL, NULL_SUBTREE, SubtreeHeapData::production_id, Subtree::ptr, TSNode::tree, ts_language_alias_sequence(), ts_node__subtree(), ts_node_start_byte(), ts_node_start_point(), and ts_subtree_child_count().

Referenced by ts_node__child(), ts_node__descendant_for_byte_range(), ts_node__descendant_for_point_range(), ts_node__first_child_for_byte(), ts_node__next_sibling(), ts_node__prev_sibling(), ts_node_child_by_field_id(), and ts_node_parent().

◆ ts_node_named_child()

◆ ts_node_named_child_count()

◆ ts_node_named_descendant_for_byte_range()

TSNode ts_node_named_descendant_for_byte_range ( TSNode  self,
uint32_t  start,
uint32_t  end 
)

Get the smallest named node within this node that spans the given range of bytes or (row, column) positions.

Definition at line 652 of file node.c.

656  {
657  return ts_node__descendant_for_byte_range(self, start, end, false);
658 }

References test_evm::end, start, and ts_node__descendant_for_byte_range().

Referenced by guess_next_autocmplt_token(), and ts_node_named_descendant_for_index_wasm().

◆ ts_node_named_descendant_for_point_range()

TSNode ts_node_named_descendant_for_point_range ( TSNode  self,
TSPoint  start,
TSPoint  end 
)

Definition at line 668 of file node.c.

672  {
673  return ts_node__descendant_for_point_range(self, start, end, false);
674 }

References test_evm::end, start, and ts_node__descendant_for_point_range().

Referenced by ts_node_named_descendant_for_position_wasm().

◆ ts_node_new()

TSNode ts_node_new ( const TSTree tree,
const Subtree subtree,
Length  position,
TSSymbol  alias 
)

Definition at line 17 of file node.c.

22  {
23  return (TSNode) {
24  {position.bytes, position.extent.row, position.extent.column, alias},
25  subtree,
26  tree,
27  };
28 }
TSPoint extent
Definition: length.h:11

References Length::bytes, TSPoint::column, Length::extent, and TSPoint::row.

Referenced by ts_node__null(), ts_node_child_iterator_next(), ts_tree_cursor_current_node(), ts_tree_cursor_parent_node(), and ts_tree_root_node().

◆ ts_node_next_named_sibling()

TSNode ts_node_next_named_sibling ( TSNode  self)

Get the node's next / previous named sibling.

Definition at line 624 of file node.c.

624  {
625  return ts_node__next_sibling(self, false);
626 }
static TSNode ts_node__next_sibling(TSNode self, bool include_anonymous)
Definition: node.c:246

References ts_node__next_sibling().

Referenced by parse_struct_node(), parse_union_node(), and ts_node_next_named_sibling_wasm().

◆ ts_node_next_sibling()

TSNode ts_node_next_sibling ( TSNode  self)

Get the node's next / previous sibling.

Definition at line 620 of file node.c.

620  {
621  return ts_node__next_sibling(self, true);
622 }

References ts_node__next_sibling().

Referenced by ts_node_next_sibling_wasm().

◆ ts_node_parent()

TSNode ts_node_parent ( TSNode  self)

Get the node's immediate parent.

Definition at line 461 of file node.c.

461  {
462  TSNode node = ts_tree_root_node(self.tree);
463  uint32_t end_byte = ts_node_end_byte(self);
464  if (node.id == self.id) return ts_node__null();
465 
466  TSNode last_visible_node = node;
467  bool did_descend = true;
468  while (did_descend) {
469  did_descend = false;
470 
471  TSNode child;
473  while (ts_node_child_iterator_next(&iterator, &child)) {
474  if (
475  ts_node_start_byte(child) > ts_node_start_byte(self) ||
476  child.id == self.id
477  ) break;
478  if (iterator.position.bytes >= end_byte) {
479  node = child;
480  if (ts_node__is_relevant(child, true)) {
481  last_visible_node = node;
482  }
483  did_descend = true;
484  break;
485  }
486  }
487  }
488 
489  return last_visible_node;
490 }
TSNode ts_tree_root_node(const TSTree *self)
Definition: tree.c:36

References TSNode::id, ts_node__is_relevant(), ts_node__null(), ts_node_child_iterator_next(), ts_node_end_byte(), ts_node_iterate_children(), ts_node_start_byte(), and ts_tree_root_node().

Referenced by get_arg_number(), get_arg_parent(), get_cd_from_arg(), handle_cmd_substitution_arg(), ts_node__next_sibling(), ts_node__prev_sibling(), and ts_node_parent_wasm().

◆ ts_node_prev_named_sibling()

TSNode ts_node_prev_named_sibling ( TSNode  self)

Definition at line 632 of file node.c.

632  {
633  return ts_node__prev_sibling(self, false);
634 }
static TSNode ts_node__prev_sibling(TSNode self, bool include_anonymous)
Definition: node.c:187

References ts_node__prev_sibling().

Referenced by ts_node_prev_named_sibling_wasm().

◆ ts_node_prev_sibling()

TSNode ts_node_prev_sibling ( TSNode  self)

Definition at line 628 of file node.c.

628  {
629  return ts_node__prev_sibling(self, true);
630 }

References ts_node__prev_sibling().

Referenced by get_arg_number(), and ts_node_prev_sibling_wasm().

◆ ts_node_start_byte()

◆ ts_node_start_point()

TSPoint ts_node_start_point ( TSNode  self)

Get the node's start position in terms of rows and columns.

Definition at line 40 of file node.c.

40  {
41  return (TSPoint) {self.context[1], self.context[2]};
42 }

Referenced by create_cmd_edit(), ts_node__descendant_for_point_range(), ts_node_descendants_of_type_wasm(), ts_node_edit(), ts_node_end_point(), ts_node_iterate_children(), ts_node_start_point_wasm(), ts_query_cursor__advance(), and ts_tree_cursor_start_position_wasm().

◆ ts_node_string()

char* ts_node_string ( TSNode  self)

Get an S-expression representing the node as a string.

This string is allocated with malloc and the caller is responsible for freeing it using free.

Definition at line 426 of file node.c.

426  {
427  return ts_subtree_string(ts_node__subtree(self), self.tree->language, false);
428 }
char * ts_subtree_string(Subtree self, const TSLanguage *language, bool include_all)
Definition: subtree.c:947

References ts_node__subtree(), and ts_subtree_string().

Referenced by core_cmd_tsrzcmd(), node_malformed_error(), parse_enum_node(), parse_struct_node(), parse_typedef_node(), parse_union_node(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), ts_node_to_string_wasm(), and type_parse_string().

◆ ts_node_symbol()

TSSymbol ts_node_symbol ( TSNode  self)

Get the node's type as a numerical id.

Definition at line 414 of file node.c.

414  {
415  TSSymbol symbol = ts_node__alias(&self);
416  if (!symbol) symbol = ts_subtree_symbol(ts_node__subtree(self));
417  return ts_language_public_symbol(self.tree->language, symbol);
418 }
TSSymbol ts_language_public_symbol(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:51
static TSSymbol ts_subtree_symbol(Subtree self)
Definition: subtree.h:213

References ts_language_public_symbol(), ts_node__alias(), ts_node__subtree(), and ts_subtree_symbol().

Referenced by handle_ts_stmt(), ts_node_descendants_of_type_wasm(), ts_node_symbol_wasm(), ts_query_cursor__advance(), and ts_tree_cursor_current_node_type_id_wasm().

◆ ts_node_type()

◆ ts_subtree_has_trailing_empty_descendant()

static bool ts_subtree_has_trailing_empty_descendant ( Subtree  self,
Subtree  other 
)
static

Definition at line 173 of file node.c.

176  {
177  for (unsigned i = ts_subtree_child_count(self) - 1; i + 1 > 0; i--) {
178  Subtree child = ts_subtree_children(self)[i];
179  if (ts_subtree_total_bytes(child) > 0) break;
180  if (child.ptr == other.ptr || ts_subtree_has_trailing_empty_descendant(child, other)) {
181  return true;
182  }
183  }
184  return false;
185 }

References i, Subtree::ptr, ts_subtree_child_count(), ts_subtree_children, and ts_subtree_total_bytes().

Referenced by ts_node__prev_sibling().