Rizin
unix-like reverse engineering framework and cli tools
api.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

Go to the source code of this file.

Classes

struct  TSPoint
 
struct  TSRange
 
struct  TSInput
 
struct  TSLogger
 
struct  TSInputEdit
 
struct  TSNode
 
struct  TSTreeCursor
 
struct  TSQueryCapture
 
struct  TSQueryMatch
 
struct  TSQueryPredicateStep
 

Macros

#define TREE_SITTER_LANGUAGE_VERSION   14
 
#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION   13
 

Typedefs

typedef uint16_t TSSymbol
 
typedef uint16_t TSFieldId
 
typedef struct TSLanguage TSLanguage
 
typedef struct TSParser TSParser
 
typedef struct TSTree TSTree
 
typedef struct TSQuery TSQuery
 
typedef struct TSQueryCursor TSQueryCursor
 

Enumerations

enum  TSInputEncoding { TSInputEncodingUTF8 , TSInputEncodingUTF16 }
 
enum  TSSymbolType { TSSymbolTypeRegular , TSSymbolTypeAnonymous , TSSymbolTypeAuxiliary }
 
enum  TSLogType { TSLogTypeParse , TSLogTypeLex }
 
enum  TSQuantifier {
  TSQuantifierZero = 0 , TSQuantifierZeroOrOne , TSQuantifierZeroOrMore , TSQuantifierOne ,
  TSQuantifierOneOrMore
}
 
enum  TSQueryPredicateStepType { TSQueryPredicateStepTypeDone , TSQueryPredicateStepTypeCapture , TSQueryPredicateStepTypeString }
 
enum  TSQueryError {
  TSQueryErrorNone = 0 , TSQueryErrorSyntax , TSQueryErrorNodeType , TSQueryErrorField ,
  TSQueryErrorCapture , TSQueryErrorStructure , TSQueryErrorLanguage
}
 

Functions

TSParserts_parser_new (void)
 
void ts_parser_delete (TSParser *parser)
 
bool ts_parser_set_language (TSParser *self, const TSLanguage *language)
 
const TSLanguagets_parser_language (const TSParser *self)
 
bool ts_parser_set_included_ranges (TSParser *self, const TSRange *ranges, uint32_t length)
 
const TSRangets_parser_included_ranges (const TSParser *self, uint32_t *length)
 
TSTreets_parser_parse (TSParser *self, const TSTree *old_tree, TSInput input)
 
TSTreets_parser_parse_string (TSParser *self, const TSTree *old_tree, const char *string, uint32_t length)
 
TSTreets_parser_parse_string_encoding (TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding)
 
void ts_parser_reset (TSParser *self)
 
void ts_parser_set_timeout_micros (TSParser *self, uint64_t timeout)
 
uint64_t ts_parser_timeout_micros (const TSParser *self)
 
void ts_parser_set_cancellation_flag (TSParser *self, const size_t *flag)
 
const size_tts_parser_cancellation_flag (const TSParser *self)
 
void ts_parser_set_logger (TSParser *self, TSLogger logger)
 
TSLogger ts_parser_logger (const TSParser *self)
 
void ts_parser_print_dot_graphs (TSParser *self, int file)
 
TSTreets_tree_copy (const TSTree *self)
 
void ts_tree_delete (TSTree *self)
 
TSNode ts_tree_root_node (const TSTree *self)
 
const TSLanguagets_tree_language (const TSTree *)
 
void ts_tree_edit (TSTree *self, const TSInputEdit *edit)
 
TSRangets_tree_get_changed_ranges (const TSTree *old_tree, const TSTree *new_tree, uint32_t *length)
 
void ts_tree_print_dot_graph (const TSTree *, FILE *)
 
const char * ts_node_type (TSNode)
 
TSSymbol ts_node_symbol (TSNode)
 
uint32_t ts_node_start_byte (TSNode)
 
TSPoint ts_node_start_point (TSNode)
 
uint32_t ts_node_end_byte (TSNode)
 
TSPoint ts_node_end_point (TSNode)
 
char * ts_node_string (TSNode)
 
bool ts_node_is_null (TSNode)
 
bool ts_node_is_named (TSNode)
 
bool ts_node_is_missing (TSNode)
 
bool ts_node_is_extra (TSNode)
 
bool ts_node_has_changes (TSNode)
 
bool ts_node_has_error (TSNode)
 
TSNode ts_node_parent (TSNode)
 
TSNode ts_node_child (TSNode, uint32_t)
 
const char * ts_node_field_name_for_child (TSNode, uint32_t)
 
uint32_t ts_node_child_count (TSNode)
 
TSNode ts_node_named_child (TSNode, uint32_t)
 
uint32_t ts_node_named_child_count (TSNode)
 
TSNode ts_node_child_by_field_name (TSNode self, const char *field_name, uint32_t field_name_length)
 
TSNode ts_node_child_by_field_id (TSNode, TSFieldId)
 
TSNode ts_node_next_sibling (TSNode)
 
TSNode ts_node_prev_sibling (TSNode)
 
TSNode ts_node_next_named_sibling (TSNode)
 
TSNode ts_node_prev_named_sibling (TSNode)
 
TSNode ts_node_first_child_for_byte (TSNode, uint32_t)
 
TSNode ts_node_first_named_child_for_byte (TSNode, uint32_t)
 
TSNode ts_node_descendant_for_byte_range (TSNode, uint32_t, uint32_t)
 
TSNode ts_node_descendant_for_point_range (TSNode, TSPoint, TSPoint)
 
TSNode ts_node_named_descendant_for_byte_range (TSNode, uint32_t, uint32_t)
 
TSNode ts_node_named_descendant_for_point_range (TSNode, TSPoint, TSPoint)
 
void ts_node_edit (TSNode *, const TSInputEdit *)
 
bool ts_node_eq (TSNode, TSNode)
 
TSTreeCursor ts_tree_cursor_new (TSNode)
 
void ts_tree_cursor_delete (TSTreeCursor *)
 
void ts_tree_cursor_reset (TSTreeCursor *, TSNode)
 
TSNode ts_tree_cursor_current_node (const TSTreeCursor *)
 
const char * ts_tree_cursor_current_field_name (const TSTreeCursor *)
 
TSFieldId ts_tree_cursor_current_field_id (const TSTreeCursor *)
 
bool ts_tree_cursor_goto_parent (TSTreeCursor *)
 
bool ts_tree_cursor_goto_next_sibling (TSTreeCursor *)
 
bool ts_tree_cursor_goto_first_child (TSTreeCursor *)
 
int64_t ts_tree_cursor_goto_first_child_for_byte (TSTreeCursor *, uint32_t)
 
int64_t ts_tree_cursor_goto_first_child_for_point (TSTreeCursor *, TSPoint)
 
TSTreeCursor ts_tree_cursor_copy (const TSTreeCursor *)
 
TSQueryts_query_new (const TSLanguage *language, const char *source, uint32_t source_len, uint32_t *error_offset, TSQueryError *error_type)
 
void ts_query_delete (TSQuery *)
 
uint32_t ts_query_pattern_count (const TSQuery *)
 
uint32_t ts_query_capture_count (const TSQuery *)
 
uint32_t ts_query_string_count (const TSQuery *)
 
uint32_t ts_query_start_byte_for_pattern (const TSQuery *, uint32_t)
 
const TSQueryPredicateStepts_query_predicates_for_pattern (const TSQuery *self, uint32_t pattern_index, uint32_t *length)
 
bool ts_query_is_pattern_guaranteed_at_step (const TSQuery *self, uint32_t byte_offset)
 
const char * ts_query_capture_name_for_id (const TSQuery *, uint32_t id, uint32_t *length)
 
TSQuantifier ts_query_capture_quantifier_for_id (const TSQuery *, uint32_t pattern_id, uint32_t capture_id)
 
const char * ts_query_string_value_for_id (const TSQuery *, uint32_t id, uint32_t *length)
 
void ts_query_disable_capture (TSQuery *, const char *, uint32_t)
 
void ts_query_disable_pattern (TSQuery *, uint32_t)
 
TSQueryCursorts_query_cursor_new (void)
 
void ts_query_cursor_delete (TSQueryCursor *)
 
void ts_query_cursor_exec (TSQueryCursor *, const TSQuery *, TSNode)
 
bool ts_query_cursor_did_exceed_match_limit (const TSQueryCursor *)
 
uint32_t ts_query_cursor_match_limit (const TSQueryCursor *)
 
void ts_query_cursor_set_match_limit (TSQueryCursor *, uint32_t)
 
void ts_query_cursor_set_byte_range (TSQueryCursor *, uint32_t, uint32_t)
 
void ts_query_cursor_set_point_range (TSQueryCursor *, TSPoint, TSPoint)
 
bool ts_query_cursor_next_match (TSQueryCursor *, TSQueryMatch *match)
 
void ts_query_cursor_remove_match (TSQueryCursor *, uint32_t id)
 
bool ts_query_cursor_next_capture (TSQueryCursor *, TSQueryMatch *match, uint32_t *capture_index)
 
uint32_t ts_language_symbol_count (const TSLanguage *)
 
const char * ts_language_symbol_name (const TSLanguage *, TSSymbol)
 
TSSymbol ts_language_symbol_for_name (const TSLanguage *self, const char *string, uint32_t length, bool is_named)
 
uint32_t ts_language_field_count (const TSLanguage *)
 
const char * ts_language_field_name_for_id (const TSLanguage *, TSFieldId)
 
TSFieldId ts_language_field_id_for_name (const TSLanguage *, const char *, uint32_t)
 
TSSymbolType ts_language_symbol_type (const TSLanguage *, TSSymbol)
 
uint32_t ts_language_version (const TSLanguage *)
 
void ts_set_allocator (void *(*new_malloc)(size_t), void *(*new_calloc)(size_t, size_t), void *(*new_realloc)(void *, size_t), void(*new_free)(void *))
 

Macro Definition Documentation

◆ TREE_SITTER_LANGUAGE_VERSION

#define TREE_SITTER_LANGUAGE_VERSION   14

The latest ABI version that is supported by the current version of the library. When Languages are generated by the Tree-sitter CLI, they are assigned an ABI version number that corresponds to the current CLI version. The Tree-sitter library is generally backwards-compatible with languages generated using older CLI versions, but is not forwards-compatible.

Definition at line 24 of file api.h.

◆ TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION

#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION   13

The earliest ABI version that is supported by the current version of the library.

Definition at line 30 of file api.h.

Typedef Documentation

◆ TSFieldId

Definition at line 37 of file api.h.

◆ TSLanguage

typedef struct TSLanguage TSLanguage

Definition at line 37 of file api.h.

◆ TSParser

typedef struct TSParser TSParser

Definition at line 37 of file api.h.

◆ TSQuery

typedef struct TSQuery TSQuery

Definition at line 37 of file api.h.

◆ TSQueryCursor

typedef struct TSQueryCursor TSQueryCursor

Definition at line 37 of file api.h.

◆ TSSymbol

typedef uint16_t TSSymbol

Definition at line 36 of file api.h.

◆ TSTree

typedef struct TSTree TSTree

Definition at line 37 of file api.h.

Enumeration Type Documentation

◆ TSInputEncoding

Enumerator
TSInputEncodingUTF8 
TSInputEncodingUTF16 

Definition at line 44 of file api.h.

