rslint_rowan/green/
node.rs1use std::{iter::FusedIterator, slice, sync::Arc};
2
3use erasable::Thin;
4use slice_dst::SliceWithHeader;
5
6use crate::{
7 green::{GreenElement, GreenElementRef, PackedGreenElement, SyntaxKind},
8 TextSize,
9};
10
11#[repr(align(2))] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub(super) struct GreenNodeHead {
14 kind: SyntaxKind,
15 text_len: TextSize,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21#[repr(transparent)]
22pub struct GreenNode {
23 pub(super) data: Thin<Arc<SliceWithHeader<GreenNodeHead, PackedGreenElement>>>,
24}
25
26impl GreenNode {
27 #[inline]
29 pub fn new<I>(kind: SyntaxKind, children: I) -> GreenNode
30 where
31 I: IntoIterator<Item = GreenElement>,
32 I::IntoIter: ExactSizeIterator,
33 {
34 let mut text_len: TextSize = 0.into();
35 let children = children
36 .into_iter()
37 .inspect(|it| text_len += it.text_len())
38 .map(PackedGreenElement::from);
39 let mut data: Arc<_> =
40 SliceWithHeader::new(GreenNodeHead { kind, text_len: 0.into() }, children);
41
42 Arc::get_mut(&mut data).unwrap().header.text_len = text_len;
45
46 GreenNode { data: data.into() }
47 }
48
49 #[inline]
51 pub fn kind(&self) -> SyntaxKind {
52 self.data.header.kind
53 }
54
55 #[inline]
57 pub fn text_len(&self) -> TextSize {
58 self.data.header.text_len
59 }
60
61 #[inline]
63 pub fn children(&self) -> Children<'_> {
64 Children { inner: self.data.slice.iter() }
65 }
66
67 pub(crate) fn ptr(&self) -> *const u8 {
68 let r: &SliceWithHeader<_, _> = &*self.data;
69 r as *const _ as _
70 }
71}
72
73#[derive(Debug, Clone)]
74pub struct Children<'a> {
75 inner: slice::Iter<'a, PackedGreenElement>,
76}
77
78impl ExactSizeIterator for Children<'_> {
80 #[inline(always)]
81 fn len(&self) -> usize {
82 self.inner.len()
83 }
84}
85
86impl<'a> Iterator for Children<'a> {
87 type Item = GreenElementRef<'a>;
88
89 #[inline]
90 fn next(&mut self) -> Option<GreenElementRef<'a>> {
91 self.inner.next().map(PackedGreenElement::as_ref)
92 }
93
94 #[inline]
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 self.inner.size_hint()
97 }
98
99 #[inline]
100 fn count(self) -> usize
101 where
102 Self: Sized,
103 {
104 self.inner.count()
105 }
106
107 #[inline]
108 fn nth(&mut self, n: usize) -> Option<Self::Item> {
109 self.inner.nth(n).map(PackedGreenElement::as_ref)
110 }
111
112 #[inline]
113 fn last(mut self) -> Option<Self::Item>
114 where
115 Self: Sized,
116 {
117 self.next_back()
118 }
119
120 #[inline]
121 fn fold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
122 where
123 Fold: FnMut(Acc, Self::Item) -> Acc,
124 {
125 let mut accum = init;
126 while let Some(x) = self.next() {
127 accum = f(accum, x);
128 }
129 accum
130 }
131}
132
133impl<'a> DoubleEndedIterator for Children<'a> {
134 #[inline]
135 fn next_back(&mut self) -> Option<Self::Item> {
136 self.inner.next_back().map(PackedGreenElement::as_ref)
137 }
138
139 #[inline]
140 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
141 self.inner.nth_back(n).map(PackedGreenElement::as_ref)
142 }
143
144 #[inline]
145 fn rfold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
146 where
147 Fold: FnMut(Acc, Self::Item) -> Acc,
148 {
149 let mut accum = init;
150 while let Some(x) = self.next_back() {
151 accum = f(accum, x);
152 }
153 accum
154 }
155}
156
157impl FusedIterator for Children<'_> {}