diff options
| author | Yuan Fu | 2024-08-27 22:31:42 -0700 |
|---|---|---|
| committer | Yuan Fu | 2024-09-12 01:04:11 -0700 |
| commit | 2a75693f24a631b0a2a366bdce1ca5cb0c38d215 (patch) | |
| tree | 75fa8b78ee467aa729632ec9169d03aac83d6350 /src/treesit.c | |
| parent | f283144658259f209efdef78c576b43832c9c479 (diff) | |
| download | emacs-2a75693f24a631b0a2a366bdce1ca5cb0c38d215.tar.gz emacs-2a75693f24a631b0a2a366bdce1ca5cb0c38d215.zip | |
Add Ftreesit_grammar_location
* src/treesit.c (treesit_loaded_lang): New struct.
(treesit_load_language): Return a struct instead of just the language
object. The struct contains both the language object and the path to
the shared library.
(Ftreesit_language_available_p, Ftreesit_language_abi_version)
(treesit_ensure_query_compiled, Ftreesit_parser_create): Update
call of treesit_load_language.
(Ftreesit_grammar_location): New function.
Diffstat (limited to 'src/treesit.c')
| -rw-r--r-- | src/treesit.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/src/treesit.c b/src/treesit.c index 0ba6c733d64..8c586109b2d 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include "lisp.h" | 23 | #include "lisp.h" |
| 24 | #include "buffer.h" | 24 | #include "buffer.h" |
| 25 | #include "coding.h" | ||
| 25 | 26 | ||
| 26 | #include "treesit.h" | 27 | #include "treesit.h" |
| 27 | 28 | ||
| @@ -541,6 +542,15 @@ treesit_debug_print_parser_list (char *msg, Lisp_Object parser) | |||
| 541 | 542 | ||
| 542 | /*** Loading language library */ | 543 | /*** Loading language library */ |
| 543 | 544 | ||
| 545 | struct treesit_loaded_lang | ||
| 546 | { | ||
| 547 | /* The language object, or NULL if the language failed to load. */ | ||
| 548 | TSLanguage *lang; | ||
| 549 | /* The absolute file name of the shared library, or NULL if access | ||
| 550 | failed. */ | ||
| 551 | const char *filename; | ||
| 552 | }; | ||
| 553 | |||
| 544 | /* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */ | 554 | /* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */ |
| 545 | static void | 555 | static void |
| 546 | treesit_symbol_to_c_name (char *symbol_name) | 556 | treesit_symbol_to_c_name (char *symbol_name) |
| @@ -625,7 +635,7 @@ treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name, | |||
| 625 | 635 | ||
| 626 | If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA | 636 | If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA |
| 627 | with values suitable for xsignal. */ | 637 | with values suitable for xsignal. */ |
| 628 | static TSLanguage * | 638 | static struct treesit_loaded_lang |
| 629 | treesit_load_language (Lisp_Object language_symbol, | 639 | treesit_load_language (Lisp_Object language_symbol, |
| 630 | Lisp_Object *signal_symbol, Lisp_Object *signal_data) | 640 | Lisp_Object *signal_symbol, Lisp_Object *signal_data) |
| 631 | { | 641 | { |
| @@ -676,6 +686,7 @@ treesit_load_language (Lisp_Object language_symbol, | |||
| 676 | dynlib_handle_ptr handle; | 686 | dynlib_handle_ptr handle; |
| 677 | const char *error; | 687 | const char *error; |
| 678 | Lisp_Object error_list = Qnil; | 688 | Lisp_Object error_list = Qnil; |
| 689 | struct treesit_loaded_lang loaded_lang = { NULL, NULL }; | ||
| 679 | 690 | ||
| 680 | tail = path_candidates; | 691 | tail = path_candidates; |
| 681 | error = NULL; | 692 | error = NULL; |
| @@ -700,7 +711,7 @@ treesit_load_language (Lisp_Object language_symbol, | |||
| 700 | mismatch. */ | 711 | mismatch. */ |
| 701 | *signal_symbol = Qtreesit_load_language_error; | 712 | *signal_symbol = Qtreesit_load_language_error; |
| 702 | *signal_data = Fcons (Qnot_found, Fnreverse (error_list)); | 713 | *signal_data = Fcons (Qnot_found, Fnreverse (error_list)); |
| 703 | return NULL; | 714 | return loaded_lang; |
| 704 | } | 715 | } |
| 705 | 716 | ||
| 706 | /* Load TSLanguage. */ | 717 | /* Load TSLanguage. */ |
| @@ -722,7 +733,7 @@ treesit_load_language (Lisp_Object language_symbol, | |||
| 722 | { | 733 | { |
| 723 | *signal_symbol = Qtreesit_load_language_error; | 734 | *signal_symbol = Qtreesit_load_language_error; |
| 724 | *signal_data = list2 (Qsymbol_error, build_string (error)); | 735 | *signal_data = list2 (Qsymbol_error, build_string (error)); |
| 725 | return NULL; | 736 | return loaded_lang; |
| 726 | } | 737 | } |
| 727 | TSLanguage *lang = (*langfn) (); | 738 | TSLanguage *lang = (*langfn) (); |
| 728 | 739 | ||
| @@ -735,9 +746,14 @@ treesit_load_language (Lisp_Object language_symbol, | |||
| 735 | *signal_symbol = Qtreesit_load_language_error; | 746 | *signal_symbol = Qtreesit_load_language_error; |
| 736 | *signal_data = list2 (Qversion_mismatch, | 747 | *signal_data = list2 (Qversion_mismatch, |
| 737 | make_fixnum (ts_language_version (lang))); | 748 | make_fixnum (ts_language_version (lang))); |
| 738 | return NULL; | 749 | return loaded_lang; |
| 739 | } | 750 | } |
| 740 | return lang; | 751 | |
| 752 | const char *sym; | ||
| 753 | dynlib_addr ((void (*)) langfn, &loaded_lang.filename, &sym); | ||
| 754 | |||
| 755 | loaded_lang.lang = lang; | ||
| 756 | return loaded_lang; | ||
| 741 | } | 757 | } |
| 742 | 758 | ||
| 743 | DEFUN ("treesit-language-available-p", Ftreesit_language_available_p, | 759 | DEFUN ("treesit-language-available-p", Ftreesit_language_available_p, |
| @@ -754,7 +770,9 @@ If DETAIL is non-nil, return (t . nil) when LANGUAGE is available, | |||
| 754 | treesit_initialize (); | 770 | treesit_initialize (); |
| 755 | Lisp_Object signal_symbol = Qnil; | 771 | Lisp_Object signal_symbol = Qnil; |
| 756 | Lisp_Object signal_data = Qnil; | 772 | Lisp_Object signal_data = Qnil; |
| 757 | if (treesit_load_language (language, &signal_symbol, &signal_data) == NULL) | 773 | struct treesit_loaded_lang loaded_lang |
| 774 | = treesit_load_language (language, &signal_symbol, &signal_data); | ||
| 775 | if (loaded_lang.lang == NULL) | ||
| 758 | { | 776 | { |
| 759 | if (NILP (detail)) | 777 | if (NILP (detail)) |
| 760 | return Qnil; | 778 | return Qnil; |
| @@ -800,9 +818,9 @@ Return nil if a grammar library for LANGUAGE is not available. */) | |||
| 800 | { | 818 | { |
| 801 | Lisp_Object signal_symbol = Qnil; | 819 | Lisp_Object signal_symbol = Qnil; |
| 802 | Lisp_Object signal_data = Qnil; | 820 | Lisp_Object signal_data = Qnil; |
| 803 | TSLanguage *ts_language = treesit_load_language (language, | 821 | struct treesit_loaded_lang lang |
| 804 | &signal_symbol, | 822 | = treesit_load_language (language, &signal_symbol, &signal_data); |
| 805 | &signal_data); | 823 | TSLanguage *ts_language = lang.lang; |
| 806 | if (ts_language == NULL) | 824 | if (ts_language == NULL) |
| 807 | return Qnil; | 825 | return Qnil; |
| 808 | uint32_t version = ts_language_version (ts_language); | 826 | uint32_t version = ts_language_version (ts_language); |
| @@ -810,6 +828,30 @@ Return nil if a grammar library for LANGUAGE is not available. */) | |||
| 810 | } | 828 | } |
| 811 | } | 829 | } |
| 812 | 830 | ||
| 831 | /* This function isn't documented in the manual since it's mainly for | ||
| 832 | debugging. */ | ||
| 833 | DEFUN ("treesit-grammar-location", Ftreesit_grammar_location, | ||
| 834 | Streesit_grammar_location, | ||
| 835 | 1, 1, 0, | ||
| 836 | doc: /* Return the absolute file name of the grammar file for LANGUAGE. | ||
| 837 | |||
| 838 | If LANGUAGE isn't loaded yet, load it first. If the language can't be | ||
| 839 | loaded or the file name couldn't be determined, return nil. */) | ||
| 840 | (Lisp_Object language) | ||
| 841 | { | ||
| 842 | CHECK_SYMBOL (language); | ||
| 843 | |||
| 844 | Lisp_Object signal_symbol = Qnil; | ||
| 845 | Lisp_Object signal_data = Qnil; | ||
| 846 | struct treesit_loaded_lang lang | ||
| 847 | = treesit_load_language (language, &signal_symbol, &signal_data); | ||
| 848 | |||
| 849 | if (!lang.lang || !lang.filename) return Qnil; | ||
| 850 | |||
| 851 | return DECODE_FILE (make_unibyte_string (lang.filename, | ||
| 852 | strlen (lang.filename))); | ||
| 853 | } | ||
| 854 | |||
| 813 | 855 | ||
| 814 | /*** Parsing functions */ | 856 | /*** Parsing functions */ |
| 815 | 857 | ||
| @@ -1401,8 +1443,9 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol, | |||
| 1401 | Lisp_Object language = XTS_COMPILED_QUERY (query)->language; | 1443 | Lisp_Object language = XTS_COMPILED_QUERY (query)->language; |
| 1402 | /* This is the main reason why we compile query lazily: to avoid | 1444 | /* This is the main reason why we compile query lazily: to avoid |
| 1403 | loading languages early. */ | 1445 | loading languages early. */ |
| 1404 | TSLanguage *treesit_lang = treesit_load_language (language, signal_symbol, | 1446 | struct treesit_loaded_lang lang |
| 1405 | signal_data); | 1447 | = treesit_load_language (language, signal_symbol, signal_data); |
| 1448 | TSLanguage *treesit_lang = lang.lang; | ||
| 1406 | if (treesit_lang == NULL) | 1449 | if (treesit_lang == NULL) |
| 1407 | return NULL; | 1450 | return NULL; |
| 1408 | 1451 | ||
| @@ -1573,8 +1616,9 @@ an indirect buffer. */) | |||
| 1573 | Lisp_Object signal_symbol = Qnil; | 1616 | Lisp_Object signal_symbol = Qnil; |
| 1574 | Lisp_Object signal_data = Qnil; | 1617 | Lisp_Object signal_data = Qnil; |
| 1575 | TSParser *parser = ts_parser_new (); | 1618 | TSParser *parser = ts_parser_new (); |
| 1576 | TSLanguage *lang = treesit_load_language (language, &signal_symbol, | 1619 | struct treesit_loaded_lang loaded_lang |
| 1577 | &signal_data); | 1620 | = treesit_load_language (language, &signal_symbol, &signal_data); |
| 1621 | TSLanguage *lang = loaded_lang.lang; | ||
| 1578 | if (lang == NULL) | 1622 | if (lang == NULL) |
| 1579 | xsignal (signal_symbol, signal_data); | 1623 | xsignal (signal_symbol, signal_data); |
| 1580 | /* We check language version when loading a language, so this should | 1624 | /* We check language version when loading a language, so this should |
| @@ -4369,6 +4413,7 @@ applies to LANGUAGE-A will be redirected to LANGUAGE-B instead. */); | |||
| 4369 | defsubr (&Streesit_language_available_p); | 4413 | defsubr (&Streesit_language_available_p); |
| 4370 | defsubr (&Streesit_library_abi_version); | 4414 | defsubr (&Streesit_library_abi_version); |
| 4371 | defsubr (&Streesit_language_abi_version); | 4415 | defsubr (&Streesit_language_abi_version); |
| 4416 | defsubr (&Streesit_grammar_location); | ||
| 4372 | 4417 | ||
| 4373 | defsubr (&Streesit_parser_p); | 4418 | defsubr (&Streesit_parser_p); |
| 4374 | defsubr (&Streesit_node_p); | 4419 | defsubr (&Streesit_node_p); |