44  {
TSInputEncoding
Definition: api.h:44
@ TSInputEncodingUTF16
Definition: api.h:46
@ TSInputEncodingUTF8
Definition: api.h:45

◆ TSLogType

enum TSLogType
Enumerator
TSLogTypeParse 
TSLogTypeLex 

Definition at line 73 of file api.h.

73  {
76 } TSLogType;
TSLogType
Definition: api.h:73
@ TSLogTypeLex
Definition: api.h:75
@ TSLogTypeParse
Definition: api.h:74

◆ TSQuantifier

Enumerator
TSQuantifierZero 
TSQuantifierZeroOrOne 
TSQuantifierZeroOrMore 
TSQuantifierOne 
TSQuantifierOneOrMore 

Definition at line 109 of file api.h.

109  {
110  TSQuantifierZero = 0, // must match the array initialization value
115 } TSQuantifier;
TSQuantifier
Definition: api.h:109
@ TSQuantifierZeroOrMore
Definition: api.h:112
@ TSQuantifierZeroOrOne
Definition: api.h:111
@ TSQuantifierZero
Definition: api.h:110
@ TSQuantifierOneOrMore
Definition: api.h:114
@ TSQuantifierOne
Definition: api.h:113

◆ TSQueryError

Enumerator
TSQueryErrorNone 
TSQueryErrorSyntax 
TSQueryErrorNodeType 
TSQueryErrorField 
TSQueryErrorCapture 
TSQueryErrorStructure 
TSQueryErrorLanguage 

Definition at line 135 of file api.h.

135  {
136  TSQueryErrorNone = 0,
143 } TSQueryError;
TSQueryError
Definition: api.h:135
@ TSQueryErrorLanguage
Definition: api.h:142
@ TSQueryErrorSyntax
Definition: api.h:137
@ TSQueryErrorNodeType
Definition: api.h:138
@ TSQueryErrorNone
Definition: api.h:136
@ TSQueryErrorField
Definition: api.h:139
@ TSQueryErrorStructure
Definition: api.h:141
@ TSQueryErrorCapture
Definition: api.h:140

◆ TSQueryPredicateStepType

Enumerator
TSQueryPredicateStepTypeDone 
TSQueryPredicateStepTypeCapture 
TSQueryPredicateStepTypeString 

Definition at line 124 of file api.h.

124  {
TSQueryPredicateStepType
Definition: api.h:124
@ TSQueryPredicateStepTypeString
Definition: api.h:127
@ TSQueryPredicateStepTypeDone
Definition: api.h:125
@ TSQueryPredicateStepTypeCapture
Definition: api.h:126

◆ TSSymbolType

Enumerator
TSSymbolTypeRegular 
TSSymbolTypeAnonymous 
TSSymbolTypeAuxiliary 

Definition at line 49 of file api.h.

49  {
53 } TSSymbolType;
TSSymbolType
Definition: api.h:49
@ TSSymbolTypeAuxiliary
Definition: api.h:52
@ TSSymbolTypeRegular
Definition: api.h:50
@ TSSymbolTypeAnonymous
Definition: api.h:51

Function Documentation

◆ ts_language_field_count()

uint32_t ts_language_field_count ( const TSLanguage self)

Get the number of distinct field names in the language.

Definition at line 14 of file language.c.

14  {
15  return self->field_count;
16 }

Referenced by ts_language_field_id_for_name(), and ts_language_field_name_for_id().

◆ ts_language_field_id_for_name()

TSFieldId ts_language_field_id_for_name ( const TSLanguage self,
const char *  name,
uint32_t  name_length 
)

Get the numerical id for the given field name string.

Definition at line 119 of file language.c.

123  {
125  for (TSSymbol i = 1; i < count + 1; i++) {
126  switch (strncmp(name, self->field_names[i], name_length)) {
127  case 0:
128  if (self->field_names[i][name_length] == 0) return i;
129  break;
130  case -1:
131  return 0;
132  default:
133  break;
134  }
135  }
136  return 0;
137 }
lzma_index ** i
Definition: index.h:629
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
uint32_t ts_language_field_count(const TSLanguage *self)
Definition: language.c:14
uint16_t TSSymbol
Definition: parser.h:19
unsigned int uint32_t
Definition: sftypes.h:29
const char *const * field_names
Definition: parser.h:106
Definition: z80asm.h:102

References count, i, and ts_language_field_count().

Referenced by ts_node_child_by_field_name(), and ts_query__parse_pattern().

◆ ts_language_field_name_for_id()

const char* ts_language_field_name_for_id ( const TSLanguage self,
TSFieldId  id 
)

Get the field name string for the given numerical id.

Definition at line 107 of file language.c.

110  {
112  if (count && id <= count) {
113  return self->field_names[id];
114  } else {
115  return NULL;
116  }
117 }
#define NULL
Definition: cris-opc.c:27
int id
Definition: op.c:540

References count, id, NULL, and ts_language_field_count().

Referenced by ts_query__analyze_patterns(), and ts_query_cursor__advance().

◆ ts_language_symbol_count()

uint32_t ts_language_symbol_count ( const TSLanguage self)

Get the number of distinct node types in the language.

Definition at line 6 of file language.c.

6  {
7  return self->symbol_count + self->alias_count;
8 }

Referenced by ts_language_symbol_for_name(), and ts_language_symbol_name().

◆ ts_language_symbol_for_name()

TSSymbol ts_language_symbol_for_name ( const TSLanguage self,
const char *  string,
uint32_t  length,
bool  is_named 
)

Get the numerical id for the given node type string.

Definition at line 74 of file language.c.

79  {
80  if (!strncmp(string, "ERROR", length)) return ts_builtin_sym_error;
82  for (TSSymbol i = 0; i < count; i++) {
84  if ((!metadata.visible && !metadata.supertype) || metadata.named != is_named) continue;
85  const char *symbol_name = self->symbol_names[i];
86  if (!strncmp(symbol_name, string, length) && !symbol_name[length]) {
87  return self->public_symbol_map[i];
88  }
89  }
90  return 0;
91 }
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
uint32_t ts_language_symbol_count(const TSLanguage *self)
Definition: language.c:6
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol)
Definition: language.c:38
#define ts_builtin_sym_error
Definition: parser.h:12
bool visible
Definition: parser.h:36
bool supertype
Definition: parser.h:38

References count, i, length, TSSymbolMetadata::named, TSSymbolMetadata::supertype, ts_builtin_sym_error, ts_language_symbol_count(), ts_language_symbol_metadata(), and TSSymbolMetadata::visible.

Referenced by rz_core_cmd_new(), and ts_query__parse_pattern().

◆ ts_language_symbol_name()

const char* ts_language_symbol_name ( const TSLanguage self,
TSSymbol  symbol 
)

Get a node type string for the given numerical id.

Definition at line 59 of file language.c.

62  {
63  if (symbol == ts_builtin_sym_error) {
64  return "ERROR";
65  } else if (symbol == ts_builtin_sym_error_repeat) {
66  return "_ERROR";
67  } else if (symbol < ts_language_symbol_count(self)) {
68  return self->symbol_names[symbol];
69  } else {
70  return NULL;
71  }
72 }
#define ts_builtin_sym_error_repeat
Definition: language.h:11

References NULL, ts_builtin_sym_error, ts_builtin_sym_error_repeat, and ts_language_symbol_count().

Referenced by ts_node_type(), ts_query__analyze_patterns(), ts_stack_print_dot_graph(), ts_subtree__print_dot_graph(), and ts_subtree__write_to_string().

◆ ts_language_symbol_type()

TSSymbolType ts_language_symbol_type ( const TSLanguage self,
TSSymbol  symbol 
)

Check whether the given node type id belongs to named nodes, anonymous nodes, or a hidden nodes.

See also ts_node_is_named. Hidden nodes are never returned from the API.

Definition at line 93 of file language.c.

96  {
97  TSSymbolMetadata metadata = ts_language_symbol_metadata(self, symbol);
98  if (metadata.named && metadata.visible) {
99  return TSSymbolTypeRegular;
100  } else if (metadata.visible) {
101  return TSSymbolTypeAnonymous;
102  } else {
103  return TSSymbolTypeAuxiliary;
104  }
105 }

References TSSymbolMetadata::named, ts_language_symbol_metadata(), TSSymbolTypeAnonymous, TSSymbolTypeAuxiliary, TSSymbolTypeRegular, and TSSymbolMetadata::visible.

Referenced by ts_language_type_is_named_wasm(), and ts_language_type_is_visible_wasm().

◆ ts_language_version()

uint32_t ts_language_version ( const TSLanguage self)

Get the ABI version number for this language. This version number is used to ensure that languages were generated by a compatible version of Tree-sitter.

See also ts_parser_set_language.

Definition at line 10 of file language.c.

10  {
11  return self->version;
12 }

◆ 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 }
const MCPhysReg * iterator
static void ts_language_field_map(const TSLanguage *self, uint32_t production_id, const TSFieldMapEntry **start, const TSFieldMapEntry **end)
Definition: language.h:246
static Subtree ts_node__subtree(TSNode self)
Definition: node.c:48
uint32_t ts_node_child_count(TSNode self)
Definition: node.c:602
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
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 TSNode ts_node__null(void)
Definition: node.c:30
@ field_id
Definition: parser.c:1736
bool inherited
Definition: parser.h:27
TSFieldId field_id
Definition: parser.h:25
Definition: api.h:92
const void * id
Definition: api.h:94
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

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 }
uint32_t visible_child_count
Definition: subtree.h:135
static uint32_t ts_subtree_child_count(Subtree self)
Definition: subtree.h:282
const SubtreeHeapData * ptr
Definition: subtree.h:158

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_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 }
uint32_t ts_node_start_byte(TSNode self)
Definition: node.c:36
TSPoint ts_node_start_point(TSNode self)
Definition: node.c:40
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
Definition: api.h:55
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 }

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()

bool ts_node_is_named ( TSNode  self)

Check if the node is named. Named nodes correspond to named rules in the grammar, whereas anonymous nodes correspond to string literals in the grammar.

Definition at line 442 of file node.c.

442  {
443  TSSymbol alias = ts_node__alias(&self);
444  return alias
445  ? ts_language_symbol_metadata(self.tree->language, alias).named
447 }
static uint32_t ts_node__alias(const TSNode *self)
Definition: node.c:44
static bool ts_subtree_named(Subtree self)
Definition: subtree.h:215

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

Referenced by parse_declaration_node(), parse_enum_node(), parse_parameter_declaration_node(), parse_parameter_list(), parse_primitive_type(), parse_sized_primitive_type(), parse_sole_type_name(), parse_struct_node(), parse_type_abstract_declarator_node(), parse_type_declarator_node(), parse_type_descriptor_single(), parse_type_node_single(), parse_type_nodes_save(), parse_typedef_node(), parse_union_node(), ts_node_is_named_wasm(), ts_node_named_children_wasm(), ts_query_cursor__advance(), and ts_tree_cursor_current_node_is_named_wasm().

◆ ts_node_is_null()

◆ 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_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
uint32_t ts_node_end_byte(TSNode self)
Definition: node.c:406

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_parser_cancellation_flag()

const size_t* ts_parser_cancellation_flag ( const TSParser self)

Get the parser's current cancellation flag pointer.

Definition at line 1795 of file parser.c.

1795  {
1796  return (const size_t *)self->cancellation_flag;
1797 }

◆ ts_parser_delete()

void ts_parser_delete ( TSParser parser)

Delete the parser, freeing all of the memory that it used.

Definition at line 1725 of file parser.c.

1725  {
1726  if (!self) return;
1727 
1729  ts_stack_delete(self->stack);
1730  if (self->reduce_actions.contents) {
1731  array_delete(&self->reduce_actions);
1732  }
1733  if (self->included_range_differences.contents) {
1734  array_delete(&self->included_range_differences);
1735  }
1736  if (self->old_tree.ptr) {
1737  ts_subtree_release(&self->tree_pool, self->old_tree);
1738  self->old_tree = NULL_SUBTREE;
1739  }
1740  ts_lexer_delete(&self->lexer);
1742  ts_subtree_pool_delete(&self->tree_pool);
1743  reusable_node_delete(&self->reusable_node);
1744  array_delete(&self->trailing_extras);
1745  array_delete(&self->trailing_extras2);
1746  array_delete(&self->scratch_trees);
1747  ts_free(self);
1748 }
#define ts_free
Definition: alloc.h:30
#define array_delete(self)
Definition: array.h:41
void ts_lexer_delete(Lexer *self)
Definition: lexer.c:304
static void reusable_node_delete(ReusableNode *self)
Definition: reusable_node.h:35
void ts_stack_delete(Stack *self)
Definition: stack.c:424
void ts_subtree_release(SubtreePool *pool, Subtree self)
Definition: subtree.c:584
void ts_subtree_pool_delete(SubtreePool *self)
Definition: subtree.c:129
#define NULL_SUBTREE
Definition: subtree.h:19
static void ts_parser__set_cached_token(TSParser *self, size_t byte_index, Subtree last_external_token, Subtree token)
Definition: parser.c:598
bool ts_parser_set_language(TSParser *self, const TSLanguage *language)
Definition: parser.c:1754

