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.