Rizin
unix-like reverse engineering framework and cli tools
tree_cursor.h File Reference
#include "./subtree.h"

Go to the source code of this file.

Classes

struct  TreeCursorEntry
 
struct  TreeCursor
 

Functions

void ts_tree_cursor_init (TreeCursor *, TSNode)
 
void ts_tree_cursor_current_status (const TSTreeCursor *, TSFieldId *, bool *, bool *, bool *, TSSymbol *, unsigned *)
 
TSNode ts_tree_cursor_parent_node (const TSTreeCursor *)
 

Function Documentation

◆ ts_tree_cursor_current_status()

void ts_tree_cursor_current_status ( const TSTreeCursor _self,
TSFieldId field_id,
bool has_later_siblings,
bool has_later_named_siblings,
bool can_have_later_siblings_with_this_field,
TSSymbol supertypes,
unsigned supertype_count 
)

Definition at line 284 of file tree_cursor.c.

292  {
293  const TreeCursor *self = (const TreeCursor *)_self;
294  unsigned max_supertypes = *supertype_count;
295  *field_id = 0;
296  *supertype_count = 0;
297  *has_later_siblings = false;
298  *has_later_named_siblings = false;
299  *can_have_later_siblings_with_this_field = false;
300 
301  // Walk up the tree, visiting the current node and its invisible ancestors,
302  // because fields can refer to nodes through invisible *wrapper* nodes,
303  for (unsigned i = self->stack.size - 1; i > 0; i--) {
304  TreeCursorEntry *entry = &self->stack.contents[i];
305  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
306 
307  const TSSymbol *alias_sequence = ts_language_alias_sequence(
308  self->tree->language,
309  parent_entry->subtree->ptr->production_id
310  );
311 
312  #define subtree_symbol(subtree, structural_child_index) \
313  (( \
314  !ts_subtree_extra(subtree) && \
315  alias_sequence && \
316  alias_sequence[structural_child_index] \
317  ) ? \
318  alias_sequence[structural_child_index] : \
319  ts_subtree_symbol(subtree))
320 
321  // Stop walking up when a visible ancestor is found.
322  TSSymbol entry_symbol = subtree_symbol(
323  *entry->subtree,
324  entry->structural_child_index
325  );
327  self->tree->language,
328  entry_symbol
329  );
330  if (i != self->stack.size - 1 && entry_metadata.visible) break;
331 
332  // Record any supertypes
333  if (entry_metadata.supertype && *supertype_count < max_supertypes) {
334  supertypes[*supertype_count] = entry_symbol;
335  (*supertype_count)++;
336  }
337 
338  // Determine if the current node has later siblings.
339  if (!*has_later_siblings) {
340  unsigned sibling_count = parent_entry->subtree->ptr->child_count;
341  unsigned structural_child_index = entry->structural_child_index;
342  if (!ts_subtree_extra(*entry->subtree)) structural_child_index++;
343  for (unsigned j = entry->child_index + 1; j < sibling_count; j++) {
344  Subtree sibling = ts_subtree_children(*parent_entry->subtree)[j];
346  self->tree->language,
347  subtree_symbol(sibling, structural_child_index)
348  );
349  if (sibling_metadata.visible) {
350  *has_later_siblings = true;
351  if (*has_later_named_siblings) break;
352  if (sibling_metadata.named) {
353  *has_later_named_siblings = true;
354  break;
355  }
356  } else if (ts_subtree_visible_child_count(sibling) > 0) {
357  *has_later_siblings = true;
358  if (*has_later_named_siblings) break;
359  if (sibling.ptr->named_child_count > 0) {
360  *has_later_named_siblings = true;
361  break;
362  }
363  }
364  if (!ts_subtree_extra(sibling)) structural_child_index++;
365  }
366  }
367 
368  #undef subtree_symbol
369 
370  if (!ts_subtree_extra(*entry->subtree)) {
371  const TSFieldMapEntry *field_map, *field_map_end;
373  self->tree->language,
374  parent_entry->subtree->ptr->production_id,
375  &field_map, &field_map_end
376  );
377 
378  // Look for a field name associated with the current node.
379  if (!*field_id) {
380  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
381  if (!i->inherited && i->child_index == entry->structural_child_index) {
382  *field_id = i->field_id;
383  break;
384  }
385  }
386  }
387 
388  // Determine if the current node can have later siblings with the same field name.
389  if (*field_id) {
390  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
391  if (
392  i->field_id == *field_id &&
393  i->child_index > entry->structural_child_index
394  ) {
395  *can_have_later_siblings_with_this_field = true;
396  break;
397  }
398  }
399  }
400  }
401  }
402 }
lzma_index ** i
Definition: index.h:629
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:38
static void ts_language_field_map(const TSLanguage *self, uint32_t production_id, const TSFieldMapEntry **start, const TSFieldMapEntry **end)
Definition: language.h:246
static const TSSymbol * ts_language_alias_sequence(const TSLanguage *self, uint32_t production_id)
Definition: language.h:227
@ field_id
Definition: parser.c:1736
uint16_t TSSymbol
Definition: parser.h:19
uint32_t named_child_count
Definition: subtree.h:136
uint32_t child_count
Definition: subtree.h:117
uint16_t production_id
Definition: subtree.h:140
bool visible
Definition: parser.h:36
bool supertype
Definition: parser.h:38
const Subtree * subtree
Definition: tree_cursor.h:7
Definition: zipcmp.c:77
#define ts_subtree_children(self)
Definition: subtree.h:233
static bool ts_subtree_extra(Subtree self)
Definition: subtree.h:216
static uint32_t ts_subtree_visible_child_count(Subtree self)
Definition: subtree.h:294
#define subtree_symbol(subtree, structural_child_index)
const SubtreeHeapData * ptr
Definition: subtree.h:158

