1mod builder;
7mod kind_scan;
8
9pub use builder::TreeBuilder;
10pub use kind_scan::KindScan;
11
12use crate::{SyntaxKind, TextRange, TextSize};
13
14pub type ElementId = u32;
16
17const NONE: u32 = u32::MAX;
18const TOKEN_BIT: u16 = 0x8000;
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct Tree {
23 text: Box<str>,
24 kinds: Vec<u16>,
25 starts: Vec<u32>,
26 ends: Vec<u32>,
28 parents: Vec<u32>,
29 prev_sibs: Vec<u32>,
30}
31
32impl Tree {
33 pub const ROOT: ElementId = 0;
34
35 pub fn text(&self) -> &str {
37 &self.text
38 }
39
40 pub fn len(&self) -> usize {
42 self.kinds.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 self.kinds.is_empty()
47 }
48
49 pub fn kind(&self, e: ElementId) -> SyntaxKind {
50 SyntaxKind::from_raw(self.kinds[e as usize] & !TOKEN_BIT)
51 }
52
53 pub fn is_token(&self, e: ElementId) -> bool {
54 self.kinds[e as usize] & TOKEN_BIT != 0
55 }
56
57 pub fn subtree_end(&self, e: ElementId) -> ElementId {
59 self.ends[e as usize]
60 }
61
62 pub fn parent(&self, e: ElementId) -> Option<ElementId> {
63 some(self.parents[e as usize])
64 }
65
66 pub fn first_child(&self, e: ElementId) -> Option<ElementId> {
67 (self.ends[e as usize] > e + 1).then_some(e + 1)
68 }
69
70 pub fn last_child(&self, e: ElementId) -> Option<ElementId> {
71 let mut last = self.first_child(e)?;
72 let mut cur = self.ends[e as usize] - 1;
74 while let Some(p) = self.parent(cur) {
75 if p == e {
76 last = cur;
77 break;
78 }
79 cur = p;
80 }
81 Some(last)
82 }
83
84 pub fn next_sibling(&self, e: ElementId) -> Option<ElementId> {
85 let parent = self.parent(e)?;
86 let next = self.ends[e as usize];
87 (next < self.ends[parent as usize]).then_some(next)
88 }
89
90 pub fn prev_sibling(&self, e: ElementId) -> Option<ElementId> {
91 some(self.prev_sibs[e as usize])
92 }
93
94 pub fn children(&self, e: ElementId) -> Children<'_> {
95 Children { tree: self, next: self.first_child(e) }
96 }
97
98 pub fn text_range(&self, e: ElementId) -> TextRange {
99 let start = self.starts[e as usize];
100 let end = self.starts.get(self.ends[e as usize] as usize).copied().unwrap_or(self.text.len() as u32);
101 TextRange::new(TextSize::from(start), TextSize::from(end))
102 }
103
104 pub fn text_of(&self, e: ElementId) -> &str {
105 &self.text[self.text_range(e)]
106 }
107
108 pub fn has_descendant_of_kind(&self, e: ElementId, kind: SyntaxKind) -> bool {
110 let raw = kind as u16;
111 self.kinds[e as usize + 1..self.ends[e as usize] as usize].iter().any(|&k| k & !TOKEN_BIT == raw)
112 }
113
114 pub fn find_kinds<const N: usize, const M: usize>(
117 &self,
118 e: ElementId,
119 nodes: [SyntaxKind; N],
120 tokens: [SyntaxKind; M],
121 ) -> KindScan<'_> {
122 const { assert!(N + M <= kind_scan::MAX_WANTED) };
123 let mut wanted = [kind_scan::NEVER; kind_scan::MAX_WANTED];
124 for (slot, k) in wanted.iter_mut().zip(nodes.map(|k| k as u16).into_iter().chain(tokens.map(|k| k as u16 | TOKEN_BIT))) {
125 *slot = k;
126 }
127 let start = e as usize;
128 KindScan::new(&self.kinds[start..self.ends[start] as usize], start, wanted)
129 }
130}
131
132pub struct Children<'t> {
133 tree: &'t Tree,
134 next: Option<ElementId>,
135}
136
137impl Iterator for Children<'_> {
138 type Item = ElementId;
139
140 fn next(&mut self) -> Option<ElementId> {
141 let cur = self.next?;
142 self.next = self.tree.next_sibling(cur);
143 Some(cur)
144 }
145}
146
147fn some(index: u32) -> Option<ElementId> {
148 (index != NONE).then_some(index)
149}
150
151#[cfg(test)]
152mod tests;