aboutsummaryrefslogtreecommitdiff
path: root/src/yellow
diff options
context:
space:
mode:
Diffstat (limited to 'src/yellow')
-rw-r--r--src/yellow/builder.rs68
-rw-r--r--src/yellow/mod.rs4
-rw-r--r--src/yellow/syntax.rs10
3 files changed, 76 insertions, 6 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
diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs
index 88d88e226..9e64d042f 100644
--- a/src/yellow/mod.rs
+++ b/src/yellow/mod.rs
@@ -1,6 +1,7 @@
1mod green; 1mod green;
2mod red; 2mod red;
3mod syntax; 3mod syntax;
4mod builder;
4 5
5use std::{ 6use std::{
6 sync::{Arc, Weak}, 7 sync::{Arc, Weak},
@@ -9,7 +10,8 @@ use std::{
9pub(crate) use self::{ 10pub(crate) use self::{
10 green::{GreenNode, TextLen}, 11 green::{GreenNode, TextLen},
11 red::RedNode, 12 red::RedNode,
12 syntax::SError, 13 syntax::SyntaxError,
14 builder::GreenBuilder,
13}; 15};
14pub use self::syntax::SyntaxNode; 16pub use self::syntax::SyntaxNode;
15 17
diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs
index 7b1a05cd9..78fa5bf95 100644
--- a/src/yellow/syntax.rs
+++ b/src/yellow/syntax.rs
@@ -4,7 +4,8 @@ use std::{
4}; 4};
5 5
6use { 6use {
7 TextRange, TextUnit, SyntaxKind, 7 TextRange, TextUnit,
8 SyntaxKind::{self, *},
8 yellow::{Ptr, RedNode, GreenNode, TextLen}, 9 yellow::{Ptr, RedNode, GreenNode, TextLen},
9}; 10};
10 11
@@ -18,17 +19,17 @@ pub struct SyntaxNode {
18#[derive(Clone)] 19#[derive(Clone)]
19pub struct SyntaxRoot { 20pub struct SyntaxRoot {
20 red: Arc<RedNode>, 21 red: Arc<RedNode>,
21 pub(crate) errors: Arc<Vec<SError>>, 22 pub(crate) errors: Arc<Vec<SyntaxError>>,
22} 23}
23 24
24#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] 25#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
25pub(crate) struct SError { 26pub(crate) struct SyntaxError {
26 pub(crate) message: String, 27 pub(crate) message: String,
27 pub(crate) offset: TextUnit, 28 pub(crate) offset: TextUnit,
28} 29}
29 30
30impl SyntaxNode { 31impl SyntaxNode {
31 pub(crate) fn new(root: Arc<GreenNode>, errors: Vec<SError>) -> SyntaxNode { 32 pub(crate) fn new(root: Arc<GreenNode>, errors: Vec<SyntaxError>) -> SyntaxNode {
32 let root = Arc::new(RedNode::new_root(root)); 33 let root = Arc::new(RedNode::new_root(root));
33 let red = Ptr::new(&root); 34 let red = Ptr::new(&root);
34 let root = SyntaxRoot { red: root, errors: Arc::new(errors) }; 35 let root = SyntaxRoot { red: root, errors: Arc::new(errors) };
@@ -123,7 +124,6 @@ impl fmt::Debug for SyntaxNode {
123} 124}
124 125
125fn has_short_text(kind: SyntaxKind) -> bool { 126fn has_short_text(kind: SyntaxKind) -> bool {
126 use syntax_kinds::*;
127 match kind { 127 match kind {
128 IDENT | LIFETIME => true, 128 IDENT | LIFETIME => true,
129 _ => false, 129 _ => false,