From: Yuan Fu Date: Tue, 12 Sep 2023 03:59:50 +0000 (-0700) Subject: Make sure undefined tree-sitter thing doesn't raise an error X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b392d05089014ac6d41e35a016d46f496964f879;p=emacs.git Make sure undefined tree-sitter thing doesn't raise an error A previous change should've achived this, but that wasn't enough. This one actually achieves the intended effect, namely, treesit-node-match-p doesn't raise an error if IGNORE-MISSING is non-nil, and traverse functions don't raise error by default. * src/treesit.c (treesit_traverse_validate_predicate): Remove ignore_missing parameter, return error symbol. (Ftreesit_node_match_p) (Ftreesit_search_subtree) (Ftreesit_search_forward) (Ftreesit_induce_sparse_tree): Check returned error symbol. (syms_of_treesit): New symbol. --- diff --git a/src/treesit.c b/src/treesit.c index eb4b4f1ab81..cc4f5f1998d 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -3274,23 +3274,23 @@ treesit_traverse_get_predicate (Lisp_Object thing, Lisp_Object language) } /* Validate the PRED passed to treesit_traverse_match_predicate. If - there's an error, set SIGNAL_DATA to something signal accepts, and - return false, otherwise return true. This function also check for + there's an error, set SIGNAL_DATA to (ERR . DATA), where ERR is an + error symbol, and DATA is something signal accepts, and return + false, otherwise return true. This function also check for recusion levels: we place a arbitrary 100 level limit on recursive predicates. RECURSION_LEVEL is the current recursion level (that starts at 0), if it goes over 99, return false and set SIGNAL_DATA. - LANGUAGE is a LANGUAGE symbol. IGNORE_MISSING is as in - `treesit-node-match-p' below. */ + LANGUAGE is a LANGUAGE symbol. */ static bool treesit_traverse_validate_predicate (Lisp_Object pred, Lisp_Object language, Lisp_Object *signal_data, - ptrdiff_t recursion_level, - bool ignore_missing) + ptrdiff_t recursion_level) { if (recursion_level > 99) { - *signal_data = list1 (build_string ("Predicate recursion level " + *signal_data = list2 (Qtreesit_invalid_predicate, + build_string ("Predicate recursion level " "exceeded: it must not exceed " "100 levels")); return false; @@ -3305,9 +3305,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred, language); if (NILP (definition)) { - if (ignore_missing) - return false; - *signal_data = list2 (build_string ("Cannot find the definition " + *signal_data = list3 (Qtreesit_predicate_not_found, + build_string ("Cannot find the definition " "of the predicate in " "`treesit-thing-settings'"), pred); @@ -3316,8 +3315,7 @@ treesit_traverse_validate_predicate (Lisp_Object pred, return treesit_traverse_validate_predicate (definition, language, signal_data, - recursion_level + 1, - ignore_missing); + recursion_level + 1); } else if (CONSP (pred)) { @@ -3327,7 +3325,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred, { if (!CONSP (cdr)) { - *signal_data = list2 (build_string ("Invalide `not' " + *signal_data = list3 (Qtreesit_invalid_predicate, + build_string ("Invalide `not' " "predicate"), pred); return false; @@ -3335,7 +3334,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred, /* At this point CDR must be a cons. */ if (XFIXNUM (Flength (cdr)) != 1) { - *signal_data = list2 (build_string ("`not' can only " + *signal_data = list3 (Qtreesit_invalid_predicate, + build_string ("`not' can only " "have one argument"), pred); return false; @@ -3343,14 +3343,14 @@ treesit_traverse_validate_predicate (Lisp_Object pred, return treesit_traverse_validate_predicate (XCAR (cdr), language, signal_data, - recursion_level + 1, - ignore_missing); + recursion_level + 1); } else if (BASE_EQ (car, Qor)) { if (!CONSP (cdr) || NILP (cdr)) { - *signal_data = list2 (build_string ("`or' must have a list " + *signal_data = list3 (Qtreesit_invalid_predicate, + build_string ("`or' must have a list " "of patterns as " "arguments "), pred); @@ -3361,8 +3361,7 @@ treesit_traverse_validate_predicate (Lisp_Object pred, if (!treesit_traverse_validate_predicate (XCAR (cdr), language, signal_data, - recursion_level + 1, - ignore_missing)) + recursion_level + 1)) return false; } return true; @@ -3370,7 +3369,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred, else if (STRINGP (car) && FUNCTIONP (cdr)) return true; } - *signal_data = list2 (build_string ("Invalid predicate, see `treesit-thing-settings' for valid forms of predicate"), + *signal_data = list3 (Qtreesit_invalid_predicate, + build_string ("Invalid predicate, see `treesit-thing-settings' for valid forms of predicate"), pred); return false; } @@ -3554,7 +3554,8 @@ Traverse the subtree of NODE, and match PREDICATE with each node along the way. PREDICATE can be a regexp string that matches against each node's type, a predicate function, and more. See `treesit-thing-settings' for the possible predicates. PREDICATE can -also be a thing defined in `treesit-thing-settings'. +also be a thing defined in `treesit-thing-settings'. Using an +undefined thing doesn't raise an error. By default, only traverse named nodes, but if ALL is non-nil, traverse all nodes. If BACKWARD is non-nil, traverse backwards. If DEPTH is @@ -3585,8 +3586,14 @@ Return the first matched node, or nil if none matches. */) Lisp_Object signal_data = Qnil; if (!treesit_traverse_validate_predicate (predicate, language, - &signal_data, 0, false)) - xsignal1 (Qtreesit_invalid_predicate, signal_data); + &signal_data, 0)) + { + Lisp_Object err_symbol = XCAR (signal_data); + Lisp_Object data = XCDR (signal_data); + if (EQ (err_symbol, Qtreesit_predicate_not_found)) + return Qnil; + xsignal1 (err_symbol, data); + } Lisp_Object return_value = Qnil; TSTreeCursor cursor; @@ -3616,7 +3623,8 @@ each node (except START itself) along the way. PREDICATE can be a regexp string that matches against each node's type, a predicate function, and more. See `treesit-thing-settings' for the possible predicates. PREDICATE can also be a thing defined in -`treesit-thing-settings'. +`treesit-thing-settings'. Using an undefined thing doesn't raise an +error. By default, only search for named nodes, but if ALL is non-nil, search for all nodes. If BACKWARD is non-nil, search backwards. @@ -3652,8 +3660,14 @@ always traverse leaf nodes first, then upwards. */) Lisp_Object signal_data = Qnil; if (!treesit_traverse_validate_predicate (predicate, language, - &signal_data, 0, false)) - xsignal1 (Qtreesit_invalid_predicate, signal_data); + &signal_data, 0)) + { + Lisp_Object err_symbol = XCAR (signal_data); + Lisp_Object data = XCDR (signal_data); + if (EQ (err_symbol, Qtreesit_predicate_not_found)) + return Qnil; + xsignal1 (err_symbol, data); + } Lisp_Object return_value = Qnil; TSTreeCursor cursor; @@ -3731,7 +3745,8 @@ match PREDICATE are left, like picking out grapes on the vine. PREDICATE can be a regexp string that matches against each node's type, a predicate function, and more. See `treesit-thing-settings' for the possible predicates. PREDICATE can also be a thing defined in -`treesit-thing-settings'. +`treesit-thing-settings'. Using an undefined thing doesn't raise an +error. For a subtree on the left that consist of both numbers and letters, if PREDICATE is "is letter", the returned tree is the one on the right. @@ -3787,8 +3802,14 @@ a regexp. */) Lisp_Object signal_data = Qnil; if (!treesit_traverse_validate_predicate (predicate, language, - &signal_data, 0, false)) - xsignal1 (Qtreesit_invalid_predicate, signal_data); + &signal_data, 0)) + { + Lisp_Object err_symbol = XCAR (signal_data); + Lisp_Object data = XCDR (signal_data); + if (EQ (err_symbol, Qtreesit_predicate_not_found)) + return Qnil; + xsignal1 (err_symbol, data); + } Lisp_Object parent = Fcons (Qnil, Qnil); /* In this function we never traverse above NODE, so we don't need @@ -3835,9 +3856,17 @@ definition, but still signal for malformed PREDICATE. */) Lisp_Object signal_data = Qnil; if (!treesit_traverse_validate_predicate (predicate, language, - &signal_data, 0, - !NILP (ignore_missing))) - xsignal1 (Qtreesit_invalid_predicate, signal_data); + &signal_data, 0)) + { + Lisp_Object err_symbol = XCAR (signal_data); + Lisp_Object data = XCDR (signal_data); + + if (!NILP (ignore_missing) + && EQ (err_symbol, Qtreesit_predicate_not_found)) + return Qnil; + + xsignal1 (err_symbol, data); + } TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (node)->node); @@ -3976,6 +4005,7 @@ syms_of_treesit (void) DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted"); DEFSYM (Qtreesit_pattern_expand, "treesit-pattern-expand"); DEFSYM (Qtreesit_invalid_predicate, "treesit-invalid-predicate"); + DEFSYM (Qtreesit_predicate_not_found, "treesit-predicate-not-found"); DEFSYM (Qor, "or");