Merge pull request #181 from tree-sitter/new-apis

Add some APIs
This commit is contained in:
Max Brunsfeld 2018-06-24 15:48:24 -07:00 committed by GitHub
commit 4f5a87b952
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 56 additions and 37 deletions

View file

@ -68,7 +68,7 @@ typedef struct {
typedef struct {
uint32_t context[4];
const void *id;
const void *tree;
const TSTree *tree;
} TSNode;
typedef struct {
@ -101,6 +101,7 @@ TSNode ts_tree_root_node(const TSTree *);
void ts_tree_edit(TSTree *, const TSInputEdit *);
TSRange *ts_tree_get_changed_ranges(const TSTree *, const TSTree *, uint32_t *);
void ts_tree_print_dot_graph(const TSTree *, FILE *);
const TSLanguage *ts_tree_language(const TSTree *);
uint32_t ts_node_start_byte(TSNode);
TSPoint ts_node_start_point(TSNode);
@ -131,7 +132,7 @@ TSNode ts_node_named_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_point_range(TSNode, TSPoint, TSPoint);
TSTreeCursor ts_tree_cursor_new(const TSTree *);
TSTreeCursor ts_tree_cursor_new(TSNode);
void ts_tree_cursor_delete(TSTreeCursor *);
bool ts_tree_cursor_goto_first_child(TSTreeCursor *);
int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *, uint32_t);
@ -141,6 +142,7 @@ TSNode ts_tree_cursor_current_node(const TSTreeCursor *);
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 *, const char *);
TSSymbolType ts_language_symbol_type(const TSLanguage *, TSSymbol);
uint32_t ts_language_version(const TSLanguage *);

View file

