mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 13:38:34 +00:00
refactor(treesitter): migrate to ts parser callback API #33141
Remove the `set_timeout` functions for `TSParser` and instead add a timeout parameter to the regular parse function. Remove these deprecated tree-sitter API functions and replace them with the preferred `TSParseOptions` style.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
#include <tree_sitter/api.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "nvim/os/time.h"
|
||||
|
||||
#ifdef HAVE_WASMTIME
|
||||
# include <wasm.h>
|
||||
|
||||
@@ -52,6 +54,11 @@ typedef struct {
|
||||
TSTree *tree;
|
||||
} TSLuaTree;
|
||||
|
||||
typedef struct {
|
||||
uint64_t parse_start_time;
|
||||
uint64_t timeout_threshold_ns;
|
||||
} TSLuaParserCallbackPayload;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "lua/treesitter.c.generated.h"
|
||||
#endif
|
||||
@@ -362,8 +369,6 @@ static struct luaL_Reg parser_meta[] = {
|
||||
{ "reset", parser_reset },
|
||||
{ "set_included_ranges", parser_set_ranges },
|
||||
{ "included_ranges", parser_get_ranges },
|
||||
{ "set_timeout", parser_set_timeout },
|
||||
{ "timeout", parser_get_timeout },
|
||||
{ "_set_logger", parser_set_logger },
|
||||
{ "_logger", parser_get_logger },
|
||||
{ NULL, NULL }
|
||||
@@ -487,6 +492,13 @@ static void push_ranges(lua_State *L, const TSRange *ranges, const size_t length
|
||||
}
|
||||
}
|
||||
|
||||
static bool on_parser_progress(TSParseState *state)
|
||||
{
|
||||
TSLuaParserCallbackPayload *payload = state->payload;
|
||||
uint64_t parse_time = os_hrtime() - payload->parse_start_time;
|
||||
return parse_time >= payload->timeout_threshold_ns;
|
||||
}
|
||||
|
||||
static int parser_parse(lua_State *L)
|
||||
{
|
||||
TSParser *p = parser_check(L, 1);
|
||||
@@ -524,7 +536,17 @@ static int parser_parse(lua_State *L)
|
||||
}
|
||||
|
||||
input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8, NULL };
|
||||
new_tree = ts_parser_parse(p, old_tree, input);
|
||||
if (!lua_isnil(L, 5)) {
|
||||
uint64_t timeout_ns = (uint64_t)lua_tointeger(L, 5);
|
||||
TSLuaParserCallbackPayload payload =
|
||||
(TSLuaParserCallbackPayload){ .parse_start_time = os_hrtime(),
|
||||
.timeout_threshold_ns = timeout_ns };
|
||||
TSParseOptions parse_options = { .payload = &payload,
|
||||
.progress_callback = on_parser_progress };
|
||||
new_tree = ts_parser_parse_with_options(p, old_tree, input, parse_options);
|
||||
} else {
|
||||
new_tree = ts_parser_parse(p, old_tree, input);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -534,12 +556,11 @@ static int parser_parse(lua_State *L)
|
||||
|
||||
bool include_bytes = (lua_gettop(L) >= 4) && lua_toboolean(L, 4);
|
||||
|
||||
// Sometimes parsing fails (timeout, or wrong parser ABI)
|
||||
// In those case, just return an error.
|
||||
if (!new_tree) {
|
||||
if (ts_parser_timeout_micros(p) == 0) {
|
||||
// No timeout set, must have had an error
|
||||
return luaL_error(L, "An error occurred when parsing.");
|
||||
// Sometimes parsing fails (no language was set, or it was set to one with an incompatible ABI)
|
||||
// In those cases, just return an error.
|
||||
if (!ts_parser_language(p)) {
|
||||
return luaL_error(L, "Language was unset, or has an incompatible ABI.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -670,26 +691,6 @@ static int parser_get_ranges(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parser_set_timeout(lua_State *L)
|
||||
{
|
||||
TSParser *p = parser_check(L, 1);
|
||||
|
||||
if (lua_gettop(L) < 2) {
|
||||
luaL_error(L, "integer expected");
|
||||
}
|
||||
|
||||
uint32_t timeout = (uint32_t)luaL_checkinteger(L, 2);
|
||||
ts_parser_set_timeout_micros(p, timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parser_get_timeout(lua_State *L)
|
||||
{
|
||||
TSParser *p = parser_check(L, 1);
|
||||
lua_pushinteger(L, (lua_Integer)ts_parser_timeout_micros(p));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void logger_cb(void *payload, TSLogType logtype, const char *s)
|
||||
{
|
||||
TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)payload;
|
||||
|
Reference in New Issue
Block a user