]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | use std::{fmt, marker::PhantomData}; |
2 | ||
3 | use crate::{ | |
4 | cursor, Direction, GreenNode, GreenToken, NodeOrToken, SmolStr, SyntaxKind, SyntaxText, | |
5 | TextRange, TextSize, TokenAtOffset, WalkEvent, | |
6 | }; | |
7 | ||
8 | pub trait Language: Sized + Clone + Copy + fmt::Debug + Eq + Ord + std::hash::Hash { | |
9 | type Kind: fmt::Debug; | |
10 | ||
11 | fn kind_from_raw(raw: SyntaxKind) -> Self::Kind; | |
12 | fn kind_to_raw(kind: Self::Kind) -> SyntaxKind; | |
13 | } | |
14 | ||
15 | #[derive(Clone, PartialEq, Eq, Hash)] | |
16 | pub struct SyntaxNode<L: Language> { | |
17 | raw: cursor::SyntaxNode, | |
18 | _p: PhantomData<L>, | |
19 | } | |
20 | ||
21 | impl<L: Language> From<cursor::SyntaxNode> for SyntaxNode<L> { | |
22 | fn from(raw: cursor::SyntaxNode) -> SyntaxNode<L> { | |
23 | SyntaxNode { raw, _p: PhantomData } | |
24 | } | |
25 | } | |
26 | ||
27 | impl<L: Language> From<SyntaxNode<L>> for cursor::SyntaxNode { | |
28 | fn from(node: SyntaxNode<L>) -> cursor::SyntaxNode { | |
29 | node.raw | |
30 | } | |
31 | } | |
32 | ||
33 | impl<L: Language> fmt::Debug for SyntaxNode<L> { | |
34 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
35 | if f.alternate() { | |
36 | let mut level = 0; | |
37 | for event in self.preorder_with_tokens() { | |
38 | match event { | |
39 | WalkEvent::Enter(element) => { | |
40 | for _ in 0..level { | |
41 | write!(f, " ")?; | |
42 | } | |
43 | match element { | |
44 | NodeOrToken::Node(node) => writeln!(f, "{:?}", node)?, | |
45 | NodeOrToken::Token(token) => writeln!(f, "{:?}", token)?, | |
46 | } | |
47 | level += 1; | |
48 | } | |
49 | WalkEvent::Leave(_) => level -= 1, | |
50 | } | |
51 | } | |
52 | assert_eq!(level, 0); | |
53 | Ok(()) | |
54 | } else { | |
55 | write!(f, "{:?}@{:?}", self.kind(), self.text_range()) | |
56 | } | |
57 | } | |
58 | } | |
59 | ||
60 | impl<L: Language> fmt::Display for SyntaxNode<L> { | |
61 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
62 | fmt::Display::fmt(&self.raw, f) | |
63 | } | |
64 | } | |
65 | ||
66 | #[derive(Clone, PartialEq, Eq, Hash)] | |
67 | pub struct SyntaxToken<L: Language> { | |
68 | raw: cursor::SyntaxToken, | |
69 | _p: PhantomData<L>, | |
70 | } | |
71 | ||
72 | impl<L: Language> From<cursor::SyntaxToken> for SyntaxToken<L> { | |
73 | fn from(raw: cursor::SyntaxToken) -> SyntaxToken<L> { | |
74 | SyntaxToken { raw, _p: PhantomData } | |
75 | } | |
76 | } | |
77 | ||
78 | impl<L: Language> From<SyntaxToken<L>> for cursor::SyntaxToken { | |
79 | fn from(token: SyntaxToken<L>) -> cursor::SyntaxToken { | |
80 | token.raw | |
81 | } | |
82 | } | |
83 | ||
84 | impl<L: Language> fmt::Debug for SyntaxToken<L> { | |
85 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
86 | write!(f, "{:?}@{:?}", self.kind(), self.text_range())?; | |
87 | if self.text().len() < 25 { | |
88 | return write!(f, " {:?}", self.text()); | |
89 | } | |
90 | let text = self.text().as_str(); | |
91 | for idx in 21..25 { | |
92 | if text.is_char_boundary(idx) { | |
93 | let text = format!("{} ...", &text[..idx]); | |
94 | return write!(f, " {:?}", text); | |
95 | } | |
96 | } | |
97 | unreachable!() | |
98 | } | |
99 | } | |
100 | ||
101 | impl<L: Language> fmt::Display for SyntaxToken<L> { | |
102 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
103 | fmt::Display::fmt(&self.raw, f) | |
104 | } | |
105 | } | |
106 | ||
107 | pub type SyntaxElement<L> = NodeOrToken<SyntaxNode<L>, SyntaxToken<L>>; | |
108 | ||
109 | impl<L: Language> From<cursor::SyntaxElement> for SyntaxElement<L> { | |
110 | fn from(raw: cursor::SyntaxElement) -> SyntaxElement<L> { | |
111 | match raw { | |
112 | NodeOrToken::Node(it) => NodeOrToken::Node(it.into()), | |
113 | NodeOrToken::Token(it) => NodeOrToken::Token(it.into()), | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | impl<L: Language> From<SyntaxElement<L>> for cursor::SyntaxElement { | |
119 | fn from(element: SyntaxElement<L>) -> cursor::SyntaxElement { | |
120 | match element { | |
121 | NodeOrToken::Node(it) => NodeOrToken::Node(it.into()), | |
122 | NodeOrToken::Token(it) => NodeOrToken::Token(it.into()), | |
123 | } | |
124 | } | |
125 | } | |
126 | ||
127 | impl<L: Language> From<SyntaxNode<L>> for SyntaxElement<L> { | |
128 | fn from(node: SyntaxNode<L>) -> SyntaxElement<L> { | |
129 | NodeOrToken::Node(node) | |
130 | } | |
131 | } | |
132 | ||
133 | impl<L: Language> From<SyntaxToken<L>> for SyntaxElement<L> { | |
134 | fn from(token: SyntaxToken<L>) -> SyntaxElement<L> { | |
135 | NodeOrToken::Token(token) | |
136 | } | |
137 | } | |
138 | ||
139 | impl<L: Language> fmt::Display for SyntaxElement<L> { | |
140 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
141 | match self { | |
142 | NodeOrToken::Node(it) => fmt::Display::fmt(it, f), | |
143 | NodeOrToken::Token(it) => fmt::Display::fmt(it, f), | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | impl<L: Language> SyntaxNode<L> { | |
149 | pub fn new_root(green: GreenNode) -> SyntaxNode<L> { | |
150 | SyntaxNode::from(cursor::SyntaxNode::new_root(green)) | |
151 | } | |
152 | pub fn replace_with(&self, replacement: GreenNode) -> GreenNode { | |
153 | self.raw.replace_with(replacement) | |
154 | } | |
155 | ||
156 | pub fn kind(&self) -> L::Kind { | |
157 | L::kind_from_raw(self.raw.kind()) | |
158 | } | |
159 | ||
160 | pub fn text_range(&self) -> TextRange { | |
161 | self.raw.text_range() | |
162 | } | |
163 | ||
164 | pub fn text(&self) -> SyntaxText { | |
165 | self.raw.text() | |
166 | } | |
167 | ||
168 | pub fn green(&self) -> &GreenNode { | |
169 | self.raw.green() | |
170 | } | |
171 | ||
172 | pub fn parent(&self) -> Option<SyntaxNode<L>> { | |
173 | self.raw.parent().map(Self::from) | |
174 | } | |
175 | ||
176 | pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> { | |
177 | self.raw.ancestors().map(SyntaxNode::from) | |
178 | } | |
179 | ||
180 | pub fn children(&self) -> SyntaxNodeChildren<L> { | |
181 | SyntaxNodeChildren { raw: self.raw.children(), _p: PhantomData } | |
182 | } | |
183 | ||
184 | pub fn children_with_tokens(&self) -> SyntaxElementChildren<L> { | |
185 | SyntaxElementChildren { raw: self.raw.children_with_tokens(), _p: PhantomData } | |
186 | } | |
187 | ||
188 | pub fn first_child(&self) -> Option<SyntaxNode<L>> { | |
189 | self.raw.first_child().map(Self::from) | |
190 | } | |
191 | ||
192 | pub fn first_child_or_token(&self) -> Option<SyntaxElement<L>> { | |
193 | self.raw.first_child_or_token().map(NodeOrToken::from) | |
194 | } | |
195 | ||
196 | pub fn last_child(&self) -> Option<SyntaxNode<L>> { | |
197 | self.raw.last_child().map(Self::from) | |
198 | } | |
199 | ||
200 | pub fn last_child_or_token(&self) -> Option<SyntaxElement<L>> { | |
201 | self.raw.last_child_or_token().map(NodeOrToken::from) | |
202 | } | |
203 | ||
204 | pub fn next_sibling(&self) -> Option<SyntaxNode<L>> { | |
205 | self.raw.next_sibling().map(Self::from) | |
206 | } | |
207 | ||
208 | pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
209 | self.raw.next_sibling_or_token().map(NodeOrToken::from) | |
210 | } | |
211 | ||
212 | pub fn prev_sibling(&self) -> Option<SyntaxNode<L>> { | |
213 | self.raw.prev_sibling().map(Self::from) | |
214 | } | |
215 | ||
216 | pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
217 | self.raw.prev_sibling_or_token().map(NodeOrToken::from) | |
218 | } | |
219 | ||
220 | pub fn first_token(&self) -> Option<SyntaxToken<L>> { | |
221 | self.raw.first_token().map(SyntaxToken::from) | |
222 | } | |
223 | ||
224 | pub fn last_token(&self) -> Option<SyntaxToken<L>> { | |
225 | self.raw.last_token().map(SyntaxToken::from) | |
226 | } | |
227 | ||
228 | pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode<L>> { | |
229 | self.raw.siblings(direction).map(SyntaxNode::from) | |
230 | } | |
231 | ||
232 | pub fn siblings_with_tokens( | |
233 | &self, | |
234 | direction: Direction, | |
235 | ) -> impl Iterator<Item = SyntaxElement<L>> { | |
236 | self.raw.siblings_with_tokens(direction).map(SyntaxElement::from) | |
237 | } | |
238 | ||
239 | pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode<L>> { | |
240 | self.raw.descendants().map(SyntaxNode::from) | |
241 | } | |
242 | ||
243 | pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement<L>> { | |
244 | self.raw.descendants_with_tokens().map(NodeOrToken::from) | |
245 | } | |
246 | ||
247 | pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode<L>>> { | |
248 | self.raw.preorder().map(|event| event.map(SyntaxNode::from)) | |
249 | } | |
250 | ||
251 | pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement<L>>> { | |
252 | self.raw.preorder_with_tokens().map(|event| event.map(NodeOrToken::from)) | |
253 | } | |
254 | ||
255 | pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken<L>> { | |
256 | self.raw.token_at_offset(offset).map(SyntaxToken::from) | |
257 | } | |
258 | ||
259 | pub fn covering_element(&self, range: TextRange) -> SyntaxElement<L> { | |
260 | NodeOrToken::from(self.raw.covering_element(range)) | |
261 | } | |
262 | } | |
263 | ||
264 | impl<L: Language> SyntaxToken<L> { | |
265 | pub fn replace_with(&self, new_token: GreenToken) -> GreenNode { | |
266 | self.raw.replace_with(new_token) | |
267 | } | |
268 | ||
269 | pub fn kind(&self) -> L::Kind { | |
270 | L::kind_from_raw(self.raw.kind()) | |
271 | } | |
272 | ||
273 | pub fn text_range(&self) -> TextRange { | |
274 | self.raw.text_range() | |
275 | } | |
276 | ||
277 | pub fn text(&self) -> &SmolStr { | |
278 | self.raw.text() | |
279 | } | |
280 | ||
281 | pub fn green(&self) -> &GreenToken { | |
282 | self.raw.green() | |
283 | } | |
284 | ||
285 | pub fn parent(&self) -> SyntaxNode<L> { | |
286 | SyntaxNode::from(self.raw.parent()) | |
287 | } | |
288 | ||
289 | pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> { | |
290 | self.raw.ancestors().map(SyntaxNode::from) | |
291 | } | |
292 | ||
293 | pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
294 | self.raw.next_sibling_or_token().map(NodeOrToken::from) | |
295 | } | |
296 | ||
297 | pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
298 | self.raw.prev_sibling_or_token().map(NodeOrToken::from) | |
299 | } | |
300 | ||
301 | pub fn siblings_with_tokens( | |
302 | &self, | |
303 | direction: Direction, | |
304 | ) -> impl Iterator<Item = SyntaxElement<L>> { | |
305 | self.raw.siblings_with_tokens(direction).map(SyntaxElement::from) | |
306 | } | |
307 | ||
308 | pub fn next_token(&self) -> Option<SyntaxToken<L>> { | |
309 | self.raw.next_token().map(SyntaxToken::from) | |
310 | } | |
311 | ||
312 | pub fn prev_token(&self) -> Option<SyntaxToken<L>> { | |
313 | self.raw.prev_token().map(SyntaxToken::from) | |
314 | } | |
315 | } | |
316 | ||
317 | impl<L: Language> SyntaxElement<L> { | |
318 | pub fn text_range(&self) -> TextRange { | |
319 | match self { | |
320 | NodeOrToken::Node(it) => it.text_range(), | |
321 | NodeOrToken::Token(it) => it.text_range(), | |
322 | } | |
323 | } | |
324 | ||
325 | pub fn kind(&self) -> L::Kind { | |
326 | match self { | |
327 | NodeOrToken::Node(it) => it.kind(), | |
328 | NodeOrToken::Token(it) => it.kind(), | |
329 | } | |
330 | } | |
331 | ||
332 | pub fn parent(&self) -> Option<SyntaxNode<L>> { | |
333 | match self { | |
334 | NodeOrToken::Node(it) => it.parent(), | |
335 | NodeOrToken::Token(it) => Some(it.parent()), | |
336 | } | |
337 | } | |
338 | ||
339 | pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> { | |
340 | match self { | |
341 | NodeOrToken::Node(it) => it.ancestors(), | |
342 | NodeOrToken::Token(it) => it.parent().ancestors(), | |
343 | } | |
344 | } | |
345 | ||
346 | pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
347 | match self { | |
348 | NodeOrToken::Node(it) => it.next_sibling_or_token(), | |
349 | NodeOrToken::Token(it) => it.next_sibling_or_token(), | |
350 | } | |
351 | } | |
352 | ||
353 | pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> { | |
354 | match self { | |
355 | NodeOrToken::Node(it) => it.prev_sibling_or_token(), | |
356 | NodeOrToken::Token(it) => it.prev_sibling_or_token(), | |
357 | } | |
358 | } | |
359 | } | |
360 | ||
361 | #[derive(Debug, Clone)] | |
362 | pub struct SyntaxNodeChildren<L: Language> { | |
363 | raw: cursor::SyntaxNodeChildren, | |
364 | _p: PhantomData<L>, | |
365 | } | |
366 | ||
367 | impl<L: Language> Iterator for SyntaxNodeChildren<L> { | |
368 | type Item = SyntaxNode<L>; | |
369 | fn next(&mut self) -> Option<Self::Item> { | |
370 | self.raw.next().map(SyntaxNode::from) | |
371 | } | |
372 | } | |
373 | ||
374 | #[derive(Debug, Clone)] | |
375 | pub struct SyntaxElementChildren<L: Language> { | |
376 | raw: cursor::SyntaxElementChildren, | |
377 | _p: PhantomData<L>, | |
378 | } | |
379 | ||
380 | impl<L: Language> Iterator for SyntaxElementChildren<L> { | |
381 | type Item = SyntaxElement<L>; | |
382 | fn next(&mut self) -> Option<Self::Item> { | |
383 | self.raw.next().map(NodeOrToken::from) | |
384 | } | |
385 | } |