aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-08 19:14:18 +0100
committerAleksey Kladov <[email protected]>2018-08-08 19:14:18 +0100
commita5dc5f1b5cc7932477225128b2c6c9e8dff9cd73 (patch)
tree5fde33bb0e3887a015e08315ca562d6757a7e8c1
parent1fa5b2ffbc0f1dd3cfc45adff0329e1bdd46c131 (diff)
Improve tree building
-rw-r--r--Cargo.toml3
-rw-r--r--cli/src/main.rs1
-rw-r--r--src/yellow/builder.rs39
-rw-r--r--src/yellow/green.rs35
-rw-r--r--src/yellow/mod.rs2
5 files changed, 34 insertions, 46 deletions
diff --git a/Cargo.toml b/Cargo.toml
index c343ac57b..f03ce76c9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,3 +16,6 @@ parking_lot = "0.6.0"
16 16
17[dev-dependencies] 17[dev-dependencies]
18testutils = { path = "./tests/testutils" } 18testutils = { path = "./tests/testutils" }
19
20[profile.release]
21debug = true \ No newline at end of file
diff --git a/cli/src/main.rs b/cli/src/main.rs
index e5b1aae46..f6c66743f 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -47,6 +47,7 @@ fn main() -> Result<()> {
47 println!("{}", file.syntax_tree()); 47 println!("{}", file.syntax_tree());
48 } 48 }
49 eprintln!("parsing: {:?}", elapsed); 49 eprintln!("parsing: {:?}", elapsed);
50 ::std::mem::forget(file);
50 } 51 }
51 ("symbols", _) => { 52 ("symbols", _) => {
52 let file = file()?; 53 let file = file()?;
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 @@
1use { 1use {
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
7pub(crate) struct GreenBuilder<'a> { 7pub(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}
diff --git a/src/yellow/green.rs b/src/yellow/green.rs
index 26df76af6..5b4ce313a 100644
--- a/src/yellow/green.rs
+++ b/src/yellow/green.rs
@@ -12,6 +12,14 @@ pub(crate) enum GreenNode {
12} 12}
13 13
14impl GreenNode { 14impl GreenNode {
15 pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
16 GreenNode::Leaf(GreenLeaf::new(kind, text))
17 }
18
19 pub(crate) fn new_branch(kind: SyntaxKind, children: Vec<GreenNode>) -> GreenNode {
20 GreenNode::Branch(Arc::new(GreenBranch::new(kind, children)))
21 }
22
15 pub fn kind(&self) -> SyntaxKind { 23 pub fn kind(&self) -> SyntaxKind {
16 match self { 24 match self {
17 GreenNode::Leaf(l) => l.kind(), 25 GreenNode::Leaf(l) => l.kind(),
@@ -46,33 +54,6 @@ impl GreenNode {
46 } 54 }
47} 55}
48 56
49pub(crate) struct GreenNodeBuilder {
50 kind: SyntaxKind,
51 children: Vec<GreenNode>,
52}
53
54impl GreenNodeBuilder {
55 pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
56 GreenNode::Leaf(GreenLeaf::new(kind, text))
57 }
58
59 pub(crate) fn new_internal(kind: SyntaxKind) -> GreenNodeBuilder {
60 GreenNodeBuilder {
61 kind,
62 children: Vec::new(),
63 }
64 }
65
66 pub(crate) fn push_child(&mut self, node: GreenNode) {
67 self.children.push(node)
68 }
69
70 pub(crate) fn build(self) -> GreenNode {
71 let branch = GreenBranch::new(self.kind, self.children);
72 GreenNode::Branch(Arc::new(branch))
73 }
74}
75
76#[test] 57#[test]
77fn assert_send_sync() { 58fn assert_send_sync() {
78 fn f<T: Send + Sync>() {} 59 fn f<T: Send + Sync>() {}
diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs
index f20be356d..1b5d4e4df 100644
--- a/src/yellow/mod.rs
+++ b/src/yellow/mod.rs
@@ -6,7 +6,7 @@ mod syntax;
6pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}; 6pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot};
7pub(crate) use self::{ 7pub(crate) use self::{
8 builder::GreenBuilder, 8 builder::GreenBuilder,
9 green::{GreenNode, GreenNodeBuilder}, 9 green::GreenNode,
10 red::RedNode, 10 red::RedNode,
11 syntax::SyntaxError, 11 syntax::SyntaxError,
12}; 12};