Skip to content

Commit

Permalink
feat(node): add child_containing_descendant
Browse files Browse the repository at this point in the history
  • Loading branch information
ObserverOfTime committed Aug 22, 2024
1 parent 9e3806b commit 722862b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/classes/tree_sitter.Node.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Node
.. automethod:: child
.. automethod:: child_by_field_id
.. automethod:: child_by_field_name
.. automethod:: child_containing_descendant

.. versionadded:: 0.23.0
.. automethod:: children_by_field_id
.. automethod:: children_by_field_name
.. automethod:: descendant_for_byte_range
Expand Down
1 change: 1 addition & 0 deletions tree_sitter/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class Node:
def named_child(self, index: int, /) -> Node | None: ...
def child_by_field_id(self, id: int, /) -> Node | None: ...
def child_by_field_name(self, name: str, /) -> Node | None: ...
def child_containing_descendant(self, descendant: Node, /) -> Node | None: ...
def children_by_field_id(self, id: int, /) -> list[Node]: ...
def children_by_field_name(self, name: str, /) -> list[Node]: ...
def field_name_for_child(self, child_index: int, /) -> str | None: ...
Expand Down
27 changes: 25 additions & 2 deletions tree_sitter/binding/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,20 @@ PyObject *node_named_descendant_for_point_range(Node *self, PyObject *args) {
return node_new_internal(state, descendant, self->tree);
}

PyObject *node_child_containing_descendant(Node *self, PyObject *args) {
ModuleState *state = GET_MODULE_STATE(self);
TSNode descendant;
if (!PyArg_ParseTuple(args, "O!:child_containing_descendant", &descendant, state->node_type)) {
return NULL;
}

TSNode child = ts_node_child_containing_descendant(self->node, descendant);
if (ts_node_is_null(child)) {
Py_RETURN_NONE;
}
return node_new_internal(state, child, self->tree);
}

PyObject *node_get_id(Node *self, void *Py_UNUSED(payload)) {
return PyLong_FromVoidPtr((void *)self->node.id);
}
Expand Down Expand Up @@ -578,7 +592,7 @@ PyDoc_STRVAR(node_child_by_field_id_doc,
PyDoc_STRVAR(node_children_by_field_id_doc,
"children_by_field_id(self, id, /)\n--\n\n"
"Get a list of children with the given numerical field id."
DOC_SEE_ALSO ":meth:`children_by_field_name`" );
DOC_SEE_ALSO ":meth:`children_by_field_name`");
PyDoc_STRVAR(node_child_by_field_name_doc, "child_by_field_name(self, name, /)\n--\n\n"
"Get the first child with the given field name.");
PyDoc_STRVAR(node_children_by_field_name_doc, "children_by_field_name(self, name, /)\n--\n\n"
Expand All @@ -598,6 +612,9 @@ PyDoc_STRVAR(node_descendant_for_point_range_doc,
PyDoc_STRVAR(node_named_descendant_for_point_range_doc,
"named_descendant_for_point_range(self, start_point, end_point, /)\n--\n\n"
"Get the smallest *named* node within this node that spans the given point range.");
PyDoc_STRVAR(node_child_containing_descendant_doc,
"child_containing_descendant(self, descendant, /)\n--\n\n"
"Get the child of the node that contains the given descendant.");

static PyMethodDef node_methods[] = {
{
Expand Down Expand Up @@ -678,6 +695,12 @@ static PyMethodDef node_methods[] = {
.ml_flags = METH_VARARGS,
.ml_doc = node_named_descendant_for_point_range_doc,
},
{
.ml_name = "child_containing_descendant",
.ml_meth = (PyCFunction)node_child_containing_descendant,
.ml_flags = METH_VARARGS,
.ml_doc = node_child_containing_descendant_doc,
},
{NULL},
};

Expand All @@ -702,7 +725,7 @@ static PyGetSetDef node_accessors[] = {
NULL},
{"is_extra", (getter)node_get_is_extra, NULL,
PyDoc_STR("Check if this node is _extra_.\n\nExtra nodes represent things which are not "
"required the grammar but can appear anywhere (e.g. whitespace)."),
"required by the grammar but can appear anywhere (e.g. whitespace)."),
NULL},
{"has_changes", (getter)node_get_has_changes, NULL,
PyDoc_STR("Check if this node has been edited."), NULL},
Expand Down

0 comments on commit 722862b

Please sign in to comment.