aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yellow/builder.rs24
-rw-r--r--src/yellow/green.rs236
-rw-r--r--src/yellow/mod.rs2
-rw-r--r--src/yellow/red.rs43
-rw-r--r--src/yellow/syntax.rs63
5 files changed, 143 insertions, 225 deletions
diff --git a/src/yellow/builder.rs b/src/yellow/builder.rs
index 346d561cd..73b4b5ff9 100644
--- a/src/yellow/builder.rs
+++ b/src/yellow/builder.rs
@@ -1,13 +1,12 @@
1use std::sync::Arc;
2use { 1use {
3 SyntaxKind, TextRange, TextUnit, 2 SyntaxKind, TextRange, TextUnit,
4 yellow::{SyntaxNode, GreenNode, SyntaxError}, 3 yellow::{SyntaxNode, GreenNode, GreenNodeBuilder, SyntaxError},
5 parser::Sink 4 parser::Sink
6}; 5};
7 6
8pub(crate) struct GreenBuilder { 7pub(crate) struct GreenBuilder {
9 text: String, 8 text: String,
10 stack: Vec<GreenNode>, 9 stack: Vec<GreenNodeBuilder>,
11 pos: TextUnit, 10 pos: TextUnit,
12 root: Option<GreenNode>, 11 root: Option<GreenNode>,
13 errors: Vec<SyntaxError>, 12 errors: Vec<SyntaxError>,
@@ -33,24 +32,21 @@ impl Sink for GreenBuilder {
33 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) { 32 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
34 let range = TextRange::offset_len(self.pos, len); 33 let range = TextRange::offset_len(self.pos, len);
35 self.pos += len; 34 self.pos += len;
36 let text = self.text[range].to_owned(); 35 let text = &self.text[range];
36 let leaf = GreenNodeBuilder::new_leaf(kind, text);
37 let parent = self.stack.last_mut().unwrap(); 37 let parent = self.stack.last_mut().unwrap();
38 if kind.is_trivia() { 38 parent.push_child(leaf)
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 } 39 }
45 40
46 fn start_internal(&mut self, kind: SyntaxKind) { 41 fn start_internal(&mut self, kind: SyntaxKind) {
47 self.stack.push(GreenNode::new_branch(kind)) 42 self.stack.push(GreenNodeBuilder::new_internal(kind))
48 } 43 }
49 44
50 fn finish_internal(&mut self) { 45 fn finish_internal(&mut self) {
51 let node = self.stack.pop().unwrap(); 46 let builder = self.stack.pop().unwrap();
47 let node = builder.build();
52 if let Some(parent) = self.stack.last_mut() { 48 if let Some(parent) = self.stack.last_mut() {
53 parent.push_child(Arc::new(node)) 49 parent.push_child(node);
54 } else { 50 } else {
55 self.root = Some(node); 51 self.root = Some(node);
56 } 52 }
@@ -61,7 +57,7 @@ impl Sink for GreenBuilder {
61 } 57 }
62 58
63 fn finish(self) -> SyntaxNode { 59 fn finish(self) -> SyntaxNode {
64 SyntaxNode::new(Arc::new(self.root.unwrap()), self.errors) 60 SyntaxNode::new(self.root.unwrap(), self.errors)
65 } 61 }
66} 62}
67 63
diff --git a/src/yellow/green.rs b/src/yellow/green.rs
index dafe1bb22..cb9dff128 100644
--- a/src/yellow/green.rs
+++ b/src/yellow/green.rs
@@ -1,187 +1,159 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use text_unit::TextUnit; 2use {SyntaxKind::{self, *}, TextUnit};
3use SyntaxKind;
4 3
5type TokenText = String; 4#[derive(Clone, Debug)]
6 5pub(crate) enum GreenNode {
7#[derive(Debug)] 6 Leaf(GreenLeaf),
8pub(crate) struct GreenNode { 7 Branch(Arc<GreenBranch>),
9 kind: SyntaxKind,
10 data: GreenNodeData,
11} 8}
12 9
13impl GreenNode { 10impl GreenNode {
14 pub(crate) fn new_leaf(kind: SyntaxKind, text: TokenText) -> GreenNode { 11 pub fn kind(&self) -> SyntaxKind {
15 GreenNode { 12 match self {
16 kind, 13 GreenNode::Leaf(l) => l.kind(),
17 data: GreenNodeData::Leaf(GreenLeaf { text }), 14 GreenNode::Branch(b) => b.kind(),
18 } 15 }
19 } 16 }
20 17
21 pub(crate) fn new_branch( 18 pub fn text_len(&self) -> TextUnit {
22 kind: SyntaxKind, 19 match self {
23 ) -> GreenNode { 20 GreenNode::Leaf(l) => l.text_len(),
24 let branch = GreenBranch { 21 GreenNode::Branch(b) => b.text_len(),
25 text_len: 0.into(),
26 leading_trivia: Trivias::default(),
27 children: Vec::new(),
28 };
29 GreenNode {
30 kind,
31 data: GreenNodeData::Branch(branch),
32 } 22 }
33 } 23 }
34 24
35 pub(crate) fn push_trivia(&mut self, kind: SyntaxKind, text: TokenText) { 25 pub fn children(&self) -> &[GreenNode] {
36 let branch = match &mut self.data { 26 match self {
37 GreenNodeData::Branch(branch) => branch, 27 GreenNode::Leaf(_) => &[],
38 _ => panic!() 28 GreenNode::Branch(b) => b.children(),
39 };
40 branch.text_len += TextUnit::of_str(&text);
41 let leading = &mut branch.leading_trivia;
42 branch.children.last_mut().map(|(_, t)| t).unwrap_or(leading)
43 .push(Arc::new(GreenTrivia { kind, text }));
44 }
45
46 pub(crate) fn push_child(&mut self, node: Arc<GreenNode>) {
47 let branch = match &mut self.data {
48 GreenNodeData::Branch(branch) => branch,
49 _ => panic!()
50 };
51 branch.text_len += node.text_len();
52 branch.children.push((node, Trivias::default()));
53 }
54
55 pub(crate) fn kind(&self) -> SyntaxKind {
56 self.kind
57 }
58
59 pub(crate) fn text_len(&self) -> TextUnit {
60 match &self.data {
61 GreenNodeData::Leaf(l) => l.text_len(),
62 GreenNodeData::Branch(b) => b.text_len(),
63 } 29 }
64 } 30 }
65 31
66 pub(crate) fn text(&self) -> String { 32 pub fn text(&self) -> String {
67 let mut buff = String::new(); 33 let mut buff = String::new();
68 go(self, &mut buff); 34 go(self, &mut buff);
69 return buff; 35 return buff;
70 fn go(node: &GreenNode, buff: &mut String) { 36 fn go(node: &GreenNode, buff: &mut String) {
71 match &node.data { 37 match node {
72 GreenNodeData::Leaf(l) => buff.push_str(&l.text), 38 GreenNode::Leaf(l) => buff.push_str(&l.text()),
73 GreenNodeData::Branch(branch) => { 39 GreenNode::Branch(b) => {
74 add_trivia(&branch.leading_trivia, buff); 40 b.children().iter().for_each(|child| go(child, buff))
75 branch.children.iter().for_each(|(child, trivias)| {
76 go(child, buff);
77 add_trivia(trivias, buff);
78 })
79 } 41 }
80 } 42 }
81 } 43 }
82
83 fn add_trivia(trivias: &Trivias, buff: &mut String) {
84 trivias.iter().for_each(|t| buff.push_str(&t.text))
85 }
86 } 44 }
45}
87 46
88 pub(crate) fn n_children(&self) -> usize { 47pub(crate) struct GreenNodeBuilder {
89 match &self.data { 48 kind: SyntaxKind,
90 GreenNodeData::Leaf(_) => 0, 49 children: Vec<GreenNode>,
91 GreenNodeData::Branch(branch) => branch.children.len(), 50}
92 }
93 }
94 51
95 pub(crate) fn nth_child(&self, idx: usize) -> &Arc<GreenNode> { 52impl GreenNodeBuilder {
96 match &self.data { 53 pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
97 GreenNodeData::Leaf(_) => panic!("leaf nodes have no children"), 54 GreenNode::Leaf(GreenLeaf::new(kind, text))
98 GreenNodeData::Branch(branch) => &branch.children[idx].0,
99 }
100 } 55 }
101 56
102 pub(crate) fn nth_trivias(&self, idx: usize) -> &Trivias { 57 pub(crate) fn new_internal(kind: SyntaxKind) -> GreenNodeBuilder {
103 match &self.data { 58 GreenNodeBuilder {
104 GreenNodeData::Leaf(_) => panic!("leaf nodes have no children"), 59 kind,
105 GreenNodeData::Branch(branch) => if idx == 0 { 60 children: Vec::new(),
106 &branch.leading_trivia
107 } else {
108 &branch.children[idx - 1].1
109 },
110 } 61 }
111 } 62 }
112 63
113 pub(crate) fn is_leaf(&self) -> bool { 64 pub(crate) fn push_child(&mut self, node: GreenNode) {
114 match self.data { 65 self.children.push(node)
115 GreenNodeData::Leaf(_) => true,
116 GreenNodeData::Branch(_) => false
117 }
118 } 66 }
119}
120 67
121#[derive(Debug)] 68 pub(crate) fn build(self) -> GreenNode {
122enum GreenNodeData { 69 let branch = GreenBranch::new(self.kind, self.children);
123 Leaf(GreenLeaf), 70 GreenNode::Branch(Arc::new(branch))
124 Branch(GreenBranch), 71 }
125} 72}
126 73
127#[derive(Debug)]
128struct GreenLeaf {
129 text: TokenText
130}
131 74
132#[derive(Debug)] 75#[test]
133struct GreenBranch { 76fn assert_send_sync() {
134 text_len: TextUnit, 77 fn f<T: Send + Sync>() {}
135 leading_trivia: Trivias, 78 f::<GreenNode>();
136 children: Vec<(Arc<GreenNode>, Trivias)>,
137} 79}
138 80
139#[derive(Debug)] 81#[derive(Clone, Debug)]
140pub(crate) struct GreenTrivia { 82pub(crate) enum GreenLeaf {
141 pub(crate) kind: SyntaxKind, 83 Whitespace {
142 pub(crate) text: TokenText, 84 newlines: u8,
85 spaces: u8,
86 },
87 Token {
88 kind: SyntaxKind,
89 text: Arc<str>,
90 },
143} 91}
144 92
145type Trivias = Vec<Arc<GreenTrivia>>; 93impl GreenLeaf {
94 fn new(kind: SyntaxKind, text: &str) -> Self {
95 if kind == WHITESPACE {
96 let newlines = text.bytes().take_while(|&b| b == b'\n').count();
97 let spaces = text[newlines..].bytes().take_while(|&b| b == b' ').count();
98 if newlines + spaces == text.len() && newlines <= N_NEWLINES && spaces <= N_SPACES {
99 return GreenLeaf::Whitespace { newlines: newlines as u8, spaces: spaces as u8 };
100 }
101 }
102 GreenLeaf::Token { kind, text: text.to_owned().into_boxed_str().into() }
103 }
146 104
105 pub(crate) fn kind(&self) -> SyntaxKind {
106 match self {
107 GreenLeaf::Whitespace { .. } => WHITESPACE,
108 GreenLeaf::Token { kind, .. } => *kind,
109 }
110 }
147 111
148pub(crate) trait TextLen { 112 pub(crate) fn text(&self) -> &str {
149 fn text_len(&self) -> TextUnit; 113 match self {
150} 114 &GreenLeaf::Whitespace { newlines, spaces } => {
115 let newlines = newlines as usize;
116 let spaces = spaces as usize;
117 assert!(newlines <= N_NEWLINES && spaces <= N_SPACES);
118 &WS[N_NEWLINES - newlines..N_NEWLINES + spaces]
119 }
120 GreenLeaf::Token { text, .. } => text,
121 }
122 }
151 123
152impl TextLen for GreenTrivia { 124 pub(crate) fn text_len(&self) -> TextUnit {
153 fn text_len(&self) -> TextUnit { 125 TextUnit::of_str(self.text())
154 TextUnit::of_str(&self.text)
155 } 126 }
156} 127}
157 128
158impl<T: TextLen> TextLen for Arc<T> { 129const N_NEWLINES: usize = 16;
159 fn text_len(&self) -> TextUnit { 130const N_SPACES: usize = 64;
160 let this: &T = self; 131const WS: &str =
161 this.text_len() 132 "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n ";
162 } 133
134#[derive(Clone, Debug)]
135pub(crate) struct GreenBranch {
136 text_len: TextUnit,
137 kind: SyntaxKind,
138 children: Vec<GreenNode>,
163} 139}
164 140
165impl TextLen for GreenNode { 141impl GreenBranch {
166 fn text_len(&self) -> TextUnit { 142 fn new(kind: SyntaxKind, children: Vec<GreenNode>) -> GreenBranch {
167 self.text_len() 143 let text_len = children.iter().map(|x| x.text_len()).sum::<TextUnit>();
144 GreenBranch { text_len, kind, children }
168 } 145 }
169}
170 146
171impl TextLen for GreenLeaf { 147 pub fn kind(&self) -> SyntaxKind {
172 fn text_len(&self) -> TextUnit { 148 self.kind
173 TextUnit::of_str(&self.text)
174 } 149 }
175}
176 150
177impl TextLen for GreenBranch { 151 pub fn text_len(&self) -> TextUnit {
178 fn text_len(&self) -> TextUnit {
179 self.text_len 152 self.text_len
180 } 153 }
181}
182 154
183impl<T: TextLen> TextLen for [T] { 155 pub fn children(&self) -> &[GreenNode] {
184 fn text_len(&self) -> TextUnit { 156 self.children.as_slice()
185 self.iter().map(TextLen::text_len).sum()
186 } 157 }
187} 158}
159
diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs
index 9e64d042f..9a6203cc1 100644
--- a/src/yellow/mod.rs
+++ b/src/yellow/mod.rs
@@ -8,7 +8,7 @@ use std::{
8 mem 8 mem
9}; 9};
10pub(crate) use self::{ 10pub(crate) use self::{
11 green::{GreenNode, TextLen}, 11 green::{GreenNode, GreenNodeBuilder},
12 red::RedNode, 12 red::RedNode,
13 syntax::SyntaxError, 13 syntax::SyntaxError,
14 builder::GreenBuilder, 14 builder::GreenBuilder,
diff --git a/src/yellow/red.rs b/src/yellow/red.rs
index 71212a081..e2dbceeae 100644
--- a/src/yellow/red.rs
+++ b/src/yellow/red.rs
@@ -1,12 +1,12 @@
1use std::sync::{Arc, RwLock}; 1use std::sync::{Arc, RwLock};
2use { 2use {
3 TextUnit, 3 TextUnit,
4 yellow::{Ptr, GreenNode, TextLen} 4 yellow::{Ptr, GreenNode},
5}; 5};
6 6
7#[derive(Debug)] 7#[derive(Debug)]
8pub(crate) struct RedNode { 8pub(crate) struct RedNode {
9 green: Arc<GreenNode>, 9 green: GreenNode,
10 parent: Option<ParentData>, 10 parent: Option<ParentData>,
11 children: RwLock<Vec<Option<Arc<RedNode>>>>, 11 children: RwLock<Vec<Option<Arc<RedNode>>>>,
12} 12}
@@ -20,30 +20,30 @@ struct ParentData {
20 20
21impl RedNode { 21impl RedNode {
22 pub fn new_root( 22 pub fn new_root(
23 green: Arc<GreenNode>, 23 green: GreenNode,
24 ) -> RedNode { 24 ) -> RedNode {
25 RedNode::new(green, None) 25 RedNode::new(green, None)
26 } 26 }
27 27
28 fn new_child( 28 fn new_child(
29 green: Arc<GreenNode>, 29 green: GreenNode,
30 parent: Ptr<RedNode>, 30 parent: Ptr<RedNode>,
31 start_offset: TextUnit, 31 start_offset: TextUnit,
32 index_in_parent: usize 32 index_in_parent: usize,
33 ) -> RedNode { 33 ) -> RedNode {
34 let parent_data = ParentData { 34 let parent_data = ParentData {
35 parent, 35 parent,
36 start_offset, 36 start_offset,
37 index_in_parent 37 index_in_parent,
38 }; 38 };
39 RedNode::new(green, Some(parent_data)) 39 RedNode::new(green, Some(parent_data))
40 } 40 }
41 41
42 fn new( 42 fn new(
43 green: Arc<GreenNode>, 43 green: GreenNode,
44 parent: Option<ParentData>, 44 parent: Option<ParentData>,
45 ) -> RedNode { 45 ) -> RedNode {
46 let children = vec![None; green.n_children()]; 46 let children = vec![None; green.children().len()];
47 RedNode { green, parent, children: RwLock::new(children) } 47 RedNode { green, parent, children: RwLock::new(children) }
48 } 48 }
49 49
@@ -59,29 +59,22 @@ impl RedNode {
59 } 59 }
60 60
61 pub(crate) fn n_children(&self) -> usize { 61 pub(crate) fn n_children(&self) -> usize {
62 self.green.n_children() 62 self.green.children().len()
63 } 63 }
64 64
65 pub(crate) fn nth_child(&self, me: Ptr<RedNode>, n: usize) -> Arc<RedNode> { 65 pub(crate) fn nth_child(&self, me: Ptr<RedNode>, idx: usize) -> Arc<RedNode> {
66 match &self.children.read().unwrap()[n] { 66 match &self.children.read().unwrap()[idx] {
67 Some(child) => return child.clone(), 67 Some(child) => return child.clone(),
68 None => (), 68 None => (),
69 } 69 }
70 let mut children = self.children.write().unwrap(); 70 let mut children = self.children.write().unwrap();
71 if children[n].is_none() { 71 if children[idx].is_none() {
72 let start_offset = { 72 let green_children = self.green.children();
73 let mut acc = self.start_offset(); 73 let start_offset = self.start_offset()
74 for i in 0..n { 74 + green_children[..idx].iter().map(|x| x.text_len()).sum::<TextUnit>();
75 acc += self.green.nth_trivias(i).text_len(); 75 let child = RedNode::new_child(green_children[idx].clone(), me, start_offset, idx);
76 acc += self.green.nth_child(i).text_len(); 76 children[idx] = Some(Arc::new(child))
77 }
78 acc += self.green.nth_trivias(n).text_len();
79 acc
80 };
81 let green = self.green.nth_child(n).clone();
82 let child = RedNode::new_child(green, me, start_offset, n);
83 children[n] = Some(Arc::new(child))
84 } 77 }
85 children[n].as_ref().unwrap().clone() 78 children[idx].as_ref().unwrap().clone()
86 } 79 }
87} 80}
diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs
index 78fa5bf95..53d8c82b9 100644
--- a/src/yellow/syntax.rs
+++ b/src/yellow/syntax.rs
@@ -6,14 +6,13 @@ use std::{
6use { 6use {
7 TextRange, TextUnit, 7 TextRange, TextUnit,
8 SyntaxKind::{self, *}, 8 SyntaxKind::{self, *},
9 yellow::{Ptr, RedNode, GreenNode, TextLen}, 9 yellow::{Ptr, RedNode, GreenNode},
10}; 10};
11 11
12#[derive(Clone)] 12#[derive(Clone)]
13pub struct SyntaxNode { 13pub struct SyntaxNode {
14 pub(crate) root: SyntaxRoot, 14 pub(crate) root: SyntaxRoot,
15 red: Ptr<RedNode>, 15 red: Ptr<RedNode>,
16 trivia_pos: Option<(usize, usize)>,
17} 16}
18 17
19#[derive(Clone)] 18#[derive(Clone)]
@@ -29,80 +28,38 @@ pub(crate) struct SyntaxError {
29} 28}
30 29
31impl SyntaxNode { 30impl SyntaxNode {
32 pub(crate) fn new(root: Arc<GreenNode>, errors: Vec<SyntaxError>) -> SyntaxNode { 31 pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
33 let root = Arc::new(RedNode::new_root(root)); 32 let root = Arc::new(RedNode::new_root(root));
34 let red = Ptr::new(&root); 33 let red = Ptr::new(&root);
35 let root = SyntaxRoot { red: root, errors: Arc::new(errors) }; 34 let root = SyntaxRoot { red: root, errors: Arc::new(errors) };
36 SyntaxNode { root, red, trivia_pos: None } 35 SyntaxNode { root, red }
37 } 36 }
38 37
39 pub fn kind(&self) -> SyntaxKind { 38 pub fn kind(&self) -> SyntaxKind {
40 let green = self.red().green(); 39 self.red().green().kind()
41 match self.trivia_pos {
42 None => green.kind(),
43 Some((i, j)) => green.nth_trivias(i)[j].kind
44 }
45 } 40 }
46 41
47 pub fn range(&self) -> TextRange { 42 pub fn range(&self) -> TextRange {
48 let red = self.red(); 43 let red = self.red();
49 let green = red.green(); 44 TextRange::offset_len(
50 match self.trivia_pos { 45 red.start_offset(),
51 None => TextRange::offset_len(red.start_offset(), red.green().text_len()), 46 red.green().text_len(),
52 Some((i, j)) => { 47 )
53 let trivias = green.nth_trivias(i);
54 let offset = if i == 0 {
55 red.start_offset()
56 } else {
57 let prev_child = red.nth_child(Ptr::clone(&self.red), i - 1);
58 let mut offset = prev_child.start_offset() + prev_child.green().text_len();
59 for k in 0..j {
60 offset += &trivias[k].text_len();
61 }
62 offset
63 };
64 TextRange::offset_len(offset, trivias[j].text_len())
65 }
66 }
67 } 48 }
68 49
69 pub fn text(&self) -> String { 50 pub fn text(&self) -> String {
70 let green = self.red().green(); 51 self.red().green().text()
71 match self.trivia_pos {
72 None => green.text(),
73 Some((i, j)) => green.nth_trivias(i)[j].text.clone()
74 }
75 } 52 }
76 53
77 pub fn children(&self) -> Vec<SyntaxNode> { 54 pub fn children(&self) -> Vec<SyntaxNode> {
78 let mut res = Vec::new();
79 let red = self.red(); 55 let red = self.red();
80 let green = red.green();
81 if green.is_leaf() || self.trivia_pos.is_some() {
82 return Vec::new();
83 }
84 for (j, _) in green.nth_trivias(0).iter().enumerate() {
85 res.push(SyntaxNode {
86 root: self.root.clone(),
87 red: Ptr::clone(&self.red),
88 trivia_pos: Some((0, j)),
89 })
90 }
91
92 let n_children = red.n_children(); 56 let n_children = red.n_children();
57 let mut res = Vec::with_capacity(n_children);
93 for i in 0..n_children { 58 for i in 0..n_children {
94 res.push(SyntaxNode { 59 res.push(SyntaxNode {
95 root: self.root.clone(), 60 root: self.root.clone(),
96 red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)), 61 red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)),
97 trivia_pos: None,
98 }); 62 });
99 for (j, _) in green.nth_trivias(i + 1).iter().enumerate() {
100 res.push(SyntaxNode {
101 root: self.root.clone(),
102 red: self.red.clone(),
103 trivia_pos: Some((i + 1, j)),
104 })
105 }
106 } 63 }
107 res 64 res
108 } 65 }