References array_delete, NULL, NULL_SUBTREE, reusable_node_delete(), ts_free, ts_lexer_delete(), ts_parser__set_cached_token(), ts_parser_set_language(), ts_stack_delete(), ts_subtree_pool_delete(), and ts_subtree_release().

Referenced by core_cmd_tsrzcmd(), guess_data_free(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), and type_parse_string().

◆ ts_parser_included_ranges()

const TSRange* ts_parser_included_ranges ( const TSParser self,
uint32_t length 
)

Get the ranges of text that the parser will include when parsing.

The returned pointer is owned by the parser. The caller should not free it or write to it. The length of the array will be written to the given length pointer.

Definition at line 1819 of file parser.c.

1819  {
1820  return ts_lexer_included_ranges(&self->lexer, count);
1821 }
TSRange * ts_lexer_included_ranges(const Lexer *self, uint32_t *count)
Definition: lexer.c:395
Lexer lexer
Definition: parser.c:87

References count, and ts_lexer_included_ranges().

◆ ts_parser_language()

const TSLanguage* ts_parser_language ( const TSParser self)

Get the parser's current language.

Definition at line 1750 of file parser.c.

1750  {
1751  return self->language;
1752 }

◆ ts_parser_logger()

TSLogger ts_parser_logger ( const TSParser self)

Get the parser's current logger.

Definition at line 1775 of file parser.c.

1775  {
1776  return self->lexer.logger;
1777 }

◆ ts_parser_new()

TSParser* ts_parser_new ( void  )

Create a new parser.

Definition at line 1704 of file parser.c.

1704  {
1705  TSParser *self = ts_calloc(1, sizeof(TSParser));
1706  ts_lexer_init(&self->lexer);
1707  array_init(&self->reduce_actions);
1708  array_reserve(&self->reduce_actions, 4);
1709  self->tree_pool = ts_subtree_pool_new(32);
1710  self->stack = ts_stack_new(&self->tree_pool);
1711  self->finished_tree = NULL_SUBTREE;
1712  self->reusable_node = reusable_node_new();
1713  self->dot_graph_file = NULL;
1714  self->cancellation_flag = NULL;
1715  self->timeout_duration = 0;
1716  self->end_clock = clock_null();
1717  self->operation_count = 0;
1718  self->old_tree = NULL_SUBTREE;
1719  self->included_range_differences = (TSRangeArray) array_new();
1720  self->included_range_difference_index = 0;
1722  return self;
1723 }
#define ts_calloc
Definition: alloc.h:24
#define array_new()
Definition: array.h:25
#define array_init(self)
Definition: array.h:22
#define array_reserve(self, new_capacity)
Definition: array.h:37
static TSClock clock_null(void)
Definition: clock.h:119
void ts_lexer_init(Lexer *self)
Definition: lexer.c:275
static ReusableNode reusable_node_new(void)
Definition: reusable_node.h:14
Stack * ts_stack_new(SubtreePool *subtree_pool)
Definition: stack.c:405
SubtreePool ts_subtree_pool_new(uint32_t capacity)
Definition: subtree.c:123

References array_init, array_new, array_reserve, clock_null(), NULL, NULL_SUBTREE, reusable_node_new(), ts_calloc, ts_lexer_init(), ts_parser__set_cached_token(), ts_stack_new(), and ts_subtree_pool_new().

Referenced by core_cmd_tsrzcmd(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), ts_parser_new_wasm(), and type_parse_string().

◆ ts_parser_parse()

TSTree* ts_parser_parse ( TSParser self,
const TSTree old_tree,
TSInput  input 
)

Use the parser to parse some source code and create a syntax tree.

If you are parsing this document for the first time, pass NULL for the old_tree parameter. Otherwise, if you have already parsed an earlier version of this document and the document has since been edited, pass the previous syntax tree so that the unchanged parts of it can be reused. This will save time and memory. For this to work correctly, you must have already edited the old syntax tree using the ts_tree_edit function in a way that exactly matches the source code changes.

The TSInput parameter lets you specify how to read the text. It has the following three fields:

  1. read: A function to retrieve a chunk of text at a given byte offset and (row, column) position. The function should return a pointer to the text and write its length to the bytes_read pointer. The parser does not take ownership of this buffer; it just borrows it until it has finished reading it. The function should write a zero value to the bytes_read pointer to indicate the end of the document.
  2. payload: An arbitrary pointer that will be passed to each invocation of the read function.
  3. encoding: An indication of how the text is encoded. Either TSInputEncodingUTF8 or TSInputEncodingUTF16.

This function returns a syntax tree on success, and NULL on failure. There are three possible reasons for failure:

  1. The parser does not have a language assigned. Check for this using the ts_parser_language function.
  2. Parsing was cancelled due to a timeout that was set by an earlier call to the ts_parser_set_timeout_micros function. You can resume parsing from where the parser left out by calling ts_parser_parse again with the same arguments. Or you can start parsing from scratch by first calling ts_parser_reset.
  3. Parsing was cancelled using a cancellation flag that was set by an earlier call to ts_parser_set_cancellation_flag. You can resume parsing from where the parser left out by calling ts_parser_parse again with the same arguments.

Definition at line 1844 of file parser.c.

1848  {
1849  if (!self->language || !input.read) return NULL;
1850 
1851  ts_lexer_set_input(&self->lexer, input);
1852 
1854  self->included_range_difference_index = 0;
1855 
1856  if (ts_parser_has_outstanding_parse(self)) {
1857  LOG("resume_parsing");
1858  } else if (old_tree) {
1859  ts_subtree_retain(old_tree->root);
1860  self->old_tree = old_tree->root;
1862  old_tree->included_ranges, old_tree->included_range_count,
1865  );
1866  reusable_node_reset(&self->reusable_node, old_tree->root);
1867  LOG("parse_after_edit");
1868  LOG_TREE(self->old_tree);
1869  for (unsigned i = 0; i < self->included_range_differences.size; i++) {
1870  TSRange *range = &self->included_range_differences.contents[i];
1871  LOG("different_included_range %u - %u", range->start_byte, range->end_byte);
1872  }
1873  } else {
1875  LOG("new_parse");
1876  }
1877 
1878  self->operation_count = 0;
1879  if (self->timeout_duration) {
1880  self->end_clock = clock_after(clock_now(), self->timeout_duration);
1881  } else {
1882  self->end_clock = clock_null();
1883  }
1884 
1885  uint32_t position = 0, last_position = 0, version_count = 0;
1886  do {
1887  for (
1888  StackVersion version = 0;
1889  version_count = ts_stack_version_count(self->stack),
1890  version < version_count;
1891  version++
1892  ) {
1893  bool allow_node_reuse = version_count == 1;
1894  while (ts_stack_is_active(self->stack, version)) {
1895  LOG(
1896  "process version:%d, version_count:%u, state:%d, row:%u, col:%u",
1897  version,
1899  ts_stack_state(self->stack, version),
1902  );
1903 
1904  if (!ts_parser__advance(self, version, allow_node_reuse)) return NULL;
1905  LOG_STACK();
1906 
1907  position = ts_stack_position(self->stack, version).bytes;
1908  if (position > last_position || (version > 0 && position == last_position)) {
1909  last_position = position;
1910  break;
1911  }
1912  }
1913  }
1914 
1915  unsigned min_error_cost = ts_parser__condense_stack(self);
1916  if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) < min_error_cost) {
1917  break;
1918  }
1919 
1920  while (self->included_range_difference_index < self->included_range_differences.size) {
1921  TSRange *range = &self->included_range_differences.contents[self->included_range_difference_index];
1922  if (range->end_byte <= position) {
1923  self->included_range_difference_index++;
1924  } else {
1925  break;
1926  }
1927  }
1928  } while (version_count != 0);
1929 
1930  ts_subtree_balance(self->finished_tree, &self->tree_pool, self->language);
1931  LOG("done");
1932  LOG_TREE(self->finished_tree);
1933 
1934  TSTree *result = ts_tree_new(
1935  self->finished_tree,
1936  self->language,
1937  self->lexer.included_ranges,
1939  );
1940  self->finished_tree = NULL_SUBTREE;
1941  ts_parser_reset(self);
1942  return result;
1943 }
#define array_clear(self)
Definition: array.h:35
static TSClock clock_after(TSClock base, TSDuration duration)
Definition: clock.h:127
static TSClock clock_now(void)
Definition: clock.h:123
void ts_range_array_get_changed_ranges(const TSRange *old_ranges, unsigned old_range_count, const TSRange *new_ranges, unsigned new_range_count, TSRangeArray *differences)
void ts_lexer_set_input(Lexer *self, TSInput input)
Definition: lexer.c:308
static void reusable_node_reset(ReusableNode *self, Subtree tree)
Definition: reusable_node.h:81
static void reusable_node_clear(ReusableNode *self)
Definition: reusable_node.h:18
unsigned StackVersion
Definition: stack.h:15
TSPoint extent
Definition: length.h:11
TSRange * included_ranges
Definition: lexer.h:19
uint32_t included_range_count
Definition: lexer.h:24
unsigned included_range_difference_index
Definition: parser.c:107
const TSLanguage * language
Definition: parser.c:90
Subtree old_tree
Definition: parser.c:105
SubtreePool tree_pool
Definition: parser.c:89
Subtree finished_tree
Definition: parser.c:92
TSDuration timeout_duration
Definition: parser.c:101
TSRangeArray included_range_differences
Definition: parser.c:106
ReusableNode reusable_node
Definition: parser.c:97
Stack * stack
Definition: parser.c:88
Definition: api.h:60
Definition: tree.h:15
Subtree root
Definition: tree.h:16
TSRange * included_ranges
Definition: tree.h:18
unsigned included_range_count
Definition: tree.h:19
uint32_t ts_stack_version_count(const Stack *self)
Definition: stack.c:443
TSStateId ts_stack_state(const Stack *self, StackVersion version)
Definition: stack.c:447
bool ts_stack_is_active(const Stack *self, StackVersion version)
Definition: stack.c:716
Length ts_stack_position(const Stack *self, StackVersion version)
Definition: stack.c:451
TSTree * ts_tree_new(Subtree root, const TSLanguage *language, const TSRange *included_ranges, unsigned included_range_count)
Definition: tree.c:8
void ts_subtree_retain(Subtree self)
Definition: subtree.c:577
void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *language)
Definition: subtree.c:338
#define LOG(...)
Definition: parser.c:22
static unsigned ts_parser__condense_stack(TSParser *self)
Definition: parser.c:1595
void ts_parser_reset(TSParser *self)
Definition: parser.c:1823
static bool ts_parser__advance(TSParser *self, StackVersion version, bool allow_node_reuse)
Definition: parser.c:1387
#define LOG_STACK()
Definition: parser.c:58
#define LOG_TREE(tree)
Definition: parser.c:64
static bool ts_parser_has_outstanding_parse(TSParser *self)
Definition: parser.c:1695
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)

References array_clear, Length::bytes, clock_after(), clock_now(), clock_null(), TSPoint::column, Length::extent, i, TSTree::included_range_count, TSTree::included_ranges, input(), LOG, LOG_STACK, LOG_TREE, NULL, NULL_SUBTREE, capstone::range, reusable_node_clear(), reusable_node_reset(), TSTree::root, TSPoint::row, ts_lexer_set_input(), ts_parser__advance(), ts_parser__condense_stack(), ts_parser_has_outstanding_parse(), ts_parser_reset(), ts_range_array_get_changed_ranges(), ts_stack_is_active(), ts_stack_position(), ts_stack_state(), ts_stack_version_count(), ts_subtree_balance(), ts_subtree_error_cost(), ts_subtree_retain(), and ts_tree_new().

Referenced by ts_parser_parse_string_encoding(), and ts_parser_parse_wasm().

◆ ts_parser_parse_string()

TSTree* ts_parser_parse_string ( TSParser self,
const TSTree old_tree,
const char *  string,
uint32_t  length 
)

Use the parser to parse some source code stored in one contiguous buffer. The first two parameters are the same as in the ts_parser_parse function above. The second two parameters indicate the location of the buffer and its length in bytes.

Definition at line 1945 of file parser.c.

1950  {
1951  return ts_parser_parse_string_encoding(self, old_tree, string, length, TSInputEncodingUTF8);
1952 }
TSTree * ts_parser_parse_string_encoding(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length, TSInputEncoding encoding)
Definition: parser.c:1954

