[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
emacs-29 ec6feeaa19 1/5: Fix tree-sitter parser notifier recursion
From: |
Yuan Fu |
Subject: |
emacs-29 ec6feeaa19 1/5: Fix tree-sitter parser notifier recursion |
Date: |
Wed, 28 Dec 2022 18:57:48 -0500 (EST) |
branch: emacs-29
commit ec6feeaa19117deb0d60e97ad814b87ecbb7fa99
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
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 813d4222f9..e226df263c 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