use crate::ast::{AstGraph, AstNode};
use crate::NodeId;
use alloc::borrow::ToOwned;
use tree_sitter::{Node, Parser};
fn add_node(source: &str, graph: &mut AstGraph, node: Node<'_>, counter: &mut u64) -> NodeId {
*counter = counter.saturating_add(1);
let id = NodeId(*counter);
let start = node.start_position();
let mut ast_node = AstNode::new(
u32::try_from(start.row.saturating_add(1)).unwrap(),
u32::try_from(start.column.saturating_add(1)).unwrap(),
node.kind().to_owned(),
);
if node.child_count() == 0 {
ast_node.text = Some(source[node.byte_range()].to_owned());
}
graph.add_node(id, ast_node);
let mut cursor = node.walk();
for (index, child) in node.children(&mut cursor).enumerate() {
let child_id = add_node(source, graph, child, counter);
graph.add_edge(id, child_id, u32::try_from(index).unwrap());
}
id
}
pub fn rust_ast_graph(source: &str) -> AstGraph {
let mut parser = Parser::new();
parser
.set_language(&tree_sitter_rust::LANGUAGE.into())
.unwrap();
let tree = parser.parse(source, None).unwrap();
assert!(!tree.root_node().has_error(), "fixture must parse cleanly");
let mut graph = AstGraph::new();
add_node(source, &mut graph, tree.root_node(), &mut 0);
graph
}
pub fn find_node<'a>(graph: &'a AstGraph, kind: &str) -> &'a AstNode {
graph
.nodes
.values()
.find(|node| node.kind == kind)
.unwrap_or_else(|| panic!("[ERROR] {kind} not found on source"))
}