References length, ts_parser_parse_string_encoding(), and TSInputEncodingUTF8.

Referenced by apply_edits(), core_cmd_tsrzcmd(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), and type_parse_string().

◆ ts_parser_parse_string_encoding()

TSTree* ts_parser_parse_string_encoding ( TSParser self,
const TSTree old_tree,
const char *  string,
uint32_t  length,
TSInputEncoding  encoding 
)

Use the parser to parse some source code stored in one contiguous buffer with a given encoding. The first four parameters work the same as in the ts_parser_parse_string method above. The final parameter indicates whether the text is encoded as UTF8 or UTF16.

Definition at line 1954 of file parser.c.

1960  {
1961  TSStringInput input = {string, length};
1962  return ts_parser_parse(self, old_tree, (TSInput) {
1963  &input,
1965  encoding,
1966  });
1967 }
Definition: api.h:67
TSTree * ts_parser_parse(TSParser *self, const TSTree *old_tree, TSInput input)
Definition: parser.c:1844
static const char * ts_string_input_read(void *_self, uint32_t byte, TSPoint pt, uint32_t *length)
Definition: parser.c:132

References cmd_descs_generate::encoding, input(), length, ts_parser_parse(), and ts_string_input_read().

Referenced by ts_parser_parse_string().

◆ ts_parser_print_dot_graphs()

void ts_parser_print_dot_graphs ( TSParser self,
int  file 
)

Set the file descriptor to which the parser should write debugging graphs during parsing. The graphs are formatted in the DOT language. You may want to pipe these graphs directly to a dot(1) process in order to generate SVG output. You can turn off this logging by passing a negative number.

Definition at line 1783 of file parser.c.

1783  {
1784  if (self->dot_graph_file) {
1785  fclose(self->dot_graph_file);
1786  }
1787 
1788  if (fd >= 0) {
1789  self->dot_graph_file = fdopen(fd, "a");
1790  } else {
1791  self->dot_graph_file = NULL;
1792  }
1793 }
FILE * dot_graph_file
Definition: parser.c:99
static const z80_opcode fd[]
Definition: z80_tab.h:997

References fd, and NULL.

◆ ts_parser_reset()

void ts_parser_reset ( TSParser self)

Instruct the parser to start the next parse from the beginning.

If the parser previously failed because of a timeout or a cancellation, then by default, it will resume where it left off on the next call to ts_parser_parse or other parsing functions. If you don't want to resume, and instead intend to use this parser to parse some other document, you must call ts_parser_reset first.

Definition at line 1823 of file parser.c.

1823  {
1824  if (self->language && self->language->external_scanner.deserialize) {
1825  self->language->external_scanner.deserialize(self->external_scanner_payload, NULL, 0);
1826  }
1827 
1828  if (self->old_tree.ptr) {
1829  ts_subtree_release(&self->tree_pool, self->old_tree);
1830  self->old_tree = NULL_SUBTREE;
1831  }
1832 
1834  ts_lexer_reset(&self->lexer, length_zero());
1835  ts_stack_clear(self->stack);
1837  if (self->finished_tree.ptr) {
1839  self->finished_tree = NULL_SUBTREE;
1840  }
1841  self->accept_count = 0;
1842 }
static Length length_zero(void)
Definition: length.h:39
void ts_lexer_reset(Lexer *self, Length position)
Definition: lexer.c:316
void(* deserialize)(void *, const char *, unsigned)
Definition: parser.h:124
struct TSLanguage::@436 external_scanner
void * external_scanner_payload
Definition: parser.c:98
void ts_stack_clear(Stack *self)
Definition: stack.c:737

References length_zero(), NULL, NULL_SUBTREE, reusable_node_clear(), ts_lexer_reset(), ts_parser__set_cached_token(), ts_stack_clear(), and ts_subtree_release().

Referenced by ts_parser_parse(), and ts_parser_set_language().

◆ ts_parser_set_cancellation_flag()

void ts_parser_set_cancellation_flag ( TSParser self,
const size_t flag 
)

Set the parser's current cancellation flag pointer.

If a non-null pointer is assigned, then the parser will periodically read from this pointer during parsing. If it reads a non-zero value, it will halt early, returning NULL. See ts_parser_parse for more information.

Definition at line 1799 of file parser.c.

1799  {
1800  self->cancellation_flag = (const volatile size_t *)flag;
1801 }

◆ ts_parser_set_included_ranges()

bool ts_parser_set_included_ranges ( TSParser self,
const TSRange ranges,
uint32_t  length 
)

Set the ranges of text that the parser should include when parsing.

By default, the parser will always include entire documents. This function allows you to parse only a portion of a document but still return a syntax tree whose ranges match up with the document as a whole. You can also pass multiple disjoint ranges.

The second and third parameters specify the location and length of an array of ranges. The parser does not take ownership of these ranges; it copies the data, so it doesn't matter how these ranges are allocated.

If length is zero, then the entire document will be parsed. Otherwise, the given ranges must be ordered from earliest to latest in the document, and they must not overlap. That is, the following must hold for all i < length - 1: ranges[i].end_byte <= ranges[i + 1].start_byte

If this requirement is not satisfied, the operation will fail, the ranges will not be assigned, and this function will return false. On success, this function returns true

Definition at line 1811 of file parser.c.

1815  {
1816  return ts_lexer_set_included_ranges(&self->lexer, ranges, count);
1817 }
bool ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, uint32_t count)
Definition: lexer.c:367

References count, and ts_lexer_set_included_ranges().

Referenced by ts_parser_parse_wasm().

◆ ts_parser_set_language()

bool ts_parser_set_language ( TSParser self,
const TSLanguage language 
)

Set the language that the parser should use for parsing.

Returns a boolean indicating whether or not the language was successfully assigned. True means assignment succeeded. False means there was a version mismatch: the language was generated with an incompatible version of the Tree-sitter CLI. Check the language's version using ts_language_version and compare it to this library's TREE_SITTER_LANGUAGE_VERSION and TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION constants.

Definition at line 1754 of file parser.c.

1754  {
1755  if (language) {
1756  if (language->version > TREE_SITTER_LANGUAGE_VERSION) return false;
1757  if (language->version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION) return false;
1758  }
1759 
1761  self->language->external_scanner.destroy(self->external_scanner_payload);
1762  }
1763 
1764  if (language && language->external_scanner.create) {
1765  self->external_scanner_payload = language->external_scanner.create();
1766  } else {
1767  self->external_scanner_payload = NULL;
1768  }
1769 
1770  self->language = language;
1771  ts_parser_reset(self);
1772  return true;
1773 }
#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION
Definition: api.h:30
#define TREE_SITTER_LANGUAGE_VERSION
Definition: api.h:24
void *(* create)(void)
Definition: parser.h:120
void(* destroy)(void *)
Definition: parser.h:121
uint32_t version
Definition: parser.h:91

References TSLanguage::create, TSLanguage::external_scanner, NULL, TREE_SITTER_LANGUAGE_VERSION, TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION, ts_parser_reset(), and TSLanguage::version.

Referenced by core_cmd_tsrzcmd(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), ts_parser_delete(), and type_parse_string().

◆ ts_parser_set_logger()

void ts_parser_set_logger ( TSParser self,
TSLogger  logger 
)

Set the logger that a parser should use during parsing.

The parser does not take ownership over the logger payload. If a logger was previously assigned, the caller is responsible for releasing any memory owned by the previous logger.

Definition at line 1779 of file parser.c.

1779  {
1780  self->lexer.logger = logger;
1781 }

Referenced by ts_parser_enable_logger_wasm().

◆ ts_parser_set_timeout_micros()

void ts_parser_set_timeout_micros ( TSParser self,
uint64_t  timeout 
)

Set the maximum duration in microseconds that parsing should be allowed to take before halting.

If parsing takes longer than this, it will halt early, returning NULL. See ts_parser_parse for more information.

Definition at line 1807 of file parser.c.

1807  {
1808  self->timeout_duration = duration_from_micros(timeout_micros);
1809 }
static TSDuration duration_from_micros(uint64_t micros)
Definition: clock.h:111

References duration_from_micros().

◆ ts_parser_timeout_micros()

uint64_t ts_parser_timeout_micros ( const TSParser self)

Get the duration in microseconds that parsing is allowed to take.

Definition at line 1803 of file parser.c.

1803  {
1804  return duration_to_micros(self->timeout_duration);
1805 }
static uint64_t duration_to_micros(TSDuration self)
Definition: clock.h:115

References duration_to_micros().

◆ ts_query_capture_count()

uint32_t ts_query_capture_count ( const TSQuery self)

Definition at line 2701 of file query.c.

2701  {
2702  return self->captures.slices.size;
2703 }

◆ ts_query_capture_name_for_id()

const char* ts_query_capture_name_for_id ( const TSQuery self,
uint32_t  id,
uint32_t length 
)

Get the name and length of one of the query's captures, or one of the query's string literals. Each capture and string is associated with a numeric id based on the order that it appeared in the query's source.

Definition at line 2709 of file query.c.

2713  {
2714  return symbol_table_name_for_id(&self->captures, index, length);
2715 }
SymbolTable captures
Definition: query.c:271
static const char * symbol_table_name_for_id(const SymbolTable *self, uint16_t id, uint32_t *length)
Definition: query.c:752

References length, and symbol_table_name_for_id().

◆ ts_query_capture_quantifier_for_id()

TSQuantifier ts_query_capture_quantifier_for_id ( const TSQuery self,
uint32_t  pattern_id,
uint32_t  capture_id 
)

Get the quantifier of the query's captures. Each capture is * associated with a numeric id based on the order that it appeared in the query's source.

Definition at line 2717 of file query.c.

2721  {
2722  CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, pattern_index);
2723  return capture_quantifier_for_id(capture_quantifiers, capture_index);
2724 }
#define array_get(self, index)
Definition: array.h:28
static TSQuantifier capture_quantifier_for_id(const CaptureQuantifiers *self, uint16_t id)
Definition: query.c:656

References array_get, and capture_quantifier_for_id().

◆ ts_query_cursor_delete()

void ts_query_cursor_delete ( TSQueryCursor self)

Delete a query cursor, freeing all of the memory that it used.

Definition at line 2839 of file query.c.

2839  {
2840  array_delete(&self->states);
2841  array_delete(&self->finished_states);
2842  ts_tree_cursor_delete(&self->cursor);
2843  capture_list_pool_delete(&self->capture_list_pool);
2844  ts_free(self);
2845 }
void ts_tree_cursor_delete(TSTreeCursor *)
Definition: tree_cursor.c:94
TSTreeCursor cursor
Definition: query.c:290
static void capture_list_pool_delete(CaptureListPool *self)
Definition: query.c:411

References array_delete, capture_list_pool_delete(), ts_free, and ts_tree_cursor_delete().

◆ ts_query_cursor_did_exceed_match_limit()

bool ts_query_cursor_did_exceed_match_limit ( const TSQueryCursor self)

Manage the maximum number of in-progress matches allowed by this query cursor.

Query cursors have an optional maximum capacity for storing lists of in-progress captures. If this capacity is exceeded, then the earliest-starting match will silently be dropped to make room for further matches. This maximum capacity is optional — by default, query cursors allow any number of pending matches, dynamically allocating new space for them as needed as the query is executed.

Definition at line 2847 of file query.c.

2847  {
2848  return self->did_exceed_match_limit;
2849 }

Referenced by ts_query_captures_wasm(), and ts_query_matches_wasm().

◆ ts_query_cursor_exec()

void ts_query_cursor_exec ( TSQueryCursor self,
const TSQuery query,
TSNode  node 
)

Start running a given query on a given node.

Definition at line 2859 of file query.c.

2863  {
2864  array_clear(&self->states);
2865  array_clear(&self->finished_states);
2866  ts_tree_cursor_reset(&self->cursor, node);
2867  capture_list_pool_reset(&self->capture_list_pool);
2868  self->next_state_id = 0;
2869  self->depth = 0;
2870  self->ascending = false;
2871  self->halted = false;
2872  self->query = query;
2873  self->did_exceed_match_limit = false;
2874 }
void ts_tree_cursor_reset(TSTreeCursor *, TSNode)
Definition: tree_cursor.c:76
static void capture_list_pool_reset(CaptureListPool *self)
Definition: query.c:403

References array_clear, capture_list_pool_reset(), and ts_tree_cursor_reset().

