Subject: bug#67117: closed (Re: bug#67117: [PATCH] Tree-sitter: fix an issue when searching subtree backward)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 19 Dec 2023 02:27:02 +0000

Your bug report

#67117: [PATCH] Tree-sitter: fix an issue when searching subtree backward

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
67117: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67117
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#67117: [PATCH] Tree-sitter: fix an issue when searching subtree backward
From: Yuan Fu <[email-masked]>
To: Denis Zubarev <[email-masked]>
Cc: Eli Zaretskii <[email-masked]>, [email-masked]
Date: Mon, 18 Dec 2023 18:26:30 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

> On Dec 18, 2023, at 4:24 PM, Denis Zubarev <[email-masked]> wrote:
> 
> Just FYI, my paperwork is done.
> 

Great, applied! Closing this bug.

Yuan

Subject: [PATCH] Tree-sitter: fix an issue when searching subtree backward
From: Denis Zubarev <[email-masked]>
To: [email-masked]
Date: Sun, 12 Nov 2023 02:38:33 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

Steps to reproduce the issue:
1. emacs -Q
2. M-x find-file /tmp/t.py
3. paste to the buffer
 
Temp(1, 2) 
 
4. M-x python-ts-mode
5. Call search-subtree with backward flag
   M-x eval-expression (treesit-search-subtree
               (treesit--thing-at (point) "call")
               (lambda (n) (equal (treesit-node-type n ) "integer"))
               t)
It should return the second int node (#<treesit-node integer in 9-10>), but it returns nil.

I fixed it in treesit_traverse_child_helper.
Do not call treesit_traverse_sibling_helper when the named node is
required and the last child is the named node.
Otherwise treesit_traverse_sibling_helper will move cursor to the
previous sibling and the last node will be skipped.
I've added test for this bug.

In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.33, cairo version 1.16.0) of 2023-11-12 built on NUC-here
Repository revision: 400a71b8f2c5a49dce4f542adfd2fdb59eb34243
Repository branch: search-subtree-bacward-fix
Windowing system distributor 'The X.Org Foundation', version 11.0.12101004
System Description: Ubuntu 22.04.3 LTS

Configured using:
 'configure --with-modules --with-native-compilation=aot
 --with-imagemagick --with-json --with-tree-sitter --with-xft'

>From 88e913940cdd3c82afbdf2ad6520e1a1b9c2797b Mon Sep 17 00:00:00 2001
From: Denis Zubarev <[email-masked]>
Date: Sun, 12 Nov 2023 01:42:42 +0300
Subject: [PATCH] Fix an issue when searching subtree backward

* src/treesit.c (treesit_traverse_child_helper):
Do not call treesit_traverse_sibling_helper when the named node is
required and the last child is the named node.
Otherwise treesit_traverse_sibling_helper will move cursor to the
previous sibling and last node will be skipped.
* test/src/treesit-tests.el (treesit-search-subtree-forward-1):
(treesit-search-subtree-backward-1):
Add tests
---
 src/treesit.c             |  4 ++--
 test/src/treesit-tests.el | 30 ++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/treesit.c b/src/treesit.c
index 69b59fca11..4dcad751f4 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -3247,9 +3247,9 @@ treesit_traverse_child_helper (TSTreeCursor *cursor,
       /* First go to the last child.  */
       while (ts_tree_cursor_goto_next_sibling (cursor));
 
-      if (!named)
+      if (!named || (named && ts_node_is_named (ts_tree_cursor_current_node(cursor))))
 	return true;
-      /* Else named... */
+      /* Else named is required and last child is not named node */
       if (treesit_traverse_sibling_helper(cursor, false, true))
 	return true;
       else
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index 791e902bd0..c9b15c618c 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -1167,6 +1167,36 @@ treesit-defun-navigation-top-level
    treesit--ert-defun-navigation-top-level-master
    'top-level))
 
+(ert-deftest treesit-search-subtree-forward-1 ()
+  "Test search subtree forward."
+  (skip-unless (treesit-language-available-p 'python))
+  (require 'python)
+  (python-ts-mode)
+  (insert "Temp(1, 2)")
+  (goto-char (point-min))
+  (let ((node (treesit-search-subtree
+               (treesit--thing-at (point) "call")
+               (lambda (n) (equal (treesit-node-type n ) "integer")))))
+
+    (should node)
+    (should (equal (treesit-node-text node) "1"))))
+
+(ert-deftest treesit-search-subtree-backward-1 ()
+  "Test search subtree with backward=t."
+  (skip-unless (treesit-language-available-p 'python))
+  (require 'python)
+  (python-ts-mode)
+  (insert "Temp(1, 2)")
+  (goto-char (point-min))
+  (let ((node (treesit-search-subtree
+               (treesit--thing-at (point) "call")
+               (lambda (n) (equal (treesit-node-type n ) "integer"))
+               t)))
+
+    (should node)
+    (should (equal (treesit-node-text node) "2"))))
+
+
 ;; TODO
 ;; - Functions in treesit.el
 ;; - treesit-load-name-override-list
-- 
2.34.1