Merge pull request #123 from tree-sitter/child-for-byte
Add methods for finding a child node that spans a given position
This commit is contained in:
commit
e451aaa4b8
3 changed files with 127 additions and 0 deletions
|
|
@ -92,10 +92,13 @@ TSNode ts_node_child(TSNode, uint32_t);
|
|||
TSNode ts_node_named_child(TSNode, uint32_t);
|
||||
uint32_t ts_node_child_count(TSNode);
|
||||
uint32_t ts_node_named_child_count(TSNode);
|
||||
uint32_t ts_node_child_index(TSNode);
|
||||
TSNode ts_node_next_sibling(TSNode);
|
||||
TSNode ts_node_next_named_sibling(TSNode);
|
||||
TSNode ts_node_prev_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_named_descendant_for_byte_range(TSNode, uint32_t, uint32_t);
|
||||
TSNode ts_node_descendant_for_point_range(TSNode, TSPoint, TSPoint);
|
||||
|
|
|
|||
|
|
@ -152,6 +152,31 @@ static inline bool point_gt(TSPoint a, TSPoint b) {
|
|||
return a.row > b.row || (a.row == b.row && a.column > b.column);
|
||||
}
|
||||
|
||||
static inline TSNode ts_node__first_child_for_byte(TSNode self, uint32_t goal,
|
||||
bool include_anonymous) {
|
||||
TSNode node = self;
|
||||
bool did_descend = true;
|
||||
|
||||
while (did_descend) {
|
||||
did_descend = false;
|
||||
|
||||
for (uint32_t i = 0; i < ts_node__tree(node)->child_count; i++) {
|
||||
TSNode child = ts_node__direct_child(node, i);
|
||||
if (ts_node_end_byte(child) > goal) {
|
||||
if (ts_node__is_relevant(child, include_anonymous)) {
|
||||
return child;
|
||||
} else if (ts_node_child_count(child) > 0) {
|
||||
did_descend = true;
|
||||
node = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ts_node__null();
|
||||
}
|
||||
|
||||
static inline TSNode ts_node__descendant_for_byte_range(TSNode self, uint32_t min,
|
||||
uint32_t max,
|
||||
bool include_anonymous) {
|
||||
|
|
@ -304,6 +329,25 @@ TSNode ts_node_parent(TSNode self) {
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32_t ts_node_child_index(TSNode self) {
|
||||
const Tree *tree = ts_node__tree(self);
|
||||
uint32_t result = 0;
|
||||
|
||||
for (;;) {
|
||||
const Tree *parent = tree->context.parent;
|
||||
uint32_t index = tree->context.index;
|
||||
if (!parent) return UINT32_MAX;
|
||||
for (uint32_t i = 0; i < index; i++) {
|
||||
Tree *child = parent->children[i];
|
||||
result += child->visible ? 1 : child->visible_child_count;
|
||||
}
|
||||
if (parent->visible) break;
|
||||
tree = parent;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TSNode ts_node_child(TSNode self, uint32_t child_index) {
|
||||
return ts_node__child(self, child_index, true);
|
||||
}
|
||||
|
|
@ -346,6 +390,14 @@ TSNode ts_node_prev_named_sibling(TSNode self) {
|
|||
return ts_node__prev_sibling(self, false);
|
||||
}
|
||||
|
||||
TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) {
|
||||
return ts_node__first_child_for_byte(self, byte, true);
|
||||
}
|
||||
|
||||
TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) {
|
||||
return ts_node__first_child_for_byte(self, byte, false);
|
||||
}
|
||||
|
||||
TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t min, uint32_t max) {
|
||||
return ts_node__descendant_for_byte_range(self, min, max, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,6 +183,78 @@ describe("Node", [&]() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("first_child_for_byte(byte_offset)", [&]() {
|
||||
it("returns the first child that extends beyond the given byte offset", [&]() {
|
||||
TSNode child;
|
||||
|
||||
child = ts_node_first_child_for_byte(root_node, array_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("["));
|
||||
child = ts_node_first_child_for_byte(root_node, number_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("number"));
|
||||
child = ts_node_first_child_for_byte(root_node, number_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals(","));
|
||||
child = ts_node_first_child_for_byte(root_node, number_end_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_child_for_byte(root_node, false_index - 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_child_for_byte(root_node, false_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_child_for_byte(root_node, false_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_child_for_byte(root_node, false_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals(","));
|
||||
child = ts_node_first_child_for_byte(root_node, false_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals(","));
|
||||
child = ts_node_first_child_for_byte(root_node, object_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("object"));
|
||||
child = ts_node_first_child_for_byte(root_node, object_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("object"));
|
||||
child = ts_node_first_child_for_byte(root_node, object_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("]"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("first_named_child_for_byte(byte_offset)", [&]() {
|
||||
it("returns the first named child that extends beyond the given byte offset", [&]() {
|
||||
TSNode child;
|
||||
|
||||
child = ts_node_first_named_child_for_byte(root_node, array_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("number"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, number_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("number"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, number_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, number_end_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, false_index - 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, false_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, false_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("false"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, false_end_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("object"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, object_index);
|
||||
AssertThat(ts_node_type(child, document), Equals("object"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, object_index + 1);
|
||||
AssertThat(ts_node_type(child, document), Equals("object"));
|
||||
child = ts_node_first_named_child_for_byte(root_node, object_end_index);
|
||||
AssertThat(child.data, Equals<void *>(nullptr));
|
||||
});
|
||||
});
|
||||
|
||||
describe("child_index()", [&]() {
|
||||
it("returns the index of the node within its parent", [&]() {
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 0)), Equals(0u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 1)), Equals(1u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 2)), Equals(2u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 3)), Equals(3u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 4)), Equals(4u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 5)), Equals(5u));
|
||||
AssertThat(ts_node_child_index(ts_node_child(root_node, 6)), Equals(6u));
|
||||
});
|
||||
});
|
||||
|
||||
describe("symbols()", [&]() {
|
||||
it("returns an iterator that yields each of the node's symbols", [&]() {
|
||||
const TSLanguage *language = ts_document_language(document);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue