diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/yellow/builder.rs | 24 | ||||
-rw-r--r-- | src/yellow/green.rs | 236 | ||||
-rw-r--r-- | src/yellow/mod.rs | 2 | ||||
-rw-r--r-- | src/yellow/red.rs | 43 | ||||
-rw-r--r-- | src/yellow/syntax.rs | 63 |
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 @@ | |||
1 | use std::sync::Arc; | ||
2 | use { | 1 | use { |
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 | ||
8 | pub(crate) struct GreenBuilder { | 7 | pub(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 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | use text_unit::TextUnit; | 2 | use {SyntaxKind::{self, *}, TextUnit}; |
3 | use SyntaxKind; | ||
4 | 3 | ||
5 | type TokenText = String; | 4 | #[derive(Clone, Debug)] |
6 | 5 | pub(crate) enum GreenNode { | |
7 | #[derive(Debug)] | 6 | Leaf(GreenLeaf), |
8 | pub(crate) struct GreenNode { | 7 | Branch(Arc<GreenBranch>), |
9 | kind: SyntaxKind, | ||
10 | data: GreenNodeData, | ||
11 | } | 8 | } |
12 | 9 | ||
13 | impl GreenNode { | 10 | impl 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 { | 47 | pub(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> { | 52 | impl 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 { |
122 | enum 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)] | ||
128 | struct GreenLeaf { | ||
129 | text: TokenText | ||
130 | } | ||
131 | 74 | ||
132 | #[derive(Debug)] | 75 | #[test] |
133 | struct GreenBranch { | 76 | fn 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)] |
140 | pub(crate) struct GreenTrivia { | 82 | pub(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 | ||
145 | type Trivias = Vec<Arc<GreenTrivia>>; | 93 | impl 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 | ||
148 | pub(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 | ||
152 | impl 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 | ||
158 | impl<T: TextLen> TextLen for Arc<T> { | 129 | const N_NEWLINES: usize = 16; |
159 | fn text_len(&self) -> TextUnit { | 130 | const N_SPACES: usize = 64; |
160 | let this: &T = self; | 131 | const 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)] | ||
135 | pub(crate) struct GreenBranch { | ||
136 | text_len: TextUnit, | ||
137 | kind: SyntaxKind, | ||
138 | children: Vec<GreenNode>, | ||
163 | } | 139 | } |
164 | 140 | ||
165 | impl TextLen for GreenNode { | 141 | impl 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 | ||
171 | impl 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 | ||
177 | impl 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 | ||
183 | impl<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 | }; |
10 | pub(crate) use self::{ | 10 | pub(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 @@ | |||
1 | use std::sync::{Arc, RwLock}; | 1 | use std::sync::{Arc, RwLock}; |
2 | use { | 2 | use { |
3 | TextUnit, | 3 | TextUnit, |
4 | yellow::{Ptr, GreenNode, TextLen} | 4 | yellow::{Ptr, GreenNode}, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | #[derive(Debug)] | 7 | #[derive(Debug)] |
8 | pub(crate) struct RedNode { | 8 | pub(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 | ||
21 | impl RedNode { | 21 | impl 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::{ | |||
6 | use { | 6 | use { |
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)] |
13 | pub struct SyntaxNode { | 13 | pub 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 | ||
31 | impl SyntaxNode { | 30 | impl 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 | } |