diff options
| author | Yuan Fu | 2022-12-28 15:19:34 -0800 |
|---|---|---|
| committer | Yuan Fu | 2022-12-28 15:19:34 -0800 |
| commit | ec6feeaa19117deb0d60e97ad814b87ecbb7fa99 (patch) | |
| tree | f4663ffde848f6e1f8d64128aa5a86eb92af5400 | |
| parent | db96b1282f90ee40560f81e8b715fe785badbb6e (diff) | |
| download | emacs-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.
| -rw-r--r-- | src/treesit.c | 19 |
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, | |||
| 955 | static void | 955 | static void |
| 956 | treesit_ensure_parsed (Lisp_Object parser) | 956 | treesit_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 |