diff options
Diffstat (limited to 'src/yellow/builder.rs')
-rw-r--r-- | src/yellow/builder.rs | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/src/yellow/builder.rs b/src/yellow/builder.rs index dbe646cd7..70869952c 100644 --- a/src/yellow/builder.rs +++ b/src/yellow/builder.rs | |||
@@ -1,14 +1,14 @@ | |||
1 | use { | 1 | use { |
2 | parser_impl::Sink, | 2 | parser_impl::Sink, |
3 | yellow::{GreenNode, GreenNodeBuilder, SyntaxError, SyntaxNode, SyntaxRoot}, | 3 | yellow::{GreenNode, SyntaxError, SyntaxNode, SyntaxRoot}, |
4 | SyntaxKind, TextRange, TextUnit, | 4 | SyntaxKind, TextRange, TextUnit, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | pub(crate) struct GreenBuilder<'a> { | 7 | pub(crate) struct GreenBuilder<'a> { |
8 | text: &'a str, | 8 | text: &'a str, |
9 | stack: Vec<GreenNodeBuilder>, | 9 | parents: Vec<(SyntaxKind, usize)>, |
10 | children: Vec<GreenNode>, | ||
10 | pos: TextUnit, | 11 | pos: TextUnit, |
11 | root: Option<GreenNode>, | ||
12 | errors: Vec<SyntaxError>, | 12 | errors: Vec<SyntaxError>, |
13 | } | 13 | } |
14 | 14 | ||
@@ -18,9 +18,9 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { | |||
18 | fn new(text: &'a str) -> Self { | 18 | fn new(text: &'a str) -> Self { |
19 | GreenBuilder { | 19 | GreenBuilder { |
20 | text, | 20 | text, |
21 | stack: Vec::new(), | 21 | parents: Vec::new(), |
22 | children: Vec::new(), | ||
22 | pos: 0.into(), | 23 | pos: 0.into(), |
23 | root: None, | ||
24 | errors: Vec::new(), | 24 | errors: Vec::new(), |
25 | } | 25 | } |
26 | } | 26 | } |
@@ -29,23 +29,24 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { | |||
29 | let range = TextRange::offset_len(self.pos, len); | 29 | let range = TextRange::offset_len(self.pos, len); |
30 | self.pos += len; | 30 | self.pos += len; |
31 | let text = &self.text[range]; | 31 | let text = &self.text[range]; |
32 | let leaf = GreenNodeBuilder::new_leaf(kind, text); | 32 | self.children.push( |
33 | let parent = self.stack.last_mut().unwrap(); | 33 | GreenNode::new_leaf(kind, text) |
34 | parent.push_child(leaf) | 34 | ); |
35 | } | 35 | } |
36 | 36 | ||
37 | fn start_internal(&mut self, kind: SyntaxKind) { | 37 | fn start_internal(&mut self, kind: SyntaxKind) { |
38 | self.stack.push(GreenNodeBuilder::new_internal(kind)) | 38 | let len = self.children.len(); |
39 | self.parents.push((kind, len)); | ||
39 | } | 40 | } |
40 | 41 | ||
41 | fn finish_internal(&mut self) { | 42 | fn finish_internal(&mut self) { |
42 | let builder = self.stack.pop().unwrap(); | 43 | let (kind, first_child) = self.parents.pop().unwrap(); |
43 | let node = builder.build(); | 44 | let children = self.children |
44 | if let Some(parent) = self.stack.last_mut() { | 45 | .drain(first_child..) |
45 | parent.push_child(node); | 46 | .collect(); |
46 | } else { | 47 | self.children.push( |
47 | self.root = Some(node); | 48 | GreenNode::new_branch(kind, children) |
48 | } | 49 | ); |
49 | } | 50 | } |
50 | 51 | ||
51 | fn error(&mut self, message: String) { | 52 | fn error(&mut self, message: String) { |
@@ -55,8 +56,10 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { | |||
55 | }) | 56 | }) |
56 | } | 57 | } |
57 | 58 | ||
58 | fn finish(self) -> SyntaxNode { | 59 | fn finish(mut self) -> SyntaxNode { |
59 | let root = SyntaxRoot::new(self.root.unwrap(), self.errors); | 60 | assert_eq!(self.children.len(), 1); |
61 | let root = self.children.pop().unwrap(); | ||
62 | let root = SyntaxRoot::new(root, self.errors); | ||
60 | SyntaxNode::new_owned(root) | 63 | SyntaxNode::new_owned(root) |
61 | } | 64 | } |
62 | } | 65 | } |