perf(treesitter): speed up has_ancestor? predicate

This commit is contained in:
vanaigr 2024-04-25 18:57:20 -05:00
parent aa36e84474
commit f642475767
2 changed files with 40 additions and 17 deletions

View File

@ -462,12 +462,12 @@ local predicate_handlers = {
ancestor_types[type] = true
end
local cur = node:parent()
local cur = node:tree():root()
while cur do
if ancestor_types[cur:type()] then
return true
end
cur = cur:parent()
cur = cur:child_containing_descendant(node)
end
end
return false

View File

@ -11,6 +11,22 @@ local is_os = t.is_os
local api = n.api
local fn = n.fn
local get_query_result_code = [[
function get_query_result(query_text)
cquery = vim.treesitter.query.parse("c", query_text)
parser = vim.treesitter.get_parser(0, "c")
tree = parser:parse()[1]
res = {}
for cid, node in cquery:iter_captures(tree:root(), 0) do
-- can't transmit node over RPC. just check the name, range, and text
local text = vim.treesitter.get_node_text(node, 0)
local range = {node:range()}
table.insert(res, { cquery.captures[cid], node:type(), range, text })
end
return res
end
]]
describe('treesitter query API', function()
before_each(function()
clear()
@ -295,21 +311,7 @@ void ui_refresh(void)
return 0;
}
]])
exec_lua([[
function get_query_result(query_text)
cquery = vim.treesitter.query.parse("c", query_text)
parser = vim.treesitter.get_parser(0, "c")
tree = parser:parse()[1]
res = {}
for cid, node in cquery:iter_captures(tree:root(), 0) do
-- can't transmit node over RPC. just check the name, range, and text
local text = vim.treesitter.get_node_text(node, 0)
local range = {node:range()}
table.insert(res, { cquery.captures[cid], node:type(), range, text })
end
return res
end
]])
exec_lua(get_query_result_code)
local res0 = exec_lua(
[[return get_query_result(...)]],
@ -337,6 +339,27 @@ void ui_refresh(void)
}, res1)
end)
it('supports builtin predicate has-ancestor?', function()
insert([[
int x = 123;
struct S { int x; };
int main() { int x = 124; }]]
)
exec_lua(get_query_result_code)
local result = exec_lua(
[[return get_query_result(...)]],
[[((number_literal) @literal (#has-ancestor? @literal "function_definition"))]]
)
eq({ { 'literal', 'number_literal', { 2, 21, 2, 24 }, '124' } }, result)
result = exec_lua(
[[return get_query_result(...)]],
[[((number_literal) @literal (#has-ancestor? @literal "struct_specifier"))]]
)
eq({}, result)
end)
it('allows loading query with escaped quotes and capture them `#{lua,vim}-match`?', function()
insert('char* astring = "Hello World!";')