From 956889d8ff1c79db45ca9b1711f406961e71c272 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Thu, 12 Jan 2023 17:07:21 -0800 Subject: [PATCH] Equal now recognizes tree-sitter nodes (bug#60659) Now equal uses ts_node_eq to check equality between nodes. * doc/lispref/parsing.texi: (Accessing Node Information): Update manual. * src/fns.c (internal_equal): Handle tree-sitter nodes. * src/treesit.c (treesit_node_eq): New function. (Ftreesit_node_eq): Factor out. Update docstring. * src/treesit.h (treesit_node_eq): Declare new function. --- doc/lispref/parsing.texi | 2 +- src/fns.c | 8 ++++++++ src/treesit.c | 20 +++++++++++++------- src/treesit.h | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index b55af912f9b..ecba833eb8f 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -931,7 +931,7 @@ Checks if @var{object} is a tree-sitter syntax node. @defun treesit-node-eq node1 node2 Checks if @var{node1} and @var{node2} are the same node in a syntax -tree. +tree. This function uses the same equivalence metric as @code{equal}. @end defun @heading Property information diff --git a/src/fns.c b/src/fns.c index 1aaf17914a2..d5f7565d3d7 100644 --- a/src/fns.c +++ b/src/fns.c @@ -38,6 +38,10 @@ along with GNU Emacs. If not, see . */ #include "puresize.h" #include "gnutls.h" +#ifdef HAVE_TREE_SITTER +#include "treesit.h" +#endif + enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; static bool internal_equal (Lisp_Object, Lisp_Object, enum equal_kind, int, Lisp_Object); @@ -2822,6 +2826,10 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, && !memcmp (bool_vector_data (o1), bool_vector_data (o2), bool_vector_bytes (size))); } + if (TS_NODEP (o1)) + { + return treesit_node_eq (o1, o2); + } /* Aside from them, only true vectors, char-tables, compiled functions, and fonts (font-spec, font-entity, font-object) diff --git a/src/treesit.c b/src/treesit.c index 55463122d14..d2db91604ab 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -2154,11 +2154,22 @@ If NODE is nil, return nil. */) return make_treesit_node (XTS_NODE (node)->parser, child); } +/* Return true if NODE1 and NODE2 are the same node. Assumes they are + TS_NODE type. */ +bool treesit_node_eq (Lisp_Object node1, Lisp_Object node2) +{ + treesit_initialize (); + TSNode treesit_node_1 = XTS_NODE (node1)->node; + TSNode treesit_node_2 = XTS_NODE (node2)->node; + return ts_node_eq (treesit_node_1, treesit_node_2); +} + DEFUN ("treesit-node-eq", Ftreesit_node_eq, Streesit_node_eq, 2, 2, 0, doc: /* Return non-nil if NODE1 and NODE2 are the same node. -If any one of NODE1 and NODE2 is nil, return nil. */) +If any one of NODE1 and NODE2 is nil, return nil. +This function uses the same equivalence metric as `equal'. */) (Lisp_Object node1, Lisp_Object node2) { if (NILP (node1) || NILP (node2)) @@ -2166,12 +2177,7 @@ If any one of NODE1 and NODE2 is nil, return nil. */) CHECK_TS_NODE (node1); CHECK_TS_NODE (node2); - treesit_initialize (); - - TSNode treesit_node_1 = XTS_NODE (node1)->node; - TSNode treesit_node_2 = XTS_NODE (node2)->node; - - bool same_node = ts_node_eq (treesit_node_1, treesit_node_2); + bool same_node = treesit_node_eq (node1, node2); return same_node ? Qt : Qnil; } diff --git a/src/treesit.h b/src/treesit.h index 909609737d3..5382bc58817 100644 --- a/src/treesit.h +++ b/src/treesit.h @@ -191,6 +191,7 @@ extern bool treesit_node_uptodate_p (Lisp_Object); extern void treesit_delete_parser (struct Lisp_TS_Parser *); extern void treesit_delete_query (struct Lisp_TS_Query *); extern bool treesit_named_node_p (TSNode); +extern bool treesit_node_eq (Lisp_Object, Lisp_Object); #endif /* HAVE_TREE_SITTER */ -- 2.39.2