References SubtreeHeapData::child_count, field_id, i, TSSymbolMetadata::named, SubtreeHeapData::named_child_count, SubtreeHeapData::production_id, Subtree::ptr, TreeCursorEntry::subtree, subtree_symbol, TSSymbolMetadata::supertype, ts_language_alias_sequence(), ts_language_field_map(), ts_language_symbol_metadata(), ts_subtree_children, ts_subtree_extra(), ts_subtree_visible_child_count(), and TSSymbolMetadata::visible.

Referenced by ts_query_cursor__advance().

◆ ts_tree_cursor_init()

void ts_tree_cursor_init ( TreeCursor self,
TSNode  node 
)

Definition at line 80 of file tree_cursor.c.

80  {
81  self->tree = node.tree;
82  array_clear(&self->stack);
83  array_push(&self->stack, ((TreeCursorEntry) {
84  .subtree = (const Subtree *)node.id,
85  .position = {
86  ts_node_start_byte(node),
87  ts_node_start_point(node)
88  },
89  .child_index = 0,
90  .structural_child_index = 0,
91  }));
92 }
#define array_push(self, element)
Definition: array.h:43
#define array_clear(self)
Definition: array.h:35
const TSTree * tree
Definition: api.h:95

References array_clear, array_push, and TSNode::tree.

Referenced by ts_tree_cursor_new(), ts_tree_cursor_reset(), and ts_tree_get_changed_ranges().

◆ ts_tree_cursor_parent_node()

TSNode ts_tree_cursor_parent_node ( const TSTreeCursor _self)

Definition at line 404 of file tree_cursor.c.

404  {
405  const TreeCursor *self = (const TreeCursor *)_self;
406  for (int i = (int)self->stack.size - 2; i >= 0; i--) {
407  TreeCursorEntry *entry = &self->stack.contents[i];
408  bool is_visible = true;
409  TSSymbol alias_symbol = 0;
410  if (i > 0) {
411  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
412  alias_symbol = ts_language_alias_at(
413  self->tree->language,
414  parent_entry->subtree->ptr->production_id,
415  entry->structural_child_index
416  );
417  is_visible = (alias_symbol != 0) || ts_subtree_visible(*entry->subtree);
418  }
419  if (is_visible) {
420  return ts_node_new(
421  self->tree,
422  entry->subtree,
423  entry->position,
424  alias_symbol
425  );
426  }
427  }
428  return ts_node_new(NULL, NULL, length_zero(), 0);
429 }
#define NULL
Definition: cris-opc.c:27
static TSSymbol ts_language_alias_at(const TSLanguage *self, uint32_t production_id, uint32_t child_index)
Definition: language.h:236
static Length length_zero(void)
Definition: length.h:39
TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias)
Definition: node.c:17
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214

References i, length_zero(), NULL, SubtreeHeapData::production_id, Subtree::ptr, TreeCursorEntry::subtree, ts_language_alias_at(), ts_node_new(), and ts_subtree_visible().

Referenced by ts_query_cursor__advance().