From c31acb8fec0028c5761c2b00dde72f169dd04bb9 Mon Sep 17 00:00:00 2001 From: Niranjan Hasabnis Date: Fri, 21 May 2021 01:50:10 +0000 Subject: [PATCH] Changing API name; Adding unit test and Rust bindings --- cli/src/tests/node_test.rs | 19 +++++++++++++++++++ lib/binding_rust/bindings.rs | 5 +++++ lib/binding_rust/lib.rs | 12 ++++++++++++ lib/include/tree_sitter/api.h | 4 ++-- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cli/src/tests/node_test.rs b/cli/src/tests/node_test.rs index 9a47ce06..c5c9e720 100644 --- a/cli/src/tests/node_test.rs +++ b/cli/src/tests/node_test.rs @@ -248,6 +248,25 @@ fn test_node_parent_of_child_by_field_name() { ); } +#[test] +fn test_node_field_name_for_child() { + let mut parser = Parser::new(); + parser.set_language(get_language("c")).unwrap(); + let tree = parser.parse("x + y;", None).unwrap(); + let translation_unit_node = tree.root_node(); + let binary_expression_node = translation_unit_node + .named_child(0) + .unwrap() + .named_child(0) + .unwrap(); + + assert_eq!(binary_expression_node.field_name_for_child(0), Some("left")); + assert_eq!(binary_expression_node.field_name_for_child(1), Some("operator")); + assert_eq!(binary_expression_node.field_name_for_child(2), Some("right")); + // Negative test - Not a valid child index + assert_eq!(binary_expression_node.field_name_for_child(3), None); +} + #[test] fn test_node_child_by_field_name_with_extra_hidden_children() { let mut parser = Parser::new(); diff --git a/lib/binding_rust/bindings.rs b/lib/binding_rust/bindings.rs index a749ef98..50da12fc 100644 --- a/lib/binding_rust/bindings.rs +++ b/lib/binding_rust/bindings.rs @@ -434,6 +434,11 @@ extern "C" { #[doc = " child."] pub fn ts_node_child(arg1: TSNode, arg2: u32) -> TSNode; } +extern "C" { + #[doc = " Get the field name for node's child at the given index, where zero represents"] + #[doc = " the first child. Returns NULL, if no field is found."] + pub fn ts_node_field_name_for_child(arg1: TSNode, arg2: u32) -> *const ::std::os::raw::c_char; +} extern "C" { #[doc = " Get the node\'s number of children."] pub fn ts_node_child_count(arg1: TSNode) -> u32; diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index 22a0c2c1..771a8433 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -859,6 +859,18 @@ impl<'tree> Node<'tree> { Self::new(unsafe { ffi::ts_node_child_by_field_id(self.0, field_id) }) } + /// Get the field name of this node's child at the given index. + pub fn field_name_for_child(&self, child_index: u32) -> Option<&'static str> { + unsafe { + let ptr = ffi::ts_node_field_name_for_child(self.0, child_index); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr).to_str().unwrap()) + } + } + } + /// Iterate over this node's children. /// /// A [TreeCursor] is used to retrieve the children efficiently. Obtain diff --git a/lib/include/tree_sitter/api.h b/lib/include/tree_sitter/api.h index 4633d069..43315415 100644 --- a/lib/include/tree_sitter/api.h +++ b/lib/include/tree_sitter/api.h @@ -488,10 +488,10 @@ TSNode ts_node_parent(TSNode); TSNode ts_node_child(TSNode, uint32_t); /** - * Get the field_name for node's child at the given index, where zero represents + * Get the field name for node's child at the given index, where zero represents * the first child. Returns NULL, if no field is found. */ -const char *ts_node_child_field_name(TSNode, uint32_t); +const char *ts_node_field_name_for_child(TSNode, uint32_t); /** * Get the node's number of children.