Referenced by ts_query_captures_wasm(), and ts_query_matches_wasm().

◆ ts_query_cursor_match_limit()

uint32_t ts_query_cursor_match_limit ( const TSQueryCursor self)

Definition at line 2851 of file query.c.

2851  {
2852  return self->capture_list_pool.max_capture_list_count;
2853 }

◆ ts_query_cursor_new()

TSQueryCursor* ts_query_cursor_new ( void  )

Create a new cursor for executing a given query.

The cursor stores the state that is needed to iteratively search for matches. To use the query cursor, first call ts_query_cursor_exec to start running a given query on a given syntax node. Then, there are two options for consuming the results of the query:

  1. Repeatedly call ts_query_cursor_next_match to iterate over all of the matches in the order that they were found. Each match contains the index of the pattern that matched, and an array of captures. Because multiple patterns can match the same set of nodes, one match may contain captures that appear before some of the captures from a previous match.
  2. Repeatedly call ts_query_cursor_next_capture to iterate over all of the individual captures in the order that they appear. This is useful if don't care about which pattern matched, and just want a single ordered sequence of captures.

If you don't care about consuming all of the results, you can stop calling ts_query_cursor_next_match or ts_query_cursor_next_capture at any point. You can then start executing another query on another node by calling ts_query_cursor_exec again.

Definition at line 2820 of file query.c.

2820  {
2821  TSQueryCursor *self = ts_malloc(sizeof(TSQueryCursor));
2822  *self = (TSQueryCursor) {
2823  .did_exceed_match_limit = false,
2824  .ascending = false,
2825  .halted = false,
2826  .states = array_new(),
2827  .finished_states = array_new(),
2828  .capture_list_pool = capture_list_pool_new(),
2829  .start_byte = 0,
2830  .end_byte = UINT32_MAX,
2831  .start_point = {0, 0},
2832  .end_point = POINT_MAX,
2833  };
2834  array_reserve(&self->states, 8);
2835  array_reserve(&self->finished_states, 8);
2836  return self;
2837 }
#define ts_malloc
Definition: alloc.h:21
struct TSQueryCursor TSQueryCursor
Definition: api.h:42
#define POINT_MAX
Definition: point.h:7
#define UINT32_MAX
static CaptureListPool capture_list_pool_new(void)
Definition: query.c:394

References array_new, array_reserve, capture_list_pool_new(), POINT_MAX, ts_malloc, and UINT32_MAX.

Referenced by ts_query_captures_wasm(), and ts_query_matches_wasm().

◆ ts_query_cursor_next_capture()

bool ts_query_cursor_next_capture ( TSQueryCursor self,
TSQueryMatch match,
uint32_t capture_index 
)

Advance to the next capture of the currently running query.

If there is a capture, write its match to *match and its index within the matche's capture list to *capture_index. Otherwise, return false.

Definition at line 3746 of file query.c.

3750  {
3751  // The goal here is to return captures in order, even though they may not
3752  // be discovered in order, because patterns can overlap. Search for matches
3753  // until there is a finished capture that is before any unfinished capture.
3754  for (;;) {
3755  // First, find the earliest capture in an unfinished match.
3756  uint32_t first_unfinished_capture_byte;
3757  uint32_t first_unfinished_pattern_index;
3758  uint32_t first_unfinished_state_index;
3759  bool first_unfinished_state_is_definite = false;
3761  self,
3762  &first_unfinished_state_index,
3763  &first_unfinished_capture_byte,
3764  &first_unfinished_pattern_index,
3765  &first_unfinished_state_is_definite
3766  );
3767 
3768  // Then find the earliest capture in a finished match. It must occur
3769  // before the first capture in an *unfinished* match.
3770  QueryState *first_finished_state = NULL;
3771  uint32_t first_finished_capture_byte = first_unfinished_capture_byte;
3772  uint32_t first_finished_pattern_index = first_unfinished_pattern_index;
3773  for (unsigned i = 0; i < self->finished_states.size;) {
3774  QueryState *state = &self->finished_states.contents[i];
3775  const CaptureList *captures = capture_list_pool_get(
3776  &self->capture_list_pool,
3777  state->capture_list_id
3778  );
3779 
3780  // Remove states whose captures are all consumed.
3781  if (state->consumed_capture_count >= captures->size) {
3783  &self->capture_list_pool,
3784  state->capture_list_id
3785  );
3786  array_erase(&self->finished_states, i);
3787  continue;
3788  }
3789 
3790  // Skip captures that precede the cursor's start byte.
3791  TSNode node = captures->contents[state->consumed_capture_count].node;
3792  if (ts_node_end_byte(node) <= self->start_byte) {
3793  state->consumed_capture_count++;
3794  continue;
3795  }
3796 
3797  uint32_t node_start_byte = ts_node_start_byte(node);
3798  if (
3799  node_start_byte < first_finished_capture_byte ||
3800  (
3801  node_start_byte == first_finished_capture_byte &&
3802  state->pattern_index < first_finished_pattern_index
3803  )
3804  ) {
3805  first_finished_state = state;
3806  first_finished_capture_byte = node_start_byte;
3807  first_finished_pattern_index = state->pattern_index;
3808  }
3809  i++;
3810  }
3811 
3812  // If there is finished capture that is clearly before any unfinished
3813  // capture, then return its match, and its capture index. Internally
3814  // record the fact that the capture has been 'consumed'.
3815  QueryState *state;
3816  if (first_finished_state) {
3817  state = first_finished_state;
3818  } else if (first_unfinished_state_is_definite) {
3819  state = &self->states.contents[first_unfinished_state_index];
3820  } else {
3821  state = NULL;
3822  }
3823 
3824  if (state) {
3825  if (state->id == UINT32_MAX) state->id = self->next_state_id++;
3826  match->id = state->id;
3827  match->pattern_index = state->pattern_index;
3828  const CaptureList *captures = capture_list_pool_get(
3829  &self->capture_list_pool,
3830  state->capture_list_id
3831  );
3832  match->captures = captures->contents;
3833  match->capture_count = captures->size;
3834  *capture_index = state->consumed_capture_count;
3835  state->consumed_capture_count++;
3836  return true;
3837  }
3838 
3839  if (capture_list_pool_is_empty(&self->capture_list_pool)) {
3840  LOG(
3841  " abandon state. index:%u, pattern:%u, offset:%u.\n",
3842  first_unfinished_state_index,
3843  first_unfinished_pattern_index,
3844  first_unfinished_capture_byte
3845  );
3847  &self->capture_list_pool,
3848  self->states.contents[first_unfinished_state_index].capture_list_id
3849  );
3850  array_erase(&self->states, first_unfinished_state_index);
3851  }
3852 
3853  // If there are no finished matches that are ready to be returned, then
3854  // continue finding more matches.
3855  if (
3856  !ts_query_cursor__advance(self, true) &&
3857  self->finished_states.size == 0
3858  ) return false;
3859  }
3860 }
uint32_t ts_node_start_byte(TSNode)
Definition: node.c:36
uint32_t ts_node_end_byte(TSNode)
Definition: node.c:406
#define array_erase(self, index)
Definition: array.h:79
Definition: engine.c:71
Definition: dis.h:43
static bool ts_query_cursor__first_in_progress_capture(TSQueryCursor *self, uint32_t *state_index, uint32_t *byte_offset, uint32_t *pattern_index, bool *root_pattern_guaranteed)
Definition: query.c:2902
#define LOG(...)
Definition: query.c:3033
static bool ts_query_cursor__advance(TSQueryCursor *self, bool stop_on_definite_step)
Definition: query.c:3206
static const CaptureList * capture_list_pool_get(const CaptureListPool *self, uint16_t id)
Definition: query.c:418
static bool capture_list_pool_is_empty(const CaptureListPool *self)
Definition: query.c:428
static void capture_list_pool_release(CaptureListPool *self, uint16_t id)
Definition: query.c:458

References array_erase, capture_list_pool_get(), capture_list_pool_is_empty(), capture_list_pool_release(), i, LOG, NULL, ts_node_end_byte(), ts_node_start_byte(), ts_query_cursor__advance(), ts_query_cursor__first_in_progress_capture(), and UINT32_MAX.

Referenced by ts_query_captures_wasm().

◆ ts_query_cursor_next_match()

bool ts_query_cursor_next_match ( TSQueryCursor self,
TSQueryMatch match 
)

Advance to the next match of the currently running query.

If there is a match, write it to *match and return true. Otherwise, return false.

Definition at line 3690 of file query.c.

3693  {
3694  if (self->finished_states.size == 0) {
3695  if (!ts_query_cursor__advance(self, false)) {
3696  return false;
3697  }
3698  }
3699 
3700  QueryState *state = &self->finished_states.contents[0];
3701  if (state->id == UINT32_MAX) state->id = self->next_state_id++;
3702  match->id = state->id;
3703  match->pattern_index = state->pattern_index;
3704  const CaptureList *captures = capture_list_pool_get(
3705  &self->capture_list_pool,
3706  state->capture_list_id
3707  );
3708  match->captures = captures->contents;
3709  match->capture_count = captures->size;
3710  capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);
3711  array_erase(&self->finished_states, 0);
3712  return true;
3713 }

References array_erase, capture_list_pool_get(), capture_list_pool_release(), ts_query_cursor__advance(), and UINT32_MAX.

Referenced by ts_query_matches_wasm().

◆ ts_query_cursor_remove_match()

void ts_query_cursor_remove_match ( TSQueryCursor self,
uint32_t  id 
)

Definition at line 3715 of file query.c.

3718  {
3719  for (unsigned i = 0; i < self->finished_states.size; i++) {
3720  const QueryState *state = &self->finished_states.contents[i];
3721  if (state->id == match_id) {
3723  &self->capture_list_pool,
3724  state->capture_list_id
3725  );
3726  array_erase(&self->finished_states, i);
3727  return;
3728  }
3729  }
3730 
3731  // Remove unfinished query states as well to prevent future
3732  // captures for a match being removed.
3733  for (unsigned i = 0; i < self->states.size; i++) {
3734  const QueryState *state = &self->states.contents[i];
3735  if (state->id == match_id) {
3737  &self->capture_list_pool,
3738  state->capture_list_id
3739  );
3740  array_erase(&self->states, i);
3741  return;
3742  }
3743  }
3744 }

References array_erase, capture_list_pool_release(), and i.

◆ ts_query_cursor_set_byte_range()

void ts_query_cursor_set_byte_range ( TSQueryCursor self,
uint32_t  start_byte,
uint32_t  end_byte 
)

Set the range of bytes or (row, column) positions in which the query will be executed.

Definition at line 2876 of file query.c.

2880  {
2881  if (end_byte == 0) {
2882  end_byte = UINT32_MAX;
2883  }
2884  self->start_byte = start_byte;
2885  self->end_byte = end_byte;
2886 }

References UINT32_MAX.

◆ ts_query_cursor_set_match_limit()

void ts_query_cursor_set_match_limit ( TSQueryCursor self,
uint32_t  limit 
)

Definition at line 2855 of file query.c.

2855  {
2856  self->capture_list_pool.max_capture_list_count = limit;
2857 }
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45

References limit.

Referenced by ts_query_captures_wasm(), and ts_query_matches_wasm().

◆ ts_query_cursor_set_point_range()

void ts_query_cursor_set_point_range ( TSQueryCursor self,
TSPoint  start_point,
TSPoint  end_point 
)

Definition at line 2888 of file query.c.

2892  {
2893  if (end_point.row == 0 && end_point.column == 0) {
2894  end_point = POINT_MAX;
2895  }
2896  self->start_point = start_point;
2897  self->end_point = end_point;
2898 }

References TSPoint::column, POINT_MAX, and TSPoint::row.

Referenced by ts_query_captures_wasm(), and ts_query_matches_wasm().

◆ ts_query_delete()

void ts_query_delete ( TSQuery self)

Delete a query, freeing all of the memory that it used.

Definition at line 2677 of file query.c.

