aboutsummaryrefslogtreecommitdiff
path: root/src/yellow/builder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/yellow/builder.rs')
-rw-r--r--src/yellow/builder.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/yellow/builder.rs b/src/yellow/builder.rs
new file mode 100644
index 000000000..346d561cd
--- /dev/null
+++ b/src/yellow/builder.rs
@@ -0,0 +1,68 @@
1use std::sync::Arc;
2use {
3 SyntaxKind, TextRange, TextUnit,
4 yellow::{SyntaxNode, GreenNode, SyntaxError},
5 parser::Sink
6};
7
8pub(crate) struct GreenBuilder {
9 text: String,
10 stack: Vec<GreenNode>,
11 pos: TextUnit,
12 root: Option<GreenNode>,
13 errors: Vec<SyntaxError>,
14}
15
16impl GreenBuilder {
17
18}
19
20impl Sink for GreenBuilder {
21 type Tree = SyntaxNode;
22
23 fn new(text: String) -> Self {
24 GreenBuilder {
25 text,
26 stack: Vec::new(),
27 pos: 0.into(),
28 root: None,
29 errors: Vec::new(),
30 }
31 }
32
33 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
34 let range = TextRange::offset_len(self.pos, len);
35 self.pos += len;
36 let text = self.text[range].to_owned();
37 let parent = self.stack.last_mut().unwrap();
38 if kind.is_trivia() {
39 parent.push_trivia(kind, text);
40 } else {
41 let node = GreenNode::new_leaf(kind, text);
42 parent.push_child(Arc::new(node));
43 }
44 }
45
46 fn start_internal(&mut self, kind: SyntaxKind) {
47 self.stack.push(GreenNode::new_branch(kind))
48 }
49
50 fn finish_internal(&mut self) {
51 let node = self.stack.pop().unwrap();
52 if let Some(parent) = self.stack.last_mut() {
53 parent.push_child(Arc::new(node))
54 } else {
55 self.root = Some(node);
56 }
57 }
58
59 fn error(&mut self, message: String) {
60 self.errors.push(SyntaxError { message, offset: self.pos })
61 }
62
63 fn finish(self) -> SyntaxNode {
64 SyntaxNode::new(Arc::new(self.root.unwrap()), self.errors)
65 }
66}
67
68