1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Tree-sitter parse tree integration.
use crate::tree::Tree;
impl Tree {
/// Builds a tree from a tree-sitter parse tree.
///
/// Requires the `tree-sitter` feature.
///
/// Converts a tree-sitter parse tree into a Tree structure.
///
/// # Examples
///
/// ```no_run
/// use treelog::Tree;
/// use tree_sitter::{Parser, Language};
///
/// let mut parser = Parser::new();
/// // parser.set_language(language).unwrap();
/// // let tree = parser.parse("source code", None).unwrap();
/// // let tree = Tree::from_tree_sitter(&tree);
/// ```
#[cfg(feature = "arbitrary-tree-sitter")]
pub fn from_tree_sitter(parse_tree: &tree_sitter::Tree) -> Self {
let root_node = parse_tree.root_node();
Self::from_tree_sitter_node(&root_node)
}
/// Builds a tree from source code using a tree-sitter language.
///
/// Requires the `tree-sitter` feature.
///
/// Parses the source code and converts the parse tree into a Tree structure.
///
/// # Examples
///
/// ```no_run
/// use treelog::Tree;
/// use tree_sitter::Language;
///
/// // This requires a specific language to be loaded
/// // let tree = Tree::from_tree_sitter_language(source_code, language).unwrap();
/// ```
#[cfg(feature = "arbitrary-tree-sitter")]
pub fn from_tree_sitter_language(
source: &str,
language: tree_sitter::Language,
) -> Result<Self, Box<dyn std::error::Error>> {
let mut parser = tree_sitter::Parser::new();
parser.set_language(&language)?;
let parse_tree = parser.parse(source, None).ok_or("Parse failed")?;
Ok(Self::from_tree_sitter(&parse_tree))
}
#[cfg(feature = "arbitrary-tree-sitter")]
fn from_tree_sitter_node(node: &tree_sitter::Node) -> Self {
let kind = node.kind();
let mut label = kind.to_string();
// Add additional info if available
if node.is_named() {
label = format!("{} (named)", label);
}
if node.is_missing() {
label = format!("{} (missing)", label);
}
if node.has_error() {
label = format!("{} (error)", label);
}
// Add byte range info
let start_byte = node.start_byte();
let end_byte = node.end_byte();
if end_byte > start_byte {
label = format!("{} [{}..{}]", label, start_byte, end_byte);
}
let mut children = Vec::new();
// Process child nodes
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
children.push(Self::from_tree_sitter_node(&child));
}
// If no children, it's a leaf node
if children.is_empty() {
Tree::new_leaf(label)
} else {
Tree::Node(label, children)
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "arbitrary-tree-sitter")]
#[test]
fn test_tree_sitter_parsing() {
// This test would require a tree-sitter language to be loaded
// For now, we just verify the function exists
// In a real scenario, this would need a test fixture with a language
}
}