aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/yellow/red.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/yellow/red.rs')
-rw-r--r--crates/libsyntax2/src/yellow/red.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/crates/libsyntax2/src/yellow/red.rs b/crates/libsyntax2/src/yellow/red.rs
new file mode 100644
index 000000000..13ad44c65
--- /dev/null
+++ b/crates/libsyntax2/src/yellow/red.rs
@@ -0,0 +1,94 @@
1use parking_lot::RwLock;
2use {yellow::{GreenNode, RedPtr}, TextUnit};
3
4#[derive(Debug)]
5pub(crate) struct RedNode {
6 green: GreenNode,
7 parent: Option<ParentData>,
8 children: RwLock<Box<[Option<RedNode>]>>,
9}
10
11#[derive(Debug)]
12struct ParentData {
13 parent: RedPtr,
14 start_offset: TextUnit,
15 index_in_parent: usize,
16}
17
18impl RedNode {
19 pub fn new_root(green: GreenNode) -> RedNode {
20 RedNode::new(green, None)
21 }
22
23 fn new_child(
24 green: GreenNode,
25 parent: RedPtr,
26 start_offset: TextUnit,
27 index_in_parent: usize,
28 ) -> RedNode {
29 let parent_data = ParentData {
30 parent,
31 start_offset,
32 index_in_parent,
33 };
34 RedNode::new(green, Some(parent_data))
35 }
36
37 fn new(green: GreenNode, parent: Option<ParentData>) -> RedNode {
38 let n_children = green.children().len();
39 let children = (0..n_children)
40 .map(|_| None)
41 .collect::<Vec<_>>()
42 .into_boxed_slice();
43 RedNode {
44 green,
45 parent,
46 children: RwLock::new(children),
47 }
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.children().len()
63 }
64
65 pub(crate) fn get_child(&self, idx: usize) -> Option<RedPtr> {
66 if idx >= self.n_children() {
67 return None;
68 }
69 match &self.children.read()[idx] {
70 Some(child) => return Some(RedPtr::new(child)),
71 None => (),
72 };
73 let green_children = self.green.children();
74 let start_offset = self.start_offset()
75 + green_children[..idx]
76 .iter()
77 .map(|x| x.text_len())
78 .sum::<TextUnit>();
79 let child =
80 RedNode::new_child(green_children[idx].clone(), RedPtr::new(self), start_offset, idx);
81 let mut children = self.children.write();
82 if children[idx].is_none() {
83 children[idx] = Some(child)
84 }
85 Some(RedPtr::new(children[idx].as_ref().unwrap()))
86 }
87
88 pub(crate) fn parent(&self) -> Option<RedPtr> {
89 Some(self.parent.as_ref()?.parent)
90 }
91 pub(crate) fn index_in_parent(&self) -> Option<usize> {
92 Some(self.parent.as_ref()?.index_in_parent)
93 }
94}