agentic_codebase/parse/
treesitter.rs1use std::path::PathBuf;
4
5use crate::types::{AcbError, AcbResult, Span};
6
7pub fn get_node_text<'a>(node: tree_sitter::Node, source: &'a str) -> &'a str {
9 &source[node.byte_range()]
10}
11
12pub fn node_to_span(node: tree_sitter::Node) -> Span {
14 let start = node.start_position();
15 let end = node.end_position();
16 Span::new(
17 start.row as u32 + 1,
18 start.column as u32,
19 end.row as u32 + 1,
20 end.column as u32,
21 )
22}
23
24pub fn find_child_by_kind<'a>(
26 node: tree_sitter::Node<'a>,
27 kind: &str,
28) -> Option<tree_sitter::Node<'a>> {
29 let mut cursor = node.walk();
30 let result = node
31 .children(&mut cursor)
32 .find(|child| child.kind() == kind);
33 result
34}
35
36pub fn collect_children_by_kind<'a>(
38 node: tree_sitter::Node<'a>,
39 kind: &str,
40) -> Vec<tree_sitter::Node<'a>> {
41 let mut cursor = node.walk();
42 node.children(&mut cursor)
43 .filter(|c| c.kind() == kind)
44 .collect()
45}
46
47pub fn parse_with_language(
49 source: &str,
50 language: tree_sitter::Language,
51) -> AcbResult<tree_sitter::Tree> {
52 let mut parser = tree_sitter::Parser::new();
53 parser
54 .set_language(&language)
55 .map_err(|e| AcbError::ParseError {
56 path: PathBuf::new(),
57 message: format!("Failed to set tree-sitter language: {}", e),
58 })?;
59 parser
60 .parse(source, None)
61 .ok_or_else(|| AcbError::ParseError {
62 path: PathBuf::new(),
63 message: "Failed to parse source".into(),
64 })
65}
66
67pub fn count_complexity(node: tree_sitter::Node, decision_kinds: &[&str]) -> u32 {
69 let mut complexity = 1u32;
70 count_complexity_inner(node, decision_kinds, &mut complexity);
71 complexity
72}
73
74fn count_complexity_inner(node: tree_sitter::Node, decision_kinds: &[&str], count: &mut u32) {
75 if decision_kinds.contains(&node.kind()) {
76 *count += 1;
77 }
78 let mut cursor = node.walk();
79 for child in node.children(&mut cursor) {
80 count_complexity_inner(child, decision_kinds, count);
81 }
82}