ktrs_syntax/tree/
builder.rs1use super::{ElementId, NONE, TOKEN_BIT, Tree};
5use crate::SyntaxKind;
6
7#[derive(Default)]
8pub struct TreeBuilder {
9 text: String,
10 kinds: Vec<u16>,
11 starts: Vec<u32>,
12 ends: Vec<u32>,
13 parents: Vec<u32>,
14 prev_sibs: Vec<u32>,
15 open: Vec<(ElementId, u32)>,
17 room: usize,
19}
20
21impl TreeBuilder {
22 pub fn new() -> TreeBuilder {
23 TreeBuilder::default()
24 }
25
26 pub fn with_capacity(elements: usize, text_len: usize) -> TreeBuilder {
28 let mut builder = TreeBuilder { text: String::with_capacity(text_len), ..TreeBuilder::default() };
29 builder.reserve(elements);
30 builder
31 }
32
33 fn reserve(&mut self, additional: usize) {
34 self.kinds.reserve(additional);
35 self.starts.reserve(additional);
36 self.ends.reserve(additional);
37 self.parents.reserve(additional);
38 self.prev_sibs.reserve(additional);
39 self.update_room();
40 }
41
42 fn update_room(&mut self) {
43 self.room = [
44 self.kinds.capacity(),
45 self.starts.capacity(),
46 self.ends.capacity(),
47 self.parents.capacity(),
48 self.prev_sibs.capacity(),
49 ]
50 .into_iter()
51 .min()
52 .unwrap_or(0);
53 }
54
55 #[inline]
56 pub fn start_node(&mut self, kind: SyntaxKind) {
57 let e = self.push(kind as u16, NONE);
58 self.open.push((e, NONE));
59 }
60
61 #[inline]
62 pub fn token(&mut self, kind: SyntaxKind, text: &str) {
63 let e = self.kinds.len() as u32;
64 self.push(kind as u16 | TOKEN_BIT, e + 1);
65 self.text.push_str(text);
66 }
67
68 #[inline]
69 pub fn finish_node(&mut self) {
70 let (e, _) = self.open.pop().expect("finish_node without start_node");
71 self.ends[e as usize] = self.kinds.len() as u32;
72 }
73
74 pub fn len(&self) -> ElementId {
76 self.kinds.len() as ElementId
77 }
78
79 pub fn is_empty(&self) -> bool {
80 self.kinds.is_empty()
81 }
82
83 pub fn extract(&self, root: ElementId) -> Tree {
86 let r = root as usize;
87 assert_eq!(self.ends[r], self.len(), "extract of an open or non-final subtree");
88 let base = self.starts[r];
89 let rebase = |ids: &[u32]| {
91 std::iter::once(NONE).chain(ids[1..].iter().map(|&x| if x == NONE { NONE } else { x - root })).collect()
92 };
93 let parents: Vec<u32> = rebase(&self.parents[r..]);
94 let prev_sibs: Vec<u32> = rebase(&self.prev_sibs[r..]);
95 Tree {
96 text: self.text[base as usize..].into(),
97 kinds: self.kinds[r..].to_vec(),
98 starts: self.starts[r..].iter().map(|s| s - base).collect(),
99 ends: self.ends[r..].iter().map(|e| e - root).collect(),
100 parents,
101 prev_sibs,
102 }
103 }
104
105 pub fn push_tree(&mut self, tree: &Tree) {
108 let root = self.len();
109 let text_base = self.text.len() as u32;
110 let (parent, prev) = match self.open.last_mut() {
111 Some((parent, last_child)) => (*parent, std::mem::replace(last_child, root)),
112 None => (NONE, NONE),
113 };
114 let shift = |x: u32| if x == NONE { NONE } else { x + root };
115 self.kinds.extend_from_slice(&tree.kinds);
116 self.starts.extend(tree.starts.iter().map(|s| s + text_base));
117 self.ends.extend(tree.ends.iter().map(|&e| e + root));
118 self.parents.push(parent);
119 self.parents.extend(tree.parents[1..].iter().map(|&p| shift(p)));
120 self.prev_sibs.push(prev);
121 self.prev_sibs.extend(tree.prev_sibs[1..].iter().map(|&p| shift(p)));
122 self.text.push_str(&tree.text);
123 self.update_room();
124 }
125
126 pub fn push_subtree(&mut self, tree: &Tree, e: ElementId) {
128 if tree.is_token(e) {
129 return self.token(tree.kind(e), tree.text_of(e));
130 }
131 self.start_node(tree.kind(e));
132 for child in tree.children(e) {
133 self.push_subtree(tree, child);
134 }
135 self.finish_node();
136 }
137
138 pub fn finish(self) -> Tree {
139 assert!(self.open.is_empty(), "unbalanced tree builder");
140 assert!(self.parents.iter().skip(1).all(|&p| p != NONE), "tree has more than one root");
141 Tree {
142 text: self.text.into_boxed_str(),
143 kinds: self.kinds,
144 starts: self.starts,
145 ends: self.ends,
146 parents: self.parents,
147 prev_sibs: self.prev_sibs,
148 }
149 }
150
151 #[inline]
152 fn push(&mut self, raw_kind: u16, end: u32) -> ElementId {
153 let len = self.kinds.len();
154 if len >= self.room {
155 self.reserve(len.max(64));
156 }
157 let e = len as u32;
158 let (parent, prev) = match self.open.last_mut() {
159 Some((parent, last_child)) => (*parent, std::mem::replace(last_child, e)),
160 None => (NONE, NONE),
161 };
162 let start = self.text.len() as u32;
163 unsafe {
166 push_unchecked(&mut self.kinds, raw_kind);
167 push_unchecked(&mut self.starts, start);
168 push_unchecked(&mut self.ends, end);
169 push_unchecked(&mut self.parents, parent);
170 push_unchecked(&mut self.prev_sibs, prev);
171 }
172 e
173 }
174}
175
176#[inline(always)]
179unsafe fn push_unchecked<T>(v: &mut Vec<T>, x: T) {
180 debug_assert!(v.len() < v.capacity());
181 let len = v.len();
182 unsafe {
184 v.as_mut_ptr().add(len).write(x);
185 v.set_len(len + 1);
186 }
187}