2677  {
2678  if (self) {
2679  array_delete(&self->steps);
2680  array_delete(&self->pattern_map);
2681  array_delete(&self->predicate_steps);
2682  array_delete(&self->patterns);
2683  array_delete(&self->step_offsets);
2684  array_delete(&self->string_buffer);
2685  array_delete(&self->negated_fields);
2686  symbol_table_delete(&self->captures);
2687  symbol_table_delete(&self->predicate_values);
2688  for (uint32_t index = 0; index < self->capture_quantifiers.size; index++) {
2689  CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, index);
2690  capture_quantifiers_delete(capture_quantifiers);
2691  }
2692  array_delete(&self->capture_quantifiers);
2693  ts_free(self);
2694  }
2695 }
static void capture_quantifiers_delete(CaptureQuantifiers *self)
Definition: query.c:633
static void symbol_table_delete(SymbolTable *self)
Definition: query.c:732

References array_delete, array_get, capture_quantifiers_delete(), symbol_table_delete(), and ts_free.

Referenced by ts_query_new().

◆ ts_query_disable_capture()

void ts_query_disable_capture ( TSQuery self,
const char *  name,
uint32_t  length 
)

Disable a certain capture within a query.

This prevents the capture from being returned in matches, and also avoids any resource usage associated with recording the capture. Currently, there is no way to undo this.

Definition at line 2785 of file query.c.

2789  {
2790  // Remove capture information for any pattern step that previously
2791  // captured with the given name.
2792  int id = symbol_table_id_for_name(&self->captures, name, length);
2793  if (id != -1) {
2794  for (unsigned i = 0; i < self->steps.size; i++) {
2795  QueryStep *step = &self->steps.contents[i];
2797  }
2798  }
2799 }
static states step(struct re_guts *, sopno, sopno, states, int, states)
Definition: engine.c:888
static int symbol_table_id_for_name(const SymbolTable *self, const char *name, uint32_t length)
Definition: query.c:737
static void query_step__remove_capture(QueryStep *self, uint16_t capture_id)
Definition: query.c:816

References i, length, query_step__remove_capture(), step(), and symbol_table_id_for_name().

◆ ts_query_disable_pattern()

void ts_query_disable_pattern ( TSQuery self,
uint32_t  pattern_index 
)

Disable a certain pattern within a query.

This prevents the pattern from matching and removes most of the overhead associated with the pattern. Currently, there is no way to undo this.

Definition at line 2801 of file query.c.

2804  {
2805  // Remove the given pattern from the pattern map. Its steps will still
2806  // be in the `steps` array, but they will never be read.
2807  for (unsigned i = 0; i < self->pattern_map.size; i++) {
2808  PatternEntry *pattern = &self->pattern_map.contents[i];
2809  if (pattern->pattern_index == pattern_index) {
2810  array_erase(&self->pattern_map, i);
2811  i--;
2812  }
2813  }
2814 }
PatternEntry
Definition: query.c:143

References array_erase, i, and PatternEntry.

◆ ts_query_is_pattern_guaranteed_at_step()

bool ts_query_is_pattern_guaranteed_at_step ( const TSQuery self,
uint32_t  byte_offset 
)

Definition at line 2754 of file query.c.

2757  {
2758  uint32_t step_index = UINT32_MAX;
2759  for (unsigned i = 0; i < self->step_offsets.size; i++) {
2760  StepOffset *step_offset = &self->step_offsets.contents[i];
2761  if (step_offset->byte_offset > byte_offset) break;
2762  step_index = step_offset->step_index;
2763  }
2764  if (step_index < self->steps.size) {
2765  return self->steps.contents[step_index].root_pattern_guaranteed;
2766  } else {
2767  return false;
2768  }
2769 }
uint16_t step_index
Definition: query.c:153
uint32_t byte_offset
Definition: query.c:152

References StepOffset::byte_offset, i, StepOffset::step_index, and UINT32_MAX.

◆ ts_query_new()

TSQuery* ts_query_new ( const TSLanguage language,
const char *  source,
uint32_t  source_len,
uint32_t error_offset,
TSQueryError error_type 
)

Create a new query from a string containing one or more S-expression patterns. The query is associated with a particular language, and can only be run on syntax nodes parsed with that language.

If all of the given patterns are valid, this returns a TSQuery. If a pattern is invalid, this returns NULL, and provides two pieces of information about the problem:

  1. The byte offset of the error is written to the error_offset parameter.
  2. The type of error is written to the error_type parameter.

Definition at line 2546 of file query.c.

2552  {
2553  if (
2554  !language ||
2555  language->version > TREE_SITTER_LANGUAGE_VERSION ||
2557  ) {
2558  *error_type = TSQueryErrorLanguage;
2559  return NULL;
2560  }
2561 
2562  TSQuery *self = ts_malloc(sizeof(TSQuery));
2563  *self = (TSQuery) {
2564  .steps = array_new(),
2565  .pattern_map = array_new(),
2566  .captures = symbol_table_new(),
2567  .capture_quantifiers = array_new(),
2568  .predicate_values = symbol_table_new(),
2569  .predicate_steps = array_new(),
2570  .patterns = array_new(),
2571  .step_offsets = array_new(),
2572  .string_buffer = array_new(),
2573  .negated_fields = array_new(),
2574  .wildcard_root_pattern_count = 0,
2575  .language = language,
2576  };
2577 
2578  array_push(&self->negated_fields, 0);
2579 
2580  // Parse all of the S-expressions in the given string.
2581  Stream stream = stream_new(source, source_len);
2583  while (stream.input < stream.end) {
2584  uint32_t pattern_index = self->patterns.size;
2585  uint32_t start_step_index = self->steps.size;
2586  uint32_t start_predicate_step_index = self->predicate_steps.size;
2587  array_push(&self->patterns, ((QueryPattern) {
2588  .steps = (Slice) {.offset = start_step_index},
2589  .predicate_steps = (Slice) {.offset = start_predicate_step_index},
2590  .start_byte = stream_offset(&stream),
2591  }));
2592  CaptureQuantifiers capture_quantifiers = capture_quantifiers_new();
2593  *error_type = ts_query__parse_pattern(self, &stream, 0, false, &capture_quantifiers);
2594  array_push(&self->steps, query_step__new(0, PATTERN_DONE_MARKER, false));
2595 
2596  QueryPattern *pattern = array_back(&self->patterns);
2597  pattern->steps.length = self->steps.size - start_step_index;
2598  pattern->predicate_steps.length = self->predicate_steps.size - start_predicate_step_index;
2599 
2600  // If any pattern could not be parsed, then report the error information
2601  // and terminate.
2602  if (*error_type) {
2603  if (*error_type == PARENT_DONE) *error_type = TSQueryErrorSyntax;
2604  *error_offset = stream_offset(&stream);
2605  capture_quantifiers_delete(&capture_quantifiers);
2606  ts_query_delete(self);
2607  return NULL;
2608  }
2609 
2610  // Maintain a list of capture quantifiers for each pattern
2611  array_push(&self->capture_quantifiers, capture_quantifiers);
2612 
2613  // Maintain a map that can look up patterns for a given root symbol.
2614  uint16_t wildcard_root_alternative_index = NONE;
2615  for (;;) {
2616  QueryStep *step = &self->steps.contents[start_step_index];
2617 
2618  // If a pattern has a wildcard at its root, but it has a non-wildcard child,
2619  // then optimize the matching process by skipping matching the wildcard.
2620  // Later, during the matching process, the query cursor will check that
2621  // there is a parent node, and capture it if necessary.
2622  if (step->symbol == WILDCARD_SYMBOL && step->depth == 0 && !step->field) {
2623  QueryStep *second_step = &self->steps.contents[start_step_index + 1];
2624  if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth == 1) {
2625  wildcard_root_alternative_index = step->alternative_index;
2626  start_step_index += 1;
2627  step = second_step;
2628  }
2629  }
2630 
2631  // Determine whether the pattern has a single root node. This affects
2632  // decisions about whether or not to start matching the pattern when
2633  // a query cursor has a range restriction.
2634  bool is_rooted = true;
2635  uint32_t start_depth = step->depth;
2636  for (uint32_t step_index = start_step_index + 1; step_index < self->steps.size; step_index++) {
2637  QueryStep *step = &self->steps.contents[step_index];
2638  if (step->depth == start_depth) {
2639  is_rooted = false;
2640  break;
2641  }
2642  }
2643 
2645  .step_index = start_step_index,
2646  .pattern_index = pattern_index,
2647  .is_rooted = is_rooted
2648  });
2649  if (step->symbol == WILDCARD_SYMBOL) {
2650  self->wildcard_root_pattern_count++;
2651  }
2652 
2653  // If there are alternatives or options at the root of the pattern,
2654  // then add multiple entries to the pattern map.
2655  if (step->alternative_index != NONE) {
2656  start_step_index = step->alternative_index;
2657  step->alternative_index = NONE;
2658  } else if (wildcard_root_alternative_index != NONE) {
2659  start_step_index = wildcard_root_alternative_index;
2660  wildcard_root_alternative_index = NONE;
2661  } else {
2662  break;
2663  }
2664  }
2665  }
2666 
2667  if (!ts_query__analyze_patterns(self, error_offset)) {
2668  *error_type = TSQueryErrorStructure;
2669  ts_query_delete(self);
2670  return NULL;
2671  }
2672 
2673  array_delete(&self->string_buffer);
2674  return self;
2675 }
struct TSQuery TSQuery
Definition: api.h:41
#define array_back(self)
Definition: array.h:33
#define array_push(self, element)
Definition: array.h:43
voidpf stream
Definition: ioapi.h:138
const char * source
Definition: lz4.h:699
unsigned short uint16_t
Definition: sftypes.h:30
Slice predicate_steps
Definition: query.c:147
Slice steps
Definition: query.c:146
uint16_t depth
Definition: query.c:90
TSSymbol symbol
Definition: query.c:86
Definition: query.c:110
uint32_t length
Definition: query.c:112
Definition: query.c:23
Definition: query.c:270
void ts_query_delete(TSQuery *self)
Definition: query.c:2677
static const TSSymbol WILDCARD_SYMBOL
Definition: query.c:308
static SymbolTable symbol_table_new(void)
Definition: query.c:725
static CaptureQuantifiers capture_quantifiers_new(void)
Definition: query.c:628
static uint32_t stream_offset(Stream *self)
Definition: query.c:386
static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset)
Definition: query.c:1116
static void stream_skip_whitespace(Stream *self)
Definition: query.c:353
static TSQueryError ts_query__parse_pattern(TSQuery *self, Stream *stream, uint32_t depth, bool is_immediate, CaptureQuantifiers *capture_quantifiers)
Definition: query.c:2050
static void ts_query__pattern_map_insert(TSQuery *self, TSSymbol symbol, PatternEntry new_entry)
Definition: query.c:1089
static Stream stream_new(const char *string, uint32_t length)
Definition: query.c:342
static const uint16_t NONE
Definition: query.c:307
static QueryStep query_step__new(TSSymbol symbol, uint16_t depth, bool is_immediate)
Definition: query.c:784
static const TSQueryError PARENT_DONE
Definition: query.c:305
static const uint16_t PATTERN_DONE_MARKER
Definition: query.c:306

References array_back, array_new, array_push, capture_quantifiers_delete(), capture_quantifiers_new(), QueryStep::depth, Slice::length, NONE, NULL, PARENT_DONE, PATTERN_DONE_MARKER, PatternEntry, QueryPattern::predicate_steps, query_step__new(), source, step(), QueryPattern::steps, stream_new(), stream_offset(), stream_skip_whitespace(), QueryStep::symbol, symbol_table_new(), TREE_SITTER_LANGUAGE_VERSION, TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION, ts_malloc, ts_query__parse_pattern(), ts_query__pattern_map_insert(), ts_query_delete(), TSQueryErrorLanguage, TSQueryErrorSyntax, TSLanguage::version, and WILDCARD_SYMBOL.

◆ ts_query_pattern_count()

uint32_t ts_query_pattern_count ( const TSQuery self)

Get the number of patterns, captures, or string literals in the query.

Definition at line 2697 of file query.c.

2697  {
2698  return self->patterns.size;
2699 }

◆ ts_query_predicates_for_pattern()

const TSQueryPredicateStep* ts_query_predicates_for_pattern ( const TSQuery self,
uint32_t  pattern_index,
uint32_t length 
)

Get all of the predicates for the given pattern in the query.

