use tree_sitter::Node;
pub fn has_declarator_of_kind(node: &Node, target_kind: &str) -> bool {
if node.kind() == target_kind {
return true;
}
for i in 0..node.child_count() {
if let Some(child) = node.child(i) {
if has_declarator_of_kind(&child, target_kind) {
return true;
}
}
}
false
}
pub fn is_array_declarator(node: &Node) -> bool {
has_declarator_of_kind(node, "array_declarator")
}
pub fn is_pointer_declarator(node: &Node) -> bool {
has_declarator_of_kind(node, "pointer_declarator")
}
#[allow(dead_code)]
pub fn is_function_declarator(node: &Node) -> bool {
has_declarator_of_kind(node, "function_declarator")
}
#[cfg(test)]
mod tests {
use super::*;
use tree_sitter::Parser;
fn parse_c_code(code: &str) -> tree_sitter::Tree {
let mut parser = Parser::new();
let language = tree_sitter_c::language();
parser.set_language(&language).unwrap();
parser.parse(code, None).unwrap()
}
fn find_declarator<'a>(tree: &'a tree_sitter::Tree) -> Option<Node<'a>> {
let root = tree.root_node();
for i in 0..root.child_count() {
if let Some(child) = root.child(i) {
if child.kind() == "declaration" {
if let Some(declarator) = child.child_by_field_name("declarator") {
return Some(declarator);
}
}
}
}
None
}
#[test]
fn test_is_array_declarator() {
let tree = parse_c_code("int arr[10];");
let declarator = find_declarator(&tree).unwrap();
assert!(is_array_declarator(&declarator));
}
#[test]
fn test_is_pointer_declarator() {
let tree = parse_c_code("int *ptr;");
let declarator = find_declarator(&tree).unwrap();
assert!(is_pointer_declarator(&declarator));
}
#[test]
fn test_is_not_array() {
let tree = parse_c_code("int *ptr;");
let declarator = find_declarator(&tree).unwrap();
assert!(!is_array_declarator(&declarator));
}
#[test]
fn test_is_not_pointer() {
let tree = parse_c_code("int arr[10];");
let declarator = find_declarator(&tree).unwrap();
assert!(!is_pointer_declarator(&declarator));
}
#[test]
fn test_multidimensional_array() {
let tree = parse_c_code("int arr[5][10];");
let declarator = find_declarator(&tree).unwrap();
assert!(is_array_declarator(&declarator));
}
#[test]
fn test_double_pointer() {
let tree = parse_c_code("int **ptr;");
let declarator = find_declarator(&tree).unwrap();
assert!(is_pointer_declarator(&declarator));
}
}