aboutsummaryrefslogtreecommitdiff
path: root/src/yellow/green.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/yellow/green.rs')
-rw-r--r--src/yellow/green.rs194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/yellow/green.rs b/src/yellow/green.rs
new file mode 100644
index 000000000..ede23b719
--- /dev/null
+++ b/src/yellow/green.rs
@@ -0,0 +1,194 @@
1use std::sync::Arc;
2use text_unit::TextUnit;
3use SyntaxKind;
4
5type TokenText = String;
6
7#[derive(Debug)]
8pub(crate) struct GreenNode {
9 kind: SyntaxKind,
10 data: GreenNodeData,
11}
12
13impl GreenNode {
14 pub(crate) fn new_leaf(kind: SyntaxKind, text: TokenText) -> GreenNode {
15 GreenNode {
16 kind,
17 data: GreenNodeData::Leaf(GreenLeaf { text }),
18 }
19 }
20
21 pub(crate) fn new_branch(
22 kind: SyntaxKind,
23 ) -> GreenNode {
24 let branch = GreenBranch {
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 }
33 }
34
35 pub(crate) fn push_trivia(&mut self, kind: SyntaxKind, text: TokenText) {
36 let branch = match &mut self.data {
37 GreenNodeData::Branch(branch) => branch,
38 _ => panic!()
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 }
64 }
65
66 pub(crate) fn text(&self) -> String {
67 let mut buff = String::new();
68 go(self, &mut buff);
69 return buff;
70 fn go(node: &GreenNode, buff: &mut String) {
71 match &node.data {
72 GreenNodeData::Leaf(l) => buff.push_str(&l.text),
73 GreenNodeData::Branch(branch) => {
74 add_trivia(&branch.leading_trivia, buff);
75 branch.children.iter().for_each(|(child, trivias)| {
76 go(child, buff);
77 add_trivia(trivias, buff);
78 })
79 }
80 }
81 }
82
83 fn add_trivia(trivias: &Trivias, buff: &mut String) {
84 trivias.iter().for_each(|t| buff.push_str(&t.text))
85 }
86 }
87
88 pub(crate) fn n_children(&self) -> usize {
89 match &self.data {
90 GreenNodeData::Leaf(_) => 0,
91 GreenNodeData::Branch(branch) => branch.children.len(),
92 }
93 }
94
95 pub(crate) fn nth_child(&self, idx: usize) -> &Arc<GreenNode> {
96 match &self.data {
97 GreenNodeData::Leaf(_) => panic!("leaf nodes have no children"),
98 GreenNodeData::Branch(branch) => &branch.children[idx].0,
99 }
100 }
101
102 pub(crate) fn nth_trivias(&self, idx: usize) -> &Trivias {
103 match &self.data {
104 GreenNodeData::Leaf(_) => panic!("leaf nodes have no children"),
105 GreenNodeData::Branch(branch) => if idx == 0 {
106 &branch.leading_trivia
107 } else {
108 &branch.children[idx - 1].1
109 },
110 }
111 }
112
113 pub(crate) fn is_leaf(&self) -> bool {
114 match self.data {
115 GreenNodeData::Leaf(_) => true,
116 GreenNodeData::Branch(_) => false
117 }
118 }
119
120 pub(crate) fn leaf_text(&self) -> &str {
121 match &self.data {
122 GreenNodeData::Leaf(l) => l.text.as_str(),
123 GreenNodeData::Branch(_) => panic!("not a leaf")
124 }
125 }
126}
127
128#[derive(Debug)]
129enum GreenNodeData {
130 Leaf(GreenLeaf),
131 Branch(GreenBranch),
132}
133
134#[derive(Debug)]
135struct GreenLeaf {
136 text: TokenText
137}
138
139#[derive(Debug)]
140struct GreenBranch {
141 text_len: TextUnit,
142 leading_trivia: Trivias,
143 children: Vec<(Arc<GreenNode>, Trivias)>,
144}
145
146#[derive(Debug)]
147pub(crate) struct GreenTrivia {
148 pub(crate) kind: SyntaxKind,
149 pub(crate) text: TokenText,
150}
151
152type Trivias = Vec<Arc<GreenTrivia>>;
153
154
155pub(crate) trait TextLen {
156 fn text_len(&self) -> TextUnit;
157}
158
159impl TextLen for GreenTrivia {
160 fn text_len(&self) -> TextUnit {
161 TextUnit::of_str(&self.text)
162 }
163}
164
165impl<T: TextLen> TextLen for Arc<T> {
166 fn text_len(&self) -> TextUnit {
167 let this: &T = self;
168 this.text_len()
169 }
170}
171
172impl TextLen for GreenNode {
173 fn text_len(&self) -> TextUnit {
174 self.text_len()
175 }
176}
177
178impl TextLen for GreenLeaf {
179 fn text_len(&self) -> TextUnit {
180 TextUnit::of_str(&self.text)
181 }
182}
183
184impl TextLen for GreenBranch {
185 fn text_len(&self) -> TextUnit {
186 self.text_len
187 }
188}
189
190impl<T: TextLen> TextLen for [T] {
191 fn text_len(&self) -> TextUnit {
192 self.iter().map(TextLen::text_len).sum()
193 }
194}