The predicates are represented as a single array of steps. There are three types of steps in this array, which correspond to the three legal values for the type field:

  • TSQueryPredicateStepTypeCapture - Steps with this type represent names of captures. Their value_id can be used with the ts_query_capture_name_for_id function to obtain the name of the capture.
  • TSQueryPredicateStepTypeString - Steps with this type represent literal strings. Their value_id can be used with the ts_query_string_value_for_id function to obtain their string value.
  • TSQueryPredicateStepTypeDone - Steps with this type are sentinels that represent the end of an individual predicate. If a pattern has two predicates, then there will be two steps with this type in the array.

Definition at line 2734 of file query.c.

2738  {
2739  Slice slice = self->patterns.contents[pattern_index].predicate_steps;
2740  *step_count = slice.length;
2741  if (self->predicate_steps.contents == NULL) {
2742  return NULL;
2743  }
2744  return &self->predicate_steps.contents[slice.offset];
2745 }
uint32_t offset
Definition: query.c:111

References Slice::length, NULL, and Slice::offset.

◆ ts_query_start_byte_for_pattern()

uint32_t ts_query_start_byte_for_pattern ( const TSQuery self,
uint32_t  pattern_index 
)

Get the byte offset where the given pattern starts in the query's source.

This can be useful when combining queries by concatenating their source code strings.

Definition at line 2747 of file query.c.

2750  {
2751  return self->patterns.contents[pattern_index].start_byte;
2752 }

◆ ts_query_string_count()

uint32_t ts_query_string_count ( const TSQuery self)

Definition at line 2705 of file query.c.

2705  {
2706  return self->predicate_values.slices.size;
2707 }

◆ ts_query_string_value_for_id()

const char* ts_query_string_value_for_id ( const TSQuery self,
uint32_t  id,
uint32_t length 
)

Definition at line 2726 of file query.c.

2730  {
2731  return symbol_table_name_for_id(&self->predicate_values, index, length);
2732 }

References length, and symbol_table_name_for_id().

◆ ts_set_allocator()

void ts_set_allocator ( void *(*)(size_t new_malloc,
void *(*)(size_t, size_t new_calloc,
void *(*)(void *, size_t new_realloc,
void(*)(void *)  new_free 
)

Set the allocation functions used by the library.

By default, Tree-sitter uses the standard libc allocation functions, but aborts the process when an allocation fails. This function lets you supply alternative allocation functions at runtime.

If you pass NULL for any parameter, Tree-sitter will switch back to its default implementation of that function.

If you call this function after the library has already been used, then you must ensure that either:

  1. All the existing objects have been freed.
  2. The new allocator shares its state with the old one, so it is capable of freeing memory that was allocated by the old allocator.

Definition at line 37 of file alloc.c.

42  {
43  ts_current_malloc = new_malloc ? new_malloc : ts_malloc_default;
44  ts_current_calloc = new_calloc ? new_calloc : ts_calloc_default;
45  ts_current_realloc = new_realloc ? new_realloc : ts_realloc_default;
46  ts_current_free = new_free ? new_free : free;
47 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void * ts_realloc_default(void *buffer, size_t size)
Definition: alloc.c:22
static void * ts_calloc_default(size_t count, size_t size)
Definition: alloc.c:13
void(* ts_current_free)(void *)
Definition: alloc.c:35
static void * ts_malloc_default(size_t size)
Definition: alloc.c:4
void *(* ts_current_malloc)(size_t)
Definition: alloc.c:32
void *(* ts_current_calloc)(size_t, size_t)
Definition: alloc.c:33
void *(* ts_current_realloc)(void *, size_t)
Definition: alloc.c:34

References free(), ts_calloc_default(), ts_current_calloc, ts_current_free, ts_current_malloc, ts_current_realloc, ts_malloc_default(), and ts_realloc_default().

◆ ts_tree_copy()

TSTree* ts_tree_copy ( const TSTree self)

Create a shallow copy of the syntax tree. This is very fast.

You need to copy a syntax tree in order to use it on more than one thread at a time, as syntax trees are not thread safe.

Definition at line 21 of file tree.c.

21  {
22  ts_subtree_retain(self->root);
23  return ts_tree_new(self->root, self->language, self->included_ranges, self->included_range_count);
24 }
const TSLanguage * language
Definition: tree.h:17

References ts_subtree_retain(), and ts_tree_new().

◆ ts_tree_cursor_copy()

TSTreeCursor ts_tree_cursor_copy ( const TSTreeCursor _cursor)

Definition at line 479 of file tree_cursor.c.

479  {
480  const TreeCursor *cursor = (const TreeCursor *)_cursor;
481  TSTreeCursor res = {NULL, NULL, {0, 0}};
482  TreeCursor *copy = (TreeCursor *)&res;
483  copy->tree = cursor->tree;
484  array_init(&copy->stack);
485  array_push_all(&copy->stack, &cursor->stack);
486  return res;
487 }
#define array_push_all(self, other)
Definition: array.h:54
const TSTree * tree
Definition: tree_cursor.h:14

References array_init, array_push_all, NULL, and TreeCursor::tree.

◆ ts_tree_cursor_current_field_id()

TSFieldId ts_tree_cursor_current_field_id ( const TSTreeCursor _self)

Get the field id of the tree cursor's current node.

This returns zero if the current node doesn't have a field. See also ts_node_child_by_field_id, ts_language_field_id_for_name.

Definition at line 431 of file tree_cursor.c.

431  {
432  const TreeCursor *self = (const TreeCursor *)_self;
433 
434  // Walk up the tree, visiting the current node and its invisible ancestors.
435  for (unsigned i = self->stack.size - 1; i > 0; i--) {
436  TreeCursorEntry *entry = &self->stack.contents[i];
437  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
438 
439  // Stop walking up when another visible node is found.
440  if (i != self->stack.size - 1) {
441  if (ts_subtree_visible(*entry->subtree)) break;
442  if (
443  !ts_subtree_extra(*entry->subtree) &&
445  self->tree->language,
446  parent_entry->subtree->ptr->production_id,
447  entry->structural_child_index
448  )
449  ) break;
450  }
451 
452  if (ts_subtree_extra(*entry->subtree)) break;
453 
454  const TSFieldMapEntry *field_map, *field_map_end;
456  self->tree->language,
457  parent_entry->subtree->ptr->production_id,
458  &field_map, &field_map_end
459  );
460  for (const TSFieldMapEntry *i = field_map; i < field_map_end; i++) {
461  if (!i->inherited && i->child_index == entry->structural_child_index) {
462  return i->field_id;
463  }
464  }
465  }
466  return 0;
467 }
static TSSymbol ts_language_alias_at(const TSLanguage *self, uint32_t production_id, uint32_t child_index)
Definition: language.h:236
uint16_t production_id
Definition: subtree.h:140
const Subtree * subtree
Definition: tree_cursor.h:7
Definition: zipcmp.c:77
static bool ts_subtree_visible(Subtree self)
Definition: subtree.h:214

References i, SubtreeHeapData::production_id, Subtree::ptr, TreeCursorEntry::subtree, ts_language_alias_at(), ts_language_field_map(), ts_subtree_extra(), and ts_subtree_visible().

Referenced by ts_tree_cursor_current_field_id_wasm(), and ts_tree_cursor_current_field_name().

◆ ts_tree_cursor_current_field_name()

const char* ts_tree_cursor_current_field_name ( const TSTreeCursor _self)

Get the field name of the tree cursor's current node.

This returns NULL if the current node doesn't have a field. See also ts_node_child_by_field_name.

Definition at line 469 of file tree_cursor.c.

469  {
471  if (id) {
472  const TreeCursor *self = (const TreeCursor *)_self;
473  return self->tree->language->field_names[id];
474  } else {
475  return NULL;
476  }
477 }
TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self)
Definition: tree_cursor.c:431

References id, NULL, TSTreeCursor::tree, and ts_tree_cursor_current_field_id().

◆ ts_tree_cursor_current_node()

TSNode ts_tree_cursor_current_node ( const TSTreeCursor _self)

Get the tree cursor's current node.

Definition at line 262 of file tree_cursor.c.

262  {
263  const TreeCursor *self = (const TreeCursor *)_self;
264  TreeCursorEntry *last_entry = array_back(&self->stack);
265  TSSymbol alias_symbol = 0;
266  if (self->stack.size > 1 && !ts_subtree_extra(*last_entry->subtree)) {
267  TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];
268  alias_symbol = ts_language_alias_at(
269  self->tree->language,
270  parent_entry->subtree->ptr->production_id,
271  last_entry->structural_child_index
272  );
273  }
274  return ts_node_new(
275  self->tree,
276  last_entry->subtree,
277  last_entry->position,
278  alias_symbol
279  );
280 }
TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias)
Definition: node.c:17
Length position
Definition: tree_cursor.h:8
uint32_t structural_child_index
Definition: tree_cursor.h:10

References array_back, TreeCursorEntry::position, SubtreeHeapData::production_id, Subtree::ptr, TreeCursorEntry::structural_child_index, TreeCursorEntry::subtree, ts_language_alias_at(), ts_node_new(), and ts_subtree_extra().

Referenced by ts_node_children_wasm(), ts_node_descendants_of_type_wasm(), ts_node_named_children_wasm(), ts_query_cursor__advance(), ts_tree_cursor_current_node_id_wasm(), ts_tree_cursor_current_node_is_missing_wasm(), ts_tree_cursor_current_node_is_named_wasm(), ts_tree_cursor_current_node_type_id_wasm(), ts_tree_cursor_current_node_wasm(), ts_tree_cursor_end_index_wasm(), ts_tree_cursor_end_position_wasm(), ts_tree_cursor_start_index_wasm(), and ts_tree_cursor_start_position_wasm().

◆ ts_tree_cursor_delete()

void ts_tree_cursor_delete ( TSTreeCursor _self)

Delete a tree cursor, freeing all of the memory that it used.

Definition at line 94 of file tree_cursor.c.

94  {
95  TreeCursor *self = (TreeCursor *)_self;
96  array_delete(&self->stack);
97 }

References array_delete.

Referenced by ts_query_cursor_delete(), and ts_tree_cursor_delete_wasm().

◆ ts_tree_cursor_goto_first_child()

bool ts_tree_cursor_goto_first_child ( TSTreeCursor _self)

Move the cursor to the first child of its current node.

This returns true if the cursor successfully moved, and returns false if there were no children.

Definition at line 101 of file tree_cursor.c.

101  {
102  TreeCursor *self = (TreeCursor *)_self;
103 
104  bool did_descend;
105  do {
106  did_descend = false;
107 
108  bool visible;
111  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
112  if (visible) {
113  array_push(&self->stack, entry);
114  return true;
115  }
116 
117  if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
118  array_push(&self->stack, entry);
119  did_descend = true;
120  break;
121  }
122  }
123  } while (did_descend);
124 
125  return false;
126 }
static uint32_t ts_subtree_visible_child_count(Subtree self)
Definition: subtree.h:294
static CursorChildIterator ts_tree_cursor_iterate_children(const TreeCursor *self)
Definition: tree_cursor.c:18
static bool ts_tree_cursor_child_iterator_next(CursorChildIterator *self, TreeCursorEntry *result, bool *visible)
Definition: tree_cursor.c:37

References array_push, ts_subtree_visible_child_count(), ts_tree_cursor_child_iterator_next(), and ts_tree_cursor_iterate_children().

Referenced by ts_node_children_wasm(), ts_node_descendants_of_type_wasm(), ts_node_named_children_wasm(), ts_query_cursor__advance(), ts_tree_cursor_goto_first_child_wasm(), and ts_tree_cursor_goto_next_sibling().

◆ ts_tree_cursor_goto_first_child_for_byte()

int64_t ts_tree_cursor_goto_first_child_for_byte ( TSTreeCursor _self,
uint32_t  goal_byte 
)

Move the cursor to the first child of its current node that extends beyond the given byte offset or point.

This returns the index of the child node if one was found, and returns -1 if no such child was found.

Definition at line 128 of file tree_cursor.c.

128  {
129  TreeCursor *self = (TreeCursor *)_self;
130  uint32_t initial_size = self->stack.size;
131  uint32_t visible_child_index = 0;
132 
133  bool did_descend;
134  do {
135  did_descend = false;
136 
137  bool visible;
140  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
141  uint32_t end_byte = entry.position.bytes + ts_subtree_size(*entry.subtree).bytes;
142  bool at_goal = end_byte >= goal_byte;
143  uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
144 
145  if (at_goal) {
146  if (visible) {
147  array_push(&self->stack, entry);
148  return visible_child_index;
149  }
150 
151  if (visible_child_count > 0) {
152  array_push(&self->stack, entry);
153  did_descend = true;
154  break;
155  }
156  } else if (visible) {
157  visible_child_index++;
158  } else {
159  visible_child_index += visible_child_count;
160  }
161  }
162  } while (did_descend);
163 
164  self->stack.size = initial_size;
165  return -1;
166 }

