Fix tree-sitter traversal slowness (bug#80108)
* configure.ac (LIBSYSTEMD_CFLAGS): Increase minimal required tree-sitter version to 0.20.10. * src/treesit.c (treesit_traverse_sibling_helper): When traversing forward, use the new function ts_tree_cursor_goto_previous_sibling.
This commit is contained in:
parent
32cffe1707
commit
69dc5d3f0e
2 changed files with 10 additions and 70 deletions
32
configure.ac
32
configure.ac
|
|
@ -4069,39 +4069,15 @@ TREE_SITTER_OBJ=
|
|||
NEED_DYNLIB=no
|
||||
|
||||
if test "${with_tree_sitter}" != "no"; then
|
||||
dnl Tree-sitter 0.20.2 added support to change the malloc it uses
|
||||
dnl at runtime, we need that feature. However, tree-sitter's
|
||||
dnl Makefile has problems, until that's fixed, all tree-sitter
|
||||
dnl libraries distributed are versioned 0.6.3. We try to
|
||||
dnl accept a tree-sitter library that has incorrect version as long
|
||||
dnl as it supports changing malloc.
|
||||
EMACS_CHECK_MODULES([TREE_SITTER], [tree-sitter >= 0.20.2],
|
||||
dnl Tree-sitter 0.20.10 added ts_tree_cursor_goto_previous_sibling, we
|
||||
dnl need it for a more efficient implementation for traversing the
|
||||
dnl parse tree backwards (bug#80108).
|
||||
EMACS_CHECK_MODULES([TREE_SITTER], [tree-sitter >= 0.20.10],
|
||||
[HAVE_TREE_SITTER=yes], [HAVE_TREE_SITTER=no])
|
||||
if test "${HAVE_TREE_SITTER}" = yes; then
|
||||
AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.])
|
||||
NEED_DYNLIB=yes
|
||||
else
|
||||
EMACS_CHECK_MODULES([TREE_SITTER], [tree-sitter >= 0.6.3],
|
||||
[HAVE_TREE_SITTER=yes], [HAVE_TREE_SITTER=no])
|
||||
if test "${HAVE_TREE_SITTER}" = yes; then
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
OLD_LIBS=$LIBS
|
||||
CFLAGS="$CFLAGS $TREE_SITTER_CFLAGS"
|
||||
LIBS="$TREE_SITTER_LIBS $LIBS"
|
||||
AC_CHECK_FUNCS([ts_set_allocator])
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
LIBS=$OLD_LIBS
|
||||
if test "$ac_cv_func_ts_set_allocator" = yes; then
|
||||
AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.])
|
||||
NEED_DYNLIB=yes
|
||||
else
|
||||
AC_MSG_ERROR([Tree-sitter library exists but its version is too old]);
|
||||
TREE_SITTER_CFLAGS=
|
||||
TREE_SITTER_LIBS=
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Windows loads tree-sitter dynamically
|
||||
if test "${opsys}" = "mingw32"; then
|
||||
TREE_SITTER_LIBS=
|
||||
|
|
|
|||
|
|
@ -4278,50 +4278,14 @@ treesit_traverse_sibling_helper (TSTreeCursor *cursor,
|
|||
}
|
||||
else /* Backward. */
|
||||
{
|
||||
/* Go to first child and go through each sibling, until we find
|
||||
the one just before the starting node. */
|
||||
TSNode start = ts_tree_cursor_current_node (cursor);
|
||||
if (!ts_tree_cursor_goto_parent (cursor))
|
||||
return false;
|
||||
treesit_assume_true (ts_tree_cursor_goto_first_child (cursor));
|
||||
|
||||
/* Now CURSOR is at the first child. If we started at the first
|
||||
child, then there is no further siblings. */
|
||||
TSNode first_child = ts_tree_cursor_current_node (cursor);
|
||||
if (ts_node_eq (first_child, start))
|
||||
return false;
|
||||
|
||||
/* PROBE is always DELTA siblings ahead of CURSOR. */
|
||||
TSTreeCursor probe = ts_tree_cursor_copy (cursor);
|
||||
/* This is position of PROBE minus position of CURSOR. */
|
||||
ptrdiff_t delta = 0;
|
||||
TSNode probe_node;
|
||||
TSNode cursor_node;
|
||||
while (ts_tree_cursor_goto_next_sibling (&probe))
|
||||
if (!named)
|
||||
return ts_tree_cursor_goto_previous_sibling (cursor);
|
||||
/* Else named... */
|
||||
while (ts_tree_cursor_goto_previous_sibling (cursor))
|
||||
{
|
||||
/* Move PROBE forward, if it equals to the starting node,
|
||||
CURSOR points to the node we want (prev valid sibling of
|
||||
the starting node). */
|
||||
delta++;
|
||||
probe_node = ts_tree_cursor_current_node (&probe);
|
||||
|
||||
/* PROBE matched, depending on NAMED, return true/false. */
|
||||
if (ts_node_eq (probe_node, start))
|
||||
{
|
||||
ts_tree_cursor_delete (&probe);
|
||||
cursor_node = ts_tree_cursor_current_node (cursor);
|
||||
ts_tree_cursor_delete (&probe);
|
||||
return (!named || (named && ts_node_is_named (cursor_node)));
|
||||
}
|
||||
|
||||
/* PROBE didn't match, move CURSOR forward to PROBE's
|
||||
position, but if we are looking for named nodes, only
|
||||
move CURSOR to PROBE if PROBE is at a named node. */
|
||||
if (!named || (named && ts_node_is_named (probe_node)))
|
||||
for (; delta > 0; delta--)
|
||||
treesit_assume_true (ts_tree_cursor_goto_next_sibling (cursor));
|
||||
if (ts_node_is_named (ts_tree_cursor_current_node (cursor)))
|
||||
return true;
|
||||
}
|
||||
ts_tree_cursor_delete (&probe);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue