Add APIs for retrieving tree cursor's depth and descendant index

This commit is contained in:
Max Brunsfeld 2023-06-12 11:50:44 -07:00
parent 9dd725b4e3
commit a2119cb691
6 changed files with 47 additions and 28 deletions

View file

@ -615,7 +615,12 @@ extern "C" {
extern "C" {
#[doc = " Get the index of the cursor's current node out of all of the"]
#[doc = " descendants of the original node that the cursor was constructed with."]
pub fn ts_tree_cursor_descendant_index(arg1: *mut TSTreeCursor) -> u32;
pub fn ts_tree_cursor_current_descendant_index(arg1: *const TSTreeCursor) -> u32;
}
extern "C" {
#[doc = " Get the depth of the cursor's current node relative to the original"]
#[doc = " node that the cursor was constructed with."]
pub fn ts_tree_cursor_current_depth(arg1: *const TSTreeCursor) -> u32;
}
extern "C" {
#[doc = " Move the cursor to the first child of its current node that extends beyond"]

View file

@ -1266,6 +1266,21 @@ impl<'a> TreeCursor<'a> {
}
}
/// Get the numerical field id of this tree cursor's current node.
///
/// See also [field_name](TreeCursor::field_name).
#[doc(alias = "ts_tree_cursor_current_depth")]
pub fn depth(&self) -> u32 {
unsafe { ffi::ts_tree_cursor_current_depth(&self.0) }
}
/// Get the index of the cursor's current node out of all of the
/// descendants of the original node that the cursor was constructed with
#[doc(alias = "ts_tree_cursor_current_descendant_index")]
pub fn descendant_index(&self) -> usize {
unsafe { ffi::ts_tree_cursor_current_descendant_index(&self.0) as usize }
}
/// Move this cursor to the first child of its current node.
///
/// This returns `true` if the cursor successfully moved, and returns `false`

View file

@ -12,7 +12,7 @@ WebAssembly bindings to the [Tree-sitter](https://github.com/tree-sitter/tree-si
You can download the `tree-sitter.js` and `tree-sitter.wasm` files from [the latest GitHub release](https://github.com/tree-sitter/tree-sitter/releases/latest) and load them using a standalone script:
```html
<script src="/the/path/to/tree-sitter.js"/>
<script src="/the/path/to/tree-sitter.js"></script>
<script>
const Parser = window.TreeSitter;

View file

@ -689,7 +689,13 @@ void ts_tree_cursor_goto_descendant(TSTreeCursor *, uint32_t);
* Get the index of the cursor's current node out of all of the
* descendants of the original node that the cursor was constructed with.
*/
uint32_t ts_tree_cursor_descendant_index(TSTreeCursor *);
uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *);
/**
* Get the depth of the cursor's current node relative to the original
* node that the cursor was constructed with.
*/
uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *);
/**
* Move the cursor to the first child of its current node that extends beyond

View file

@ -261,22 +261,10 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {
TreeCursor *self = (TreeCursor *)_self;
for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
TreeCursorEntry *entry = &self->stack.contents[i];
if (ts_subtree_visible(*entry->subtree)) {
if (ts_tree_cursor_is_entry_visible(self, i)) {
self->stack.size = i + 1;
return true;
}
if (i > 0 && !ts_subtree_extra(*entry->subtree)) {
TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
if (ts_language_alias_at(
self->tree->language,
parent_entry->subtree->ptr->production_id,
entry->structural_child_index
)) {
self->stack.size = i + 1;
return true;
}
}
}
return false;
}
@ -331,7 +319,7 @@ void ts_tree_cursor_goto_descendant(
} while (did_descend);
}
uint32_t ts_tree_cursor_descendant_index(TSTreeCursor *_self) {
uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *_self) {
const TreeCursor *self = (const TreeCursor *)_self;
TreeCursorEntry *last_entry = array_back(&self->stack);
return last_entry->descendant_index;
@ -479,6 +467,17 @@ void ts_tree_cursor_current_status(
}
}
uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *_self) {
const TreeCursor *self = (const TreeCursor *)_self;
uint32_t depth = 0;
for (unsigned i = 1; i < self->stack.size; i++) {
if (ts_tree_cursor_is_entry_visible(self, i)) {
depth++;
}
}
return depth;
}
TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self) {
const TreeCursor *self = (const TreeCursor *)_self;
for (int i = (int)self->stack.size - 2; i >= 0; i--) {
@ -515,17 +514,10 @@ TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {
TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
// Stop walking up when another visible node is found.
if (i != self->stack.size - 1) {
if (ts_subtree_visible(*entry->subtree)) break;
if (
!ts_subtree_extra(*entry->subtree) &&
ts_language_alias_at(
self->tree->language,
parent_entry->subtree->ptr->production_id,
entry->structural_child_index
)
) break;
}
if (
i != self->stack.size - 1 &&
ts_tree_cursor_is_entry_visible(self, i)
) break;
if (ts_subtree_extra(*entry->subtree)) break;

View file

@ -4,6 +4,7 @@ output_path=lib/binding_rust/bindings.rs
header_path='lib/include/tree_sitter/api.h'
bindgen \
--size_t-is-usize \
--no-layout-tests \
--allowlist-type '^TS.*' \
--allowlist-function '^ts_.*' \