@ -1,6 +1,7 @@
#include "runtime/language.h"
#include "runtime/subtree.h"
#include "runtime/error_costs.h"
#include <string.h>
void ts_language_table_entry(const TSLanguage *self, TSStateId state,
TSSymbol symbol, TableEntry *result) {
@ -46,6 +47,15 @@ const char *ts_language_symbol_name(const TSLanguage *language, TSSymbol symbol)
}
}
TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *name) {
for (TSSymbol i = 0; i < self->symbol_count; i++) {
if (!strcmp(self->symbol_names[i], name)) {
return i;
}
}
return 0;
}
TSSymbolType ts_language_symbol_type(const TSLanguage *language, TSSymbol symbol) {
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
if (metadata.named) {

View file

@ -44,21 +44,16 @@ static inline const Subtree *ts_node__subtree(TSNode self) {
return self.id;
}
static inline const TSTree *ts_node__tree(const TSNode *self) {
return self->tree;
}
// ChildIterator
static inline ChildIterator ts_node_iterate_children(const TSNode *node) {
const TSTree *tree = ts_node__tree(node);
const Subtree *subtree = ts_node__subtree(*node);
const TSSymbol *alias_sequence = ts_language_alias_sequence(
tree->language,
node->tree->language,
subtree->alias_sequence_id
);
return (ChildIterator) {
.tree = tree,
.tree = node->tree,
.parent = subtree,
.position = {ts_node_start_byte(*node), ts_node_start_point(*node)},
.child_index = 0,
@ -103,7 +98,7 @@ static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous) {
(
ts_node__alias(&self) &&
ts_language_symbol_metadata(
ts_node__tree(&self)->language,
self.tree->language,
ts_node__alias(&self)
).named
)
@ -125,7 +120,6 @@ static inline uint32_t ts_node__relevant_child_count(TSNode self, bool include_a
}
static inline TSNode ts_node__child(TSNode self, uint32_t child_index, bool include_anonymous) {
const TSTree *tree = ts_node__tree(&self);
TSNode result = self;
bool did_descend = true;
@ -138,7 +132,7 @@ static inline TSNode ts_node__child(TSNode self, uint32_t child_index, bool incl
while (ts_node_child_iterator_next(&iterator, &child)) {
if (ts_node__is_relevant(child, include_anonymous)) {
if (index == child_index) {
ts_tree_set_cached_parent(tree, &child, &self);
ts_tree_set_cached_parent(self.tree, &child, &self);
return child;
}
index++;
@ -294,7 +288,6 @@ static inline TSNode ts_node__descendant_for_byte_range(TSNode self, uint32_t mi
bool include_anonymous) {
TSNode node = self;
TSNode last_visible_node = self;
const TSTree *tree = ts_node__tree(&self);
bool did_descend = true;
while (did_descend) {
@ -307,7 +300,7 @@ static inline TSNode ts_node__descendant_for_byte_range(TSNode self, uint32_t mi
if (ts_node_start_byte(child) > min) break;
node = child;
if (ts_node__is_relevant(node, include_anonymous)) {
ts_tree_set_cached_parent(tree, &child, &last_visible_node);
ts_tree_set_cached_parent(self.tree, &child, &last_visible_node);
last_visible_node = node;
}
did_descend = true;
@ -324,7 +317,6 @@ static inline TSNode ts_node__descendant_for_point_range(TSNode self, TSPoint mi
bool include_anonymous) {
TSNode node = self;
TSNode last_visible_node = self;
const TSTree *tree = ts_node__tree(&self);
bool did_descend = true;
while (did_descend) {
@ -337,7 +329,7 @@ static inline TSNode ts_node__descendant_for_point_range(TSNode self, TSPoint mi
if (point_gt(ts_node_start_point(child), min)) break;
node = child;
if (ts_node__is_relevant(node, include_anonymous)) {
ts_tree_set_cached_parent(tree, &child, &last_visible_node);
ts_tree_set_cached_parent(self.tree, &child, &last_visible_node);
last_visible_node = node;
}
did_descend = true;
@ -365,11 +357,11 @@ TSSymbol ts_node_symbol(TSNode self) {
}
const char *ts_node_type(TSNode self) {
return ts_language_symbol_name(ts_node__tree(&self)->language, ts_node_symbol(self));
return ts_language_symbol_name(self.tree->language, ts_node_symbol(self));
}
char *ts_node_string(TSNode self) {
return ts_subtree_string(ts_node__subtree(self), ts_node__tree(&self)->language, false);
return ts_subtree_string(ts_node__subtree(self), self.tree->language, false);
}
bool ts_node_eq(TSNode self, TSNode other) {
@ -383,7 +375,7 @@ bool ts_node_is_null(TSNode self) {
bool ts_node_is_named(TSNode self) {
const Subtree *tree = ts_node__subtree(self);
return ts_node__alias(&self)
? ts_language_symbol_metadata(ts_node__tree(&self)->language, ts_node__alias(&self)).named
? ts_language_symbol_metadata(self.tree->language, ts_node__alias(&self)).named
: tree->named;
}
@ -401,11 +393,10 @@ bool ts_node_has_error(TSNode self) {
}
TSNode ts_node_parent(TSNode self) {
const TSTree *tree = ts_node__tree(&self);
TSNode node = ts_tree_get_cached_parent(tree, &self);
TSNode node = ts_tree_get_cached_parent(self.tree, &self);
if (node.id) return node;
node = ts_tree_root_node(tree);
node = ts_tree_root_node(self.tree);
uint32_t end_byte = ts_node_end_byte(self);
if (ts_node__subtree(node) == ts_node__subtree(self)) return ts_node__null();
@ -424,7 +415,7 @@ TSNode ts_node_parent(TSNode self) {
if (iterator.position.bytes >= end_byte) {
node = child;
if (ts_node__is_relevant(child, true)) {
ts_tree_set_cached_parent(tree, &node, &last_visible_node);
ts_tree_set_cached_parent(self.tree, &node, &last_visible_node);
last_visible_node = node;
}
did_descend = true;

View file

@ -34,6 +34,10 @@ TSNode ts_tree_root_node(const TSTree *self) {
return ts_node_new(self, self->root, self->root->padding, 0);
}
const TSLanguage *ts_tree_language(const TSTree *self) {
return self->language;
}
void ts_tree_edit(TSTree *self, const TSInputEdit *edit) {
SubtreePool pool = ts_subtree_pool_new(0);
self->root = ts_subtree_edit(self->root, edit, &pool);
@ -43,8 +47,9 @@ void ts_tree_edit(TSTree *self, const TSInputEdit *edit) {
TSRange *ts_tree_get_changed_ranges(const TSTree *self, const TSTree *other, uint32_t *count) {
TSRange *result;
TreeCursor cursor1, cursor2;
ts_tree_cursor_init(&cursor1, self);
ts_tree_cursor_init(&cursor2, self);
TSNode root = ts_tree_root_node(self);
ts_tree_cursor_init(&cursor1, root);
ts_tree_cursor_init(&cursor2, root);
*count = ts_subtree_get_changed_ranges(
self->root, other->root, &cursor1, &cursor2,
self->language, &result

View file

@ -46,26 +46,36 @@ static inline bool ts_tree_cursor_child_iterator_next(ChildIterator *self,
if (!child->extra && self->alias_sequence) {
*visible |= self->alias_sequence[self->structural_child_index];
}
self->position = length_add(self->position, ts_subtree_total_size(child));
self->position = length_add(self->position, child->size);
self->child_index++;
if (!child->extra) self->structural_child_index++;
if (self->child_index < self->parent->children.size) {
const Subtree *child = self->parent->children.contents[self->child_index];
self->position = length_add(self->position, child->padding);
}
return true;
}
// TSTreeCursor - lifecycle
TSTreeCursor ts_tree_cursor_new(const TSTree *tree) {
TSTreeCursor ts_tree_cursor_new(TSNode node) {
TSTreeCursor self;
ts_tree_cursor_init((TreeCursor *)&self, tree);
ts_tree_cursor_init((TreeCursor *)&self, node);
return self;
}
void ts_tree_cursor_init(TreeCursor *self, const TSTree *tree) {
self->tree = tree;
void ts_tree_cursor_init(TreeCursor *self, TSNode node) {
self->tree = node.tree;
array_init(&self->stack);
array_push(&self->stack, ((TreeCursorEntry) {
.subtree = tree->root,
.position = length_zero(),
.subtree = (const Subtree *)node.id,
.position = {
ts_node_start_byte(node),
ts_node_start_point(node)
},
.child_index = 0,
.structural_child_index = 0,
}));
@ -118,7 +128,8 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
TreeCursorEntry entry;
ChildIterator iterator = ts_tree_cursor_iterate_children(self);
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
bool at_goal = iterator.position.bytes > goal_byte;
uint32_t end_byte = entry.position.bytes + entry.subtree->size.bytes;
bool at_goal = end_byte > goal_byte;
uint32_t visible_child_count = entry.subtree->children.size > 0
? entry.subtree->visible_child_count
: 0;
@ -208,7 +219,7 @@ TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self) {
return ts_node_new(
self->tree,
last_entry->subtree,
length_add(last_entry->position, last_entry->subtree->padding),
last_entry->position,
alias_symbol
);
}

View file

@ -15,6 +15,6 @@ typedef struct {
const TSTree *tree;
} TreeCursor;
void ts_tree_cursor_init(TreeCursor *, const TSTree *);
void ts_tree_cursor_init(TreeCursor *, TSNode);
#endif // RUNTIME_TREE_CURSOR_H_

View file

@ -556,7 +556,7 @@ describe("TreeCursor", [&]() {
parser = ts_parser_new();
ts_parser_set_language(parser, load_real_language("json"));
tree = ts_parser_parse_string(parser, nullptr, json_string.c_str(), json_string.size());
cursor = ts_tree_cursor_new(tree);
cursor = ts_tree_cursor_new(ts_tree_root_node(tree));
});
after_each([&]() {
@ -728,7 +728,7 @@ describe("TreeCursor", [&]() {
ts_tree_delete(tree);
tree = ts_parser_parse_string(parser, nullptr, "b ... b ... c", 13);
cursor = ts_tree_cursor_new(tree);
cursor = ts_tree_cursor_new(ts_tree_root_node(tree));
TSNode node = ts_tree_cursor_current_node(&cursor);
AssertThat(ts_node_type(node), Equals("a"));