References array_push, Length::bytes, ts_subtree_size(), ts_subtree_visible_child_count(), ts_tree_cursor_child_iterator_next(), and ts_tree_cursor_iterate_children().

◆ ts_tree_cursor_goto_first_child_for_point()

int64_t ts_tree_cursor_goto_first_child_for_point ( TSTreeCursor _self,
TSPoint  goal_point 
)

Definition at line 168 of file tree_cursor.c.

168  {
169  TreeCursor *self = (TreeCursor *)_self;
170  uint32_t initial_size = self->stack.size;
171  uint32_t visible_child_index = 0;
172 
173  bool did_descend;
174  do {
175  did_descend = false;
176 
177  bool visible;
180  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
181  TSPoint end_point = point_add(entry.position.extent, ts_subtree_size(*entry.subtree).extent);
182  bool at_goal = point_gte(end_point, goal_point);
183  uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
184  if (at_goal) {
185  if (visible) {
186  array_push(&self->stack, entry);
187  return visible_child_index;
188  }
189  if (visible_child_count > 0) {
190  array_push(&self->stack, entry);
191  did_descend = true;
192  break;
193  }
194  } else if (visible) {
195  visible_child_index++;
196  } else {
197  visible_child_index += visible_child_count;
198  }
199  }
200  } while (did_descend);
201 
202  self->stack.size = initial_size;
203  return -1;
204 }
static bool point_gte(TSPoint a, TSPoint b)
Definition: point.h:40

References array_push, Length::extent, point_add(), point_gte(), ts_subtree_size(), ts_subtree_visible_child_count(), ts_tree_cursor_child_iterator_next(), and ts_tree_cursor_iterate_children().

◆ ts_tree_cursor_goto_next_sibling()

bool ts_tree_cursor_goto_next_sibling ( TSTreeCursor _self)

Move the cursor to the next sibling of its current node.

This returns true if the cursor successfully moved, and returns false if there was no next sibling node.

Definition at line 206 of file tree_cursor.c.

206  {
207  TreeCursor *self = (TreeCursor *)_self;
208  uint32_t initial_size = self->stack.size;
209 
210  while (self->stack.size > 1) {
211  TreeCursorEntry entry = array_pop(&self->stack);
213  iterator.child_index = entry.child_index;
214  iterator.structural_child_index = entry.structural_child_index;
215  iterator.position = entry.position;
216 
217  bool visible = false;
219  if (visible && self->stack.size + 1 < initial_size) break;
220 
221  while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
222  if (visible) {
223  array_push(&self->stack, entry);
224  return true;
225  }
226 
227  if (ts_subtree_visible_child_count(*entry.subtree)) {
228  array_push(&self->stack, entry);
230  return true;
231  }
232  }
233  }
234 
235  self->stack.size = initial_size;
236  return false;
237 }
#define array_pop(self)
Definition: array.h:82
bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self)
Definition: tree_cursor.c:101

References array_pop, array_push, ts_subtree_visible_child_count(), ts_tree_cursor_child_iterator_next(), ts_tree_cursor_goto_first_child(), and ts_tree_cursor_iterate_children().

Referenced by ts_node_children_wasm(), ts_node_descendants_of_type_wasm(), ts_node_named_children_wasm(), ts_query_cursor__advance(), and ts_tree_cursor_goto_next_sibling_wasm().

◆ ts_tree_cursor_goto_parent()

bool ts_tree_cursor_goto_parent ( TSTreeCursor _self)

Move the cursor to the parent of its current node.

This returns true if the cursor successfully moved, and returns false if there was no parent node (the cursor was already on the root node).

Definition at line 239 of file tree_cursor.c.

239  {
240  TreeCursor *self = (TreeCursor *)_self;
241  for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
242  TreeCursorEntry *entry = &self->stack.contents[i];
243  if (ts_subtree_visible(*entry->subtree)) {
244  self->stack.size = i + 1;
245  return true;
246  }
247  if (i > 0 && !ts_subtree_extra(*entry->subtree)) {
248  TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
250  self->tree->language,
251  parent_entry->subtree->ptr->production_id,
252  entry->structural_child_index
253  )) {
254  self->stack.size = i + 1;
255  return true;
256  }
257  }
258  }
259  return false;
260 }
zip_uint64_t size
Definition: zipcmp.c:79

References i, SubtreeHeapData::production_id, Subtree::ptr, entry::size, TreeCursorEntry::subtree, ts_language_alias_at(), ts_subtree_extra(), and ts_subtree_visible().

Referenced by ts_node_descendants_of_type_wasm(), ts_query_cursor__advance(), and ts_tree_cursor_goto_parent_wasm().

◆ ts_tree_cursor_new()

TSTreeCursor ts_tree_cursor_new ( TSNode  node)

Create a new tree cursor starting from the given node.

A tree cursor allows you to walk a syntax tree more efficiently than is possible using the TSNode functions. It is a mutable object that is always on a certain syntax node, and can be moved imperatively to different nodes.

Definition at line 70 of file tree_cursor.c.

70  {
71  TSTreeCursor self = {NULL, NULL, {0, 0}};
72  ts_tree_cursor_init((TreeCursor *)&self, node);
73  return self;
74 }
void ts_tree_cursor_init(TreeCursor *self, TSNode node)
Definition: tree_cursor.c:80

References NULL, and ts_tree_cursor_init().

Referenced by ts_tree_cursor_new_wasm().

◆ ts_tree_cursor_reset()

void ts_tree_cursor_reset ( TSTreeCursor _self,
TSNode  node 
)

Re-initialize a tree cursor to start at a different node.

Definition at line 76 of file tree_cursor.c.

76  {
77  ts_tree_cursor_init((TreeCursor *)_self, node);
78 }

References ts_tree_cursor_init().

Referenced by ts_node_children_wasm(), ts_node_descendants_of_type_wasm(), ts_node_named_children_wasm(), ts_query_cursor_exec(), and ts_tree_cursor_reset_wasm().

◆ ts_tree_delete()

void ts_tree_delete ( TSTree self)

Delete the syntax tree, freeing all of the memory that it used.

Definition at line 26 of file tree.c.

26  {
27  if (!self) return;
28 
30  ts_subtree_release(&pool, self->root);
32  ts_free(self->included_ranges);
33  ts_free(self);
34 }

References ts_free, ts_subtree_pool_delete(), ts_subtree_pool_new(), and ts_subtree_release().

Referenced by core_cmd_tsrzcmd(), guess_data_free(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), substitute_args_do(), substitute_args_fini(), and type_parse_string().

◆ ts_tree_edit()

void ts_tree_edit ( TSTree self,
const TSInputEdit edit 
)

Edit the syntax tree to keep it in sync with source code that has been edited.

You must describe the edit both in terms of byte offsets and in terms of (row, column) coordinates.

Definition at line 44 of file tree.c.

44  {
45  for (unsigned i = 0; i < self->included_range_count; i++) {
46  TSRange *range = &self->included_ranges[i];
47  if (range->end_byte >= edit->old_end_byte) {
48  if (range->end_byte != UINT32_MAX) {
49  range->end_byte = edit->new_end_byte + (range->end_byte - edit->old_end_byte);
50  range->end_point = point_add(
51  edit->new_end_point,
52  point_sub(range->end_point, edit->old_end_point)
53  );
54  if (range->end_byte < edit->new_end_byte) {
55  range->end_byte = UINT32_MAX;
56  range->end_point = POINT_MAX;
57  }
58  }
59  if (range->start_byte >= edit->old_end_byte) {
60  range->start_byte = edit->new_end_byte + (range->start_byte - edit->old_end_byte);
61  range->start_point = point_add(
62  edit->new_end_point,
63  point_sub(range->start_point, edit->old_end_point)
64  );
65  if (range->start_byte < edit->new_end_byte) {
66  range->start_byte = UINT32_MAX;
67  range->start_point = POINT_MAX;
68  }
69  }
70  }
71  }
72 
74  self->root = ts_subtree_edit(self->root, edit, &pool);
76 }
Subtree ts_subtree_edit(Subtree self, const TSInputEdit *edit, SubtreePool *pool)
Definition: subtree.c:640

References i, TSInputEdit::new_end_byte, TSInputEdit::new_end_point, TSInputEdit::old_end_byte, TSInputEdit::old_end_point, point_add(), POINT_MAX, point_sub(), capstone::range, ts_subtree_edit(), ts_subtree_pool_delete(), ts_subtree_pool_new(), and UINT32_MAX.

Referenced by ts_tree_edit_wasm().

◆ ts_tree_get_changed_ranges()

TSRange* ts_tree_get_changed_ranges ( const TSTree old_tree,
const TSTree new_tree,
uint32_t length 
)

Compare an old edited syntax tree to a new syntax tree representing the same document, returning an array of ranges whose syntactic structure has changed.

For this to work correctly, the old syntax tree must have been edited such that its ranges match up to the new tree. Generally, you'll want to call this function right after calling one of the ts_parser_parse functions. You need to pass the old tree that was passed to parse, as well as the new tree that was returned from that function.

The returned array is allocated using malloc and the caller is responsible for freeing it using free. The length of the array will be written to the given length pointer.

Definition at line 78 of file tree.c.

78  {
79  TreeCursor cursor1 = {NULL, array_new()};
80  TreeCursor cursor2 = {NULL, array_new()};
81  ts_tree_cursor_init(&cursor1, ts_tree_root_node(self));
82  ts_tree_cursor_init(&cursor2, ts_tree_root_node(other));
83 
84  TSRangeArray included_range_differences = array_new();
86  self->included_ranges, self->included_range_count,
87  other->included_ranges, other->included_range_count,
88  &included_range_differences
89  );
90 
91  TSRange *result;
93  &self->root, &other->root, &cursor1, &cursor2,
94  self->language, &included_range_differences, &result
95  );
96 
97  array_delete(&included_range_differences);
98  array_delete(&cursor1.stack);
99  array_delete(&cursor2.stack);
100  return result;
101 }
unsigned ts_subtree_get_changed_ranges(const Subtree *old_tree, const Subtree *new_tree, TreeCursor *cursor1, TreeCursor *cursor2, const TSLanguage *language, const TSRangeArray *included_range_differences, TSRange **ranges)
TSNode ts_tree_root_node(const TSTree *self)
Definition: tree.c:36

References array_delete, array_new, count, TSTree::included_range_count, TSTree::included_ranges, NULL, TSTree::root, ts_range_array_get_changed_ranges(), ts_subtree_get_changed_ranges(), ts_tree_cursor_init(), and ts_tree_root_node().

Referenced by ts_tree_get_changed_ranges_wasm().

◆ ts_tree_language()

const TSLanguage* ts_tree_language ( const TSTree self)

Get the language that was used to parse the syntax tree.

Definition at line 40 of file tree.c.

40  {
41  return self->language;
42 }

◆ ts_tree_print_dot_graph()

void ts_tree_print_dot_graph ( const TSTree self,
FILE *  file 
)

Write a DOT graph describing the syntax tree to the given file.

Definition at line 103 of file tree.c.

103  {
105 }
Definition: gzappend.c:170
void ts_subtree_print_dot_graph(Subtree self, const TSLanguage *language, FILE *f)
Definition: subtree.c:1020

References ts_subtree_print_dot_graph().

◆ ts_tree_root_node()

TSNode ts_tree_root_node ( const TSTree self)

Get the root node of the syntax tree.

Definition at line 36 of file tree.c.

36  {
37  return ts_node_new(self, &self->root, ts_subtree_padding(self->root), 0);
38 }
static Length ts_subtree_padding(Subtree self)
Definition: subtree.h:256

References ts_node_new(), and ts_subtree_padding().

Referenced by core_cmd_tsrzcmd(), guess_next_autocmplt_token(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), substitute_args_do(), ts_node_parent(), ts_tree_get_changed_ranges(), ts_tree_root_node_wasm(), and type_parse_string().