From ec6feeaa19117deb0d60e97ad814b87ecbb7fa99 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Wed, 28 Dec 2022 15:19:34 -0800 Subject: [PATCH] Fix tree-sitter parser notifier recursion See the comment for detail. * src/treesit.c (treesit_ensure_parsed): Move the need_reparse short circuit to the very beginning. Move the call to treesit_call_after_change_functions to the very end. --- src/treesit.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index 813d4222f98..e226df263c1 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -955,6 +955,11 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, static void treesit_ensure_parsed (Lisp_Object parser) { + /* Make sure this comes before everything else, see comment + (ref:notifier-inside-ensure-parsed) for more detail. */ + if (!XTS_PARSER (parser)->need_reparse) + return; + struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); /* Before we parse, catch up with the narrowing situation. */ @@ -963,8 +968,6 @@ treesit_ensure_parsed (Lisp_Object parser) because it might set the flag to true. */ treesit_sync_visible_region (parser); - if (!XTS_PARSER (parser)->need_reparse) - return; TSParser *treesit_parser = XTS_PARSER (parser)->parser; TSTree *tree = XTS_PARSER (parser)->tree; TSInput input = XTS_PARSER (parser)->input; @@ -984,14 +987,20 @@ treesit_ensure_parsed (Lisp_Object parser) xsignal1 (Qtreesit_parse_error, buf); } + XTS_PARSER (parser)->tree = new_tree; + XTS_PARSER (parser)->need_reparse = false; + + /* After-change functions should run at the very end, most crucially + after need_reparse is set to false, this way if the function + calls some tree-sitter function which invokes + treesit_ensure_parsed again, it returns early and do not + recursively call the after change functions again. + (ref:notifier-inside-ensure-parsed) */ if (tree != NULL) { treesit_call_after_change_functions (tree, new_tree, parser); ts_tree_delete (tree); } - - XTS_PARSER (parser)->tree = new_tree; - XTS_PARSER (parser)->need_reparse = false; } /* This is the read function provided to tree-sitter to read from a -- 2.39.5