diff options
Diffstat (limited to 'src/yellow/red.rs')
-rw-r--r-- | src/yellow/red.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/yellow/red.rs b/src/yellow/red.rs new file mode 100644 index 000000000..feba99faa --- /dev/null +++ b/src/yellow/red.rs | |||
@@ -0,0 +1,87 @@ | |||
1 | use std::sync::{Arc, Weak, RwLock}; | ||
2 | use { | ||
3 | TextUnit, SyntaxKind, TextRange, | ||
4 | yellow::{Ptr, GreenNode, TextLen} | ||
5 | }; | ||
6 | |||
7 | #[derive(Debug)] | ||
8 | pub(crate) struct RedNode { | ||
9 | green: Arc<GreenNode>, | ||
10 | parent: Option<ParentData>, | ||
11 | children: RwLock<Vec<Option<Arc<RedNode>>>>, | ||
12 | } | ||
13 | |||
14 | #[derive(Debug)] | ||
15 | struct ParentData { | ||
16 | parent: Ptr<RedNode>, | ||
17 | start_offset: TextUnit, | ||
18 | index_in_parent: usize, | ||
19 | } | ||
20 | |||
21 | impl RedNode { | ||
22 | pub fn new_root( | ||
23 | green: Arc<GreenNode>, | ||
24 | ) -> RedNode { | ||
25 | RedNode::new(green, None) | ||
26 | } | ||
27 | |||
28 | fn new_child( | ||
29 | green: Arc<GreenNode>, | ||
30 | parent: Ptr<RedNode>, | ||
31 | start_offset: TextUnit, | ||
32 | index_in_parent: usize | ||
33 | ) -> RedNode { | ||
34 | let parent_data = ParentData { | ||
35 | parent, | ||
36 | start_offset, | ||
37 | index_in_parent | ||
38 | }; | ||
39 | RedNode::new(green, Some(parent_data)) | ||
40 | } | ||
41 | |||
42 | fn new( | ||
43 | green: Arc<GreenNode>, | ||
44 | parent: Option<ParentData>, | ||
45 | ) -> RedNode { | ||
46 | let children = vec![None; green.n_children()]; | ||
47 | RedNode { green, parent, children: RwLock::new(children) } | ||
48 | } | ||
49 | |||
50 | pub(crate) fn green(&self) -> &GreenNode { | ||
51 | &self.green | ||
52 | } | ||
53 | |||
54 | pub(crate) fn start_offset(&self) -> TextUnit { | ||
55 | match &self.parent { | ||
56 | None => 0.into(), | ||
57 | Some(p) => p.start_offset, | ||
58 | } | ||
59 | } | ||
60 | |||
61 | pub(crate) fn n_children(&self) -> usize { | ||
62 | self.green.n_children() | ||
63 | } | ||
64 | |||
65 | pub(crate) fn nth_child(&self, me: Ptr<RedNode>, n: usize) -> Arc<RedNode> { | ||
66 | match &self.children.read().unwrap()[n] { | ||
67 | Some(child) => return child.clone(), | ||
68 | None => (), | ||
69 | } | ||
70 | let mut children = self.children.write().unwrap(); | ||
71 | if children[n].is_none() { | ||
72 | let start_offset = { | ||
73 | let mut acc = self.start_offset(); | ||
74 | for i in 0..n { | ||
75 | acc += self.green.nth_trivias(i).text_len(); | ||
76 | acc += self.green.nth_child(i).text_len(); | ||
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 | } | ||
85 | children[n].as_ref().unwrap().clone() | ||
86 | } | ||
87 | } | ||