Remove document parameter from ts_node_type, ts_node_string
Co-Authored-By: Rick Winfrey <rewinfrey@github.com>
This commit is contained in:
parent
92255bbfdd
commit
666dfb76d2
9 changed files with 339 additions and 53 deletions
134
src/runtime/tree_cursor.c
Normal file
134
src/runtime/tree_cursor.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include "tree_sitter/runtime.h"
|
||||
#include "runtime/alloc.h"
|
||||
#include "runtime/tree_cursor.h"
|
||||
#include "runtime/document.h"
|
||||
#include "runtime/language.h"
|
||||
|
||||
TSTreeCursor *ts_tree_cursor_new(const TSDocument *document) {
|
||||
TSTreeCursor *self = ts_malloc(sizeof(TSTreeCursor));
|
||||
self->document = document;
|
||||
array_init(&self->stack);
|
||||
array_push(&self->stack, ((TreeCursorEntry) {
|
||||
.tree = document->tree,
|
||||
.position = length_zero(),
|
||||
.child_index = 0,
|
||||
.structural_child_index = 0,
|
||||
}));
|
||||
return self;
|
||||
}
|
||||
|
||||
void ts_tree_cursor_delete(TSTreeCursor *self) {
|
||||
array_delete(&self->stack);
|
||||
ts_free(self);
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) {
|
||||
TreeCursorEntry *last_entry = array_back(&self->stack);
|
||||
Tree *tree = last_entry->tree;
|
||||
Length position = last_entry->position;
|
||||
|
||||
bool did_descend;
|
||||
do {
|
||||
did_descend = false;
|
||||
|
||||
uint32_t structural_child_index = 0;
|
||||
for (uint32_t i = 0; i < tree->children.size; i++) {
|
||||
Tree *child = tree->children.contents[i];
|
||||
if (child->visible || child->visible_child_count > 0) {
|
||||
array_push(&self->stack, ((TreeCursorEntry) {
|
||||
.tree = child,
|
||||
.child_index = i,
|
||||
.structural_child_index = structural_child_index,
|
||||
.position = position,
|
||||
}));
|
||||
|
||||
if (child->visible) {
|
||||
return true;
|
||||
} else {
|
||||
tree = child;
|
||||
did_descend = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!child->extra) structural_child_index++;
|
||||
position = length_add(position, ts_tree_total_size(child));
|
||||
}
|
||||
} while (did_descend);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
|
||||
TreeCursorEntry *child_entry = array_back(&self->stack);
|
||||
|
||||
for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
|
||||
TreeCursorEntry *parent_entry = &self->stack.contents[i];
|
||||
|
||||
Tree *parent = parent_entry->tree;
|
||||
uint32_t child_index = child_entry->child_index;
|
||||
uint32_t structural_child_index = child_entry->structural_child_index;
|
||||
Length position = child_entry->position;
|
||||
Tree *child = parent->children.contents[child_index];
|
||||
|
||||
while (++child_index < parent->children.size) {
|
||||
if (!child->extra) structural_child_index++;
|
||||
position = length_add(position, ts_tree_total_size(child));
|
||||
child = parent->children.contents[child_index];
|
||||
|
||||
if (child->visible || child->visible_child_count > 0) {
|
||||
self->stack.contents[i + 1] = (TreeCursorEntry) {
|
||||
.tree = child,
|
||||
.child_index = child_index,
|
||||
.structural_child_index = structural_child_index,
|
||||
.position = position,
|
||||
};
|
||||
self->stack.size = i + 2;
|
||||
|
||||
if (child->visible) {
|
||||
return true;
|
||||
} else {
|
||||
ts_tree_cursor_goto_first_child(self);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child_entry = parent_entry;
|
||||
if (parent->visible) break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_parent(TSTreeCursor *self) {
|
||||
for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
|
||||
TreeCursorEntry *entry = &self->stack.contents[i];
|
||||
if (entry->tree->visible) {
|
||||
self->stack.size = i + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TSNode ts_tree_cursor_current_node(TSTreeCursor *self) {
|
||||
TreeCursorEntry *last_entry = array_back(&self->stack);
|
||||
TSSymbol alias_symbol = 0;
|
||||
if (self->stack.size > 1) {
|
||||
TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];
|
||||
const TSSymbol *alias_sequence = ts_language_alias_sequence(
|
||||
self->document->parser.language,
|
||||
parent_entry->tree->alias_sequence_id
|
||||
);
|
||||
if (alias_sequence) {
|
||||
alias_symbol = alias_sequence[last_entry->structural_child_index];
|
||||
}
|
||||
}
|
||||
return (TSNode) {
|
||||
.document = self->document,
|
||||
.subtree = last_entry->tree,
|
||||
.position = last_entry->position.extent,
|
||||
.byte = last_entry->position.bytes,
|
||||
.alias_symbol = alias_symbol,
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue