1use std::{
36 fmt::{Debug, Formatter},
37 iter::FusedIterator,
38 marker::PhantomData,
39 ops::Range,
40};
41
42use crate::{
43 arena::{Entry, EntryIndex, Id, Identifiable, SubId},
44 lexis::TokenCursor,
45 report::system_panic,
46 syntax::{
47 observer::ObservableSyntaxSession,
48 session::ImmutableSyntaxSession,
49 ErrorRef,
50 Node,
51 NodeRef,
52 Observer,
53 SyntaxError,
54 SyntaxSession,
55 SyntaxTree,
56 ROOT_RULE,
57 },
58};
59
60pub struct ImmutableSyntaxTree<N: Node> {
68 id: SubId,
69 nodes: Vec<Option<N>>,
70 errors: Vec<SyntaxError>,
71}
72
73impl<N: Node> PartialEq for ImmutableSyntaxTree<N> {
74 #[inline(always)]
75 fn eq(&self, other: &Self) -> bool {
76 self.id.eq(&other.id)
77 }
78}
79
80impl<N: Node> Eq for ImmutableSyntaxTree<N> {}
81
82impl<N: Node> Debug for ImmutableSyntaxTree<N> {
83 #[inline]
84 fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
85 formatter
86 .debug_struct("SyntaxTree")
87 .field("id", &self.id())
88 .finish_non_exhaustive()
89 }
90}
91
92impl<N: Node> Identifiable for ImmutableSyntaxTree<N> {
93 #[inline(always)]
94 fn id(&self) -> Id {
95 self.id.id()
96 }
97}
98
99impl<N: Node> SyntaxTree for ImmutableSyntaxTree<N> {
100 type Node = N;
101
102 type NodeIterator<'tree> = NodeIter;
103
104 type ErrorIterator<'tree> = ErrorIter;
105
106 #[inline(always)]
107 fn root_node_ref(&self) -> NodeRef {
108 #[cfg(debug_assertions)]
109 if self.nodes.is_empty() {
110 system_panic!("Empty syntax tree.");
111 }
112
113 NodeRef {
114 id: self.id.id(),
115 entry: Entry {
116 index: 0,
117 version: 0,
118 },
119 }
120 }
121
122 #[inline(always)]
123 fn node_refs(&self) -> Self::NodeIterator<'_> {
124 NodeIter {
125 id: self.id.id(),
126 inner: 0..self.nodes.len(),
127 }
128 }
129
130 #[inline(always)]
131 fn error_refs(&self) -> Self::ErrorIterator<'_> {
132 ErrorIter {
133 id: self.id.id(),
134 inner: 0..self.errors.len(),
135 }
136 }
137
138 #[inline(always)]
139 fn has_node(&self, entry: &Entry) -> bool {
140 if entry.version > 0 {
141 return false;
142 }
143
144 entry.index < self.nodes.len()
145 }
146
147 #[inline(always)]
148 fn get_node(&self, entry: &Entry) -> Option<&Self::Node> {
149 if entry.version > 0 {
150 return None;
151 }
152
153 self.nodes.get(entry.index)?.as_ref()
154 }
155
156 #[inline(always)]
157 fn get_node_mut(&mut self, entry: &Entry) -> Option<&mut Self::Node> {
158 if entry.version > 0 {
159 return None;
160 }
161
162 self.nodes.get_mut(entry.index)?.as_mut()
163 }
164
165 #[inline(always)]
166 fn has_error(&self, entry: &Entry) -> bool {
167 if entry.version > 0 {
168 return false;
169 }
170
171 entry.index < self.errors.len()
172 }
173
174 #[inline(always)]
175 fn get_error(&self, entry: &Entry) -> Option<&SyntaxError> {
176 if entry.version > 0 {
177 return None;
178 }
179
180 self.errors.get(entry.index)
181 }
182}
183
184impl<N: Node> ImmutableSyntaxTree<N> {
185 #[inline(always)]
197 pub fn parse<'code>(token_cursor: impl TokenCursor<'code, Token = <N as Node>::Token>) -> Self {
198 Self::parse_with_id(SubId::new(), token_cursor)
199 }
200
201 #[inline(always)]
209 pub fn parse_with_observer<'code>(
210 token_cursor: impl TokenCursor<'code, Token = <N as Node>::Token>,
211 observer: &mut impl Observer<Node = N>,
212 ) -> Self {
213 Self::parse_with_id_and_observer(SubId::new(), token_cursor, observer)
214 }
215
216 pub(crate) fn parse_with_id<'code, 'observer>(
217 id: SubId,
218 token_cursor: impl TokenCursor<'code, Token = <N as Node>::Token>,
219 ) -> Self {
220 let mut session = ImmutableSyntaxSession {
221 id: id.id(),
222 context: Vec::new(),
223 nodes: Vec::new(),
224 errors: Vec::new(),
225 failing: false,
226 token_cursor,
227 _phantom: PhantomData,
228 };
229
230 let _ = session.descend(ROOT_RULE);
231
232 Self {
233 id,
234 nodes: session.nodes,
235 errors: session.errors,
236 }
237 }
238
239 pub(crate) fn parse_with_id_and_observer<'code, 'observer>(
240 id: SubId,
241 token_cursor: impl TokenCursor<'code, Token = <N as Node>::Token>,
242 observer: &'observer mut impl Observer<Node = N>,
243 ) -> Self {
244 let mut session = ObservableSyntaxSession {
245 id: id.id(),
246 context: Vec::new(),
247 nodes: Vec::new(),
248 errors: Vec::new(),
249 failing: false,
250 token_cursor,
251 observer,
252 _phantom: PhantomData,
253 };
254
255 let _ = session.descend(ROOT_RULE);
256
257 Self {
258 id,
259 nodes: session.nodes,
260 errors: session.errors,
261 }
262 }
263}
264
265pub struct NodeIter {
266 id: Id,
267 inner: Range<EntryIndex>,
268}
269
270impl Iterator for NodeIter {
271 type Item = NodeRef;
272
273 #[inline(always)]
274 fn next(&mut self) -> Option<Self::Item> {
275 let index = self.inner.next()?;
276
277 Some(NodeRef {
278 id: self.id,
279 entry: Entry { index, version: 0 },
280 })
281 }
282}
283
284impl FusedIterator for NodeIter {}
285
286pub struct ErrorIter {
287 id: Id,
288 inner: Range<EntryIndex>,
289}
290
291impl Iterator for ErrorIter {
292 type Item = ErrorRef;
293
294 #[inline(always)]
295 fn next(&mut self) -> Option<Self::Item> {
296 let index = self.inner.next()?;
297
298 Some(ErrorRef {
299 id: self.id,
300 entry: Entry { index, version: 0 },
301 })
302 }
303}
304
305impl FusedIterator for ErrorIter {}