tree_house_bindings/
tree.rs

1use std::fmt;
2use std::ptr::NonNull;
3
4use crate::node::{Node, NodeRaw};
5use crate::{Point, TreeCursor};
6
7// opaque pointers
8pub(super) enum SyntaxTreeData {}
9
10pub struct Tree {
11    ptr: NonNull<SyntaxTreeData>,
12}
13
14impl Tree {
15    pub(super) unsafe fn from_raw(raw: NonNull<SyntaxTreeData>) -> Tree {
16        Tree { ptr: raw }
17    }
18
19    pub(super) fn as_raw(&self) -> NonNull<SyntaxTreeData> {
20        self.ptr
21    }
22
23    pub fn root_node(&self) -> Node<'_> {
24        unsafe { Node::from_raw(ts_tree_root_node(self.ptr)).unwrap() }
25    }
26
27    pub fn edit(&mut self, edit: &InputEdit) {
28        unsafe { ts_tree_edit(self.ptr, edit) }
29    }
30
31    pub fn walk(&self) -> TreeCursor<'_> {
32        self.root_node().walk()
33    }
34}
35
36impl fmt::Debug for Tree {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        write!(f, "{{Tree {:?}}}", self.root_node())
39    }
40}
41
42impl Drop for Tree {
43    fn drop(&mut self) {
44        unsafe { ts_tree_delete(self.ptr) }
45    }
46}
47
48impl Clone for Tree {
49    fn clone(&self) -> Self {
50        unsafe {
51            Tree {
52                ptr: ts_tree_copy(self.ptr),
53            }
54        }
55    }
56}
57
58unsafe impl Send for Tree {}
59unsafe impl Sync for Tree {}
60
61#[repr(C)]
62#[derive(Debug, Copy, Clone, PartialEq, Eq)]
63pub struct InputEdit {
64    pub start_byte: u32,
65    pub old_end_byte: u32,
66    pub new_end_byte: u32,
67    pub start_point: Point,
68    pub old_end_point: Point,
69    pub new_end_point: Point,
70}
71
72impl InputEdit {
73    /// returns the offset between the old end of the edit and the new end of
74    /// the edit. This offset needs to be added to every position that occurs
75    /// after `self.old_end_byte` to may it to its old position
76    ///
77    /// This function assumes that the the source-file is smaller than 2GiB
78    pub fn offset(&self) -> i32 {
79        self.new_end_byte as i32 - self.old_end_byte as i32
80    }
81}
82
83extern "C" {
84    /// Create a shallow copy of the syntax tree. This is very fast. You need to
85    /// copy a syntax tree in order to use it on more than one thread at a time,
86    /// as syntax trees are not thread safe.
87    fn ts_tree_copy(self_: NonNull<SyntaxTreeData>) -> NonNull<SyntaxTreeData>;
88    /// Delete the syntax tree, freeing all of the memory that it used.
89    fn ts_tree_delete(self_: NonNull<SyntaxTreeData>);
90    /// Get the root node of the syntax tree.
91    fn ts_tree_root_node<'tree>(self_: NonNull<SyntaxTreeData>) -> NodeRaw;
92    /// Edit the syntax tree to keep it in sync with source code that has been
93    /// edited.
94    ///
95    /// You must describe the edit both in terms of byte offsets and in terms of
96    /// row/column coordinates.
97    fn ts_tree_edit(self_: NonNull<SyntaxTreeData>, edit: &InputEdit);
98}