From 64847fbdc908bf0a301b8f1e1814ff71bd425bae Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Wed, 25 Sep 2024 11:33:14 -0700 Subject: perf(treesitter): use `child_containing_descendant()` in `is_ancestor()` **Problem:** `is_ancestor()` uses a slow, bottom-up parent lookup which has performance pitfalls detailed in #28512. **Solution:** Take `is_ancestor()` from $O(n^2)$ to $O(n)$ by incorporating the use of the `child_containing_descendant()` function --- runtime/lua/vim/treesitter.lua | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 809ea59b94..baf47482a8 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -159,16 +159,8 @@ function M.is_ancestor(dest, source) return false end - local current = source ---@type TSNode? - while current ~= nil do - if current == dest then - return true - end - - current = current:parent() - end - - return false + -- child_containing_descendant returns nil if dest is a direct parent + return source:parent() == dest or dest:child_containing_descendant(source) ~= nil end --- Returns the node's range or an unpacked range table -- cgit