diff options
| author | Yuan Fu | 2023-04-13 15:03:05 -0700 |
|---|---|---|
| committer | Yuan Fu | 2023-04-13 15:08:51 -0700 |
| commit | 361c5fc2d8e52d70aa58956c57eaef9495881197 (patch) | |
| tree | 31c1573058144e6a70515b0198f1c2e7cf34e8bb /test | |
| parent | a5eb9f6ad4e6f5a2819b540a477f1e889f6ef355 (diff) | |
| download | emacs-361c5fc2d8e52d70aa58956c57eaef9495881197.tar.gz emacs-361c5fc2d8e52d70aa58956c57eaef9495881197.zip | |
Support more predicates in tree-sitter search functions
Right now we support regexp strings and predicate functions for the
PRED argument. This change adds support for (not ...) (or ...)
and (regexp . pred) predicates.
I still need to find a place to document the supported shapes of a
predicate.
* src/treesit.c (treesit_traverse_validate_predicate): New function.
(treesit_traverse_match_predicate): Support more predicate shapes.
(treesit_search_dfs):
(treesit_search_forward)
(treesit_build_sparse_tree): Fix docstring (unrelated to this change).
(Ftreesit_search_subtree)
(Ftreesit_search_forward)
(Ftreesit_induce_sparse_tree): Use the new function to validate
predicate shape.
(syms_of_treesit): New error Qtreesit_invalid_predicate.
* test/src/treesit-tests.el:
(treesit--ert-search-setup): Add edebug declaration.
(treesit-search-forward-predicate)
(treesit-search-forward-predicate-invalid-predicate): New tests.
Diffstat (limited to 'test')
| -rw-r--r-- | test/src/treesit-tests.el | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index ac5e6f1e08c..26a21c34152 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el | |||
| @@ -257,6 +257,7 @@ | |||
| 257 | (defmacro treesit--ert-search-setup (&rest body) | 257 | (defmacro treesit--ert-search-setup (&rest body) |
| 258 | "Setup macro used by `treesit-search-forward' and friends. | 258 | "Setup macro used by `treesit-search-forward' and friends. |
| 259 | BODY is the test body." | 259 | BODY is the test body." |
| 260 | (declare (debug (&rest form))) | ||
| 260 | `(with-temp-buffer | 261 | `(with-temp-buffer |
| 261 | (let (parser root array) | 262 | (let (parser root array) |
| 262 | (progn | 263 | (progn |
| @@ -332,6 +333,58 @@ BODY is the test body." | |||
| 332 | do (should (equal (treesit-node-text cursor) | 333 | do (should (equal (treesit-node-text cursor) |
| 333 | text))))) | 334 | text))))) |
| 334 | 335 | ||
| 336 | (ert-deftest treesit-search-forward-predicate () | ||
| 337 | "Test various form of supported predicates in search functions." | ||
| 338 | (skip-unless (treesit-language-available-p 'json)) | ||
| 339 | (treesit--ert-search-setup | ||
| 340 | ;; The following tests are adapted from `treesit-search-forward'. | ||
| 341 | |||
| 342 | ;; Test `or' | ||
| 343 | (cl-loop for cursor = (treesit-node-child array 0) | ||
| 344 | then (treesit-search-forward cursor `(or "number" ,(rx "[")) | ||
| 345 | nil t) | ||
| 346 | for text in '("[" "[" "1" "2" "3" | ||
| 347 | "[" "4" "5" "6" | ||
| 348 | "[" "7" "8" "9") | ||
| 349 | while cursor | ||
| 350 | do (should (equal (treesit-node-text cursor) text))) | ||
| 351 | ;; Test `not' and `or' | ||
| 352 | (cl-loop for cursor = (treesit-node-child array 0) | ||
| 353 | then (treesit-search-forward cursor | ||
| 354 | `(not (or "number" ,(rx "["))) | ||
| 355 | nil t) | ||
| 356 | for text in '("[" "," "," "]" | ||
| 357 | "[1,2,3]" "," | ||
| 358 | "," "," "]" | ||
| 359 | "[4,5,6]" "," | ||
| 360 | "," "," "]" | ||
| 361 | "[7,8,9]" "]" | ||
| 362 | "[[1,2,3], [4,5,6], [7,8,9]]") | ||
| 363 | while cursor | ||
| 364 | do (should (equal (treesit-node-text cursor) text))) | ||
| 365 | ;; Test (regexp . function) | ||
| 366 | (cl-labels ((is-odd (string) | ||
| 367 | (and (eq 1 (length string)) | ||
| 368 | (cl-oddp (string-to-number string))))) | ||
| 369 | (cl-loop for cursor = (treesit-node-child array 0) | ||
| 370 | then (treesit-search-forward cursor '("number" . is-odd) | ||
| 371 | nil t) | ||
| 372 | for text in '("[" "1" "3" "5" "7" "9") | ||
| 373 | while cursor | ||
| 374 | do (should (equal (treesit-node-text cursor) text)))))) | ||
| 375 | |||
| 376 | (ert-deftest treesit-search-forward-predicate-invalid-predicate () | ||
| 377 | "Test tree-sitter's ability to detect invalid predicates." | ||
| 378 | (skip-unless (treesit-language-available-p 'json)) | ||
| 379 | (treesit--ert-search-setup | ||
| 380 | (dolist (pred '( 1 (not 1) (not "2" "3") (or) (or 1))) | ||
| 381 | (should-error (treesit-search-forward (treesit-node-child array 0) | ||
| 382 | pred) | ||
| 383 | :type 'treesit-invalid-predicate)) | ||
| 384 | (should-error (treesit-search-forward (treesit-node-child array 0) | ||
| 385 | 'not-a-function) | ||
| 386 | :type 'void-function))) | ||
| 387 | |||
| 335 | (ert-deftest treesit-cursor-helper-with-missing-node () | 388 | (ert-deftest treesit-cursor-helper-with-missing-node () |
| 336 | "Test treesit_cursor_helper with a missing node." | 389 | "Test treesit_cursor_helper with a missing node." |
| 337 | (skip-unless (treesit-language-available-p 'json)) | 390 | (skip-unless (treesit-language-available-p 'json)) |