aboutsummaryrefslogtreecommitdiff
path: root/src/tree
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree')
-rw-r--r--src/tree/file_builder.rs53
-rw-r--r--src/tree/mod.rs2
2 files changed, 32 insertions, 23 deletions
diff --git a/src/tree/file_builder.rs b/src/tree/file_builder.rs
index 430303ce9..eba850fef 100644
--- a/src/tree/file_builder.rs
+++ b/src/tree/file_builder.rs
@@ -1,6 +1,13 @@
1use {SyntaxKind, TextUnit, TextRange}; 1use {SyntaxKind, TextUnit, TextRange};
2use super::{NodeData, NodeIdx, File}; 2use super::{NodeData, NodeIdx, File};
3 3
4pub trait Sink {
5 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
6 fn start_internal(&mut self, kind: SyntaxKind);
7 fn finish_internal(&mut self);
8}
9
10
4pub struct FileBuilder { 11pub struct FileBuilder {
5 text: String, 12 text: String,
6 nodes: Vec<NodeData>, 13 nodes: Vec<NodeData>,
@@ -8,26 +15,8 @@ pub struct FileBuilder {
8 pos: TextUnit, 15 pos: TextUnit,
9} 16}
10 17
11impl FileBuilder { 18impl Sink for FileBuilder {
12 pub fn new(text: String) -> FileBuilder { 19 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
13 FileBuilder {
14 text,
15 nodes: Vec::new(),
16 in_progress: Vec::new(),
17 pos: TextUnit::new(0),
18 }
19 }
20
21 pub fn finish(self) -> File {
22 assert!(self.in_progress.is_empty());
23 assert!(self.pos == (self.text.len() as u32).into());
24 File {
25 text: self.text,
26 nodes: self.nodes,
27 }
28 }
29
30 pub fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
31 let leaf = NodeData { 20 let leaf = NodeData {
32 kind, 21 kind,
33 range: TextRange::from_len(self.pos, len), 22 range: TextRange::from_len(self.pos, len),
@@ -40,7 +29,7 @@ impl FileBuilder {
40 self.add_len(id); 29 self.add_len(id);
41 } 30 }
42 31
43 pub fn start_internal(&mut self, kind: SyntaxKind) { 32 fn start_internal(&mut self, kind: SyntaxKind) {
44 let node = NodeData { 33 let node = NodeData {
45 kind, 34 kind,
46 range: TextRange::from_len(self.pos, 0.into()), 35 range: TextRange::from_len(self.pos, 0.into()),
@@ -56,12 +45,32 @@ impl FileBuilder {
56 self.in_progress.push((id, None)) 45 self.in_progress.push((id, None))
57 } 46 }
58 47
59 pub fn finish_internal(&mut self) { 48 fn finish_internal(&mut self) {
60 let (id, _) = self.in_progress.pop().unwrap(); 49 let (id, _) = self.in_progress.pop().unwrap();
61 if !self.in_progress.is_empty() { 50 if !self.in_progress.is_empty() {
62 self.add_len(id); 51 self.add_len(id);
63 } 52 }
64 } 53 }
54}
55
56impl FileBuilder {
57 pub fn new(text: String) -> FileBuilder {
58 FileBuilder {
59 text,
60 nodes: Vec::new(),
61 in_progress: Vec::new(),
62 pos: TextUnit::new(0),
63 }
64 }
65
66 pub fn finish(self) -> File {
67 assert!(self.in_progress.is_empty());
68 assert!(self.pos == (self.text.len() as u32).into());
69 File {
70 text: self.text,
71 nodes: self.nodes,
72 }
73 }
65 74
66 fn new_node(&mut self, data: NodeData) -> NodeIdx { 75 fn new_node(&mut self, data: NodeData) -> NodeIdx {
67 let id = NodeIdx(self.nodes.len() as u32); 76 let id = NodeIdx(self.nodes.len() as u32);
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index 6bacb46ef..7a5d429a3 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -4,7 +4,7 @@ use syntax_kinds::syntax_info;
4use std::fmt; 4use std::fmt;
5 5
6mod file_builder; 6mod file_builder;
7pub use self::file_builder::FileBuilder; 7pub use self::file_builder::{FileBuilder, Sink};
8 8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct SyntaxKind(pub(crate) u32); 10pub struct SyntaxKind(pub(crate) u32);