diff options
Diffstat (limited to 'src/yellow/builder.rs')
-rw-r--r-- | src/yellow/builder.rs | 68 |
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 @@ | |||
1 | use std::sync::Arc; | ||
2 | use { | ||
3 | SyntaxKind, TextRange, TextUnit, | ||
4 | yellow::{SyntaxNode, GreenNode, SyntaxError}, | ||
5 | parser::Sink | ||
6 | }; | ||
7 | |||
8 | pub(crate) struct GreenBuilder { | ||
9 | text: String, | ||
10 | stack: Vec<GreenNode>, | ||
11 | pos: TextUnit, | ||
12 | root: Option<GreenNode>, | ||
13 | errors: Vec<SyntaxError>, | ||
14 | } | ||
15 | |||
16 | impl GreenBuilder { | ||
17 | |||
18 | } | ||
19 | |||
20 | impl 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 | |||