]> git.eshelyaron.com Git - emacs.git/commitdiff
Make sure undefined tree-sitter thing doesn't raise an error
authorYuan Fu <casouri@gmail.com>
Tue, 12 Sep 2023 03:59:50 +0000 (20:59 -0700)
committerYuan Fu <casouri@gmail.com>
Tue, 12 Sep 2023 20:16:41 +0000 (13:16 -0700)
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.

src/treesit.c

index eb4b4f1ab8134aa541aec9d7df9ae67d34e5938a..cc4f5f1998d9733be3676dae8c0dcb2da58d162f 100644 (file)
@@ -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");