emacs-diffs
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]