aboutsummaryrefslogtreecommitdiffstats
path: root/src/treesit.c
diff options
context:
space:
mode:
authorYuan Fu2022-12-28 15:19:34 -0800
committerYuan Fu2022-12-28 15:19:34 -0800
commitec6feeaa19117deb0d60e97ad814b87ecbb7fa99 (patch)
treef4663ffde848f6e1f8d64128aa5a86eb92af5400 /src/treesit.c
parentdb96b1282f90ee40560f81e8b715fe785badbb6e (diff)
downloademacs-ec6feeaa19117deb0d60e97ad814b87ecbb7fa99.tar.gz
emacs-ec6feeaa19117deb0d60e97ad814b87ecbb7fa99.zip
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.
Diffstat (limited to 'src/treesit.c')
-rw-r--r--src/treesit.c19
1 files 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,
955static void 955static void
956treesit_ensure_parsed (Lisp_Object parser) 956treesit_ensure_parsed (Lisp_Object parser)
957{ 957{
958 /* Make sure this comes before everything else, see comment
959 (ref:notifier-inside-ensure-parsed) for more detail. */
960 if (!XTS_PARSER (parser)->need_reparse)
961 return;
962
958 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); 963 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer);
959 964
960 /* Before we parse, catch up with the narrowing situation. */ 965 /* Before we parse, catch up with the narrowing situation. */
@@ -963,8 +968,6 @@ treesit_ensure_parsed (Lisp_Object parser)
963 because it might set the flag to true. */ 968 because it might set the flag to true. */
964 treesit_sync_visible_region (parser); 969 treesit_sync_visible_region (parser);
965 970
966 if (!XTS_PARSER (parser)->need_reparse)
967 return;
968 TSParser *treesit_parser = XTS_PARSER (parser)->parser; 971 TSParser *treesit_parser = XTS_PARSER (parser)->parser;
969 TSTree *tree = XTS_PARSER (parser)->tree; 972 TSTree *tree = XTS_PARSER (parser)->tree;
970 TSInput input = XTS_PARSER (parser)->input; 973 TSInput input = XTS_PARSER (parser)->input;
@@ -984,14 +987,20 @@ treesit_ensure_parsed (Lisp_Object parser)
984 xsignal1 (Qtreesit_parse_error, buf); 987 xsignal1 (Qtreesit_parse_error, buf);
985 } 988 }
986 989
990 XTS_PARSER (parser)->tree = new_tree;
991 XTS_PARSER (parser)->need_reparse = false;
992
993 /* After-change functions should run at the very end, most crucially
994 after need_reparse is set to false, this way if the function
995 calls some tree-sitter function which invokes
996 treesit_ensure_parsed again, it returns early and do not
997 recursively call the after change functions again.
998 (ref:notifier-inside-ensure-parsed) */
987 if (tree != NULL) 999 if (tree != NULL)
988 { 1000 {
989 treesit_call_after_change_functions (tree, new_tree, parser); 1001 treesit_call_after_change_functions (tree, new_tree, parser);
990 ts_tree_delete (tree); 1002 ts_tree_delete (tree);
991 } 1003 }
992
993 XTS_PARSER (parser)->tree = new_tree;
994 XTS_PARSER (parser)->need_reparse = false;
995} 1004}
996 1005
997/* This is the read function provided to tree-sitter to read from a 1006/* This is the read function provided to tree-sitter to read from a