Skip to main content

typst_syntax/
node.rs

1use std::cell::LazyCell;
2use std::fmt::{self, Debug, Display, Formatter};
3use std::ops::{Deref, Range};
4use std::rc::Rc;
5use std::sync::Arc;
6
7use ecow::{EcoString, EcoVec, eco_format, eco_vec};
8use typst_utils::debug;
9
10use crate::kind::ModeAfter;
11use crate::{
12    DiagSpan, FileId, RangeMapper, Span, SpanKind, SpanNumber, Spanned, SubRange,
13    SyntaxKind, SyntaxMode,
14};
15
16/// A node in the untyped syntax tree.
17#[derive(Clone, Eq, PartialEq, Hash)]
18pub struct SyntaxNode {
19    /// The underlying node data, potentially with wrapped warning messages.
20    data: Node,
21    /// The node's span, at the top-level to guarantee efficient access.
22    span: Span,
23    // We would love to move the `SyntaxKind` up here as well, but keeping it in
24    // `Node` saves 8 bytes :/
25}
26
27/// The data for nodes in the tree, plus their [`SyntaxKind`]. May actually be a
28/// warning message wrapping a child [`Node`].
29///
30/// Contains the [`SyntaxKind`] at the top-level for efficient access. This
31/// requires being careful when mutating the kind, as warnings store this type
32/// as their child, which duplicates the kind. Deduplicating the syntax kinds
33/// would require a whole other enum type, and makes mutable access too painful.
34///
35/// The only other invariant for syntax kinds is that error nodes always contain
36/// [`SyntaxKind::Error`], but leaf and inner nodes never do. The syntax kind of
37/// a warning depends on what it wraps.
38///
39/// The simplest way to get the underlying data by descending into the children
40/// of warnings is via a loop and match like below. The [`SyntaxNode::node_ref`]
41/// helper does this for the by-reference case, but mutation is usually more
42/// involved, so only gets the [`SyntaxNode::inner_and_span_mut`] helper.
43/// ```ignore
44/// let mut data = &mut node.data;
45/// let value = loop {
46///     match data {
47///         Leaf(_, _) | Inner(_, _) | Error(_, _) => break "value",
48///         Warning(warn, _) => data = &mut Arc::make_mut(warn).child,
49///     }
50/// };
51/// ```
52#[derive(Clone, Eq, PartialEq, Hash)]
53enum Node {
54    Leaf(EcoString, SyntaxKind),
55    Inner(Arc<InnerNode>, SyntaxKind),
56    Error(Arc<ErrorNode>, SyntaxKind),
57    Warning(Arc<WarningWrapper>, SyntaxKind),
58}
59
60/// Data attached to a node, accessed by reference via [`SyntaxNode::node_ref`].
61enum NodeRef<'a> {
62    Leaf(&'a EcoString),
63    Inner(&'a Arc<InnerNode>),
64    Error(&'a Arc<ErrorNode>),
65}
66
67impl SyntaxNode {
68    /// Access the underlying node data by reference, descending past warnings.
69    fn node_ref(&self) -> NodeRef<'_> {
70        let mut data = &self.data;
71        loop {
72            match data {
73                Node::Leaf(text, _) => break NodeRef::Leaf(text),
74                Node::Inner(inner, _) => break NodeRef::Inner(inner),
75                Node::Error(err, _) => break NodeRef::Error(err),
76                Node::Warning(warn, _) => data = &warn.child,
77            }
78        }
79    }
80
81    /// Access an inner node and the node's overall span mutably, descending
82    /// past warnings. If this only returned the `&mut InnerNode`, the caller
83    /// wouldn't be able to also get a mutable reference to the span since the
84    /// inner node would borrow mutably from `self`.
85    fn inner_and_span_mut(&mut self) -> Option<(&mut InnerNode, &mut Span)> {
86        let mut data = &mut self.data;
87        loop {
88            match data {
89                Node::Leaf(_, _) | Node::Error(_, _) => break None,
90                Node::Inner(inner, _) => {
91                    break Some((Arc::make_mut(inner), &mut self.span));
92                }
93                Node::Warning(warn, _) => data = &mut Arc::make_mut(warn).child,
94            }
95        }
96    }
97
98    /// Access the hints for an error or warning mutably.
99    fn hints_mut(&mut self) -> Option<&mut EcoVec<(EcoString, Option<SubRange>)>> {
100        match &mut self.data {
101            Node::Leaf(_, _) | Node::Inner(_, _) => None,
102            Node::Error(err, _) => Some(&mut Arc::make_mut(err).hints),
103            Node::Warning(warn, _) => Some(&mut Arc::make_mut(warn).hints),
104        }
105    }
106}
107
108impl SyntaxNode {
109    /// Create a new leaf node.
110    #[track_caller]
111    pub fn leaf(kind: SyntaxKind, text: impl Into<EcoString>) -> Self {
112        debug_assert!(!kind.is_error());
113        Self {
114            data: Node::Leaf(text.into(), kind),
115            span: Span::detached(),
116        }
117    }
118
119    /// Create a new inner node with children.
120    #[track_caller]
121    pub fn inner(kind: SyntaxKind, children: Vec<SyntaxNode>) -> Self {
122        debug_assert!(!kind.is_error());
123        Self {
124            data: Node::Inner(Arc::new(InnerNode::new(children)), kind),
125            span: Span::detached(),
126        }
127    }
128
129    /// Create a new error node with a user-presentable message for the given
130    /// text. Note that the message is the first argument, and the text causing
131    /// the error is the second argument.
132    pub fn error(message: impl Into<EcoString>, text: impl Into<EcoString>) -> Self {
133        Self {
134            data: Node::Error(
135                Arc::new(ErrorNode::new(message.into(), text.into())),
136                SyntaxKind::Error,
137            ),
138            span: Span::detached(),
139        }
140    }
141
142    /// Add a warning message to an existing node.
143    pub fn warn(&mut self, message: impl Into<EcoString>) {
144        let kind = self.kind();
145        let child = std::mem::replace(&mut self.data, Node::Leaf(EcoString::new(), kind));
146        let warn = Arc::new(WarningWrapper::new(child, None, message.into()));
147        self.data = Node::Warning(warn, kind);
148    }
149
150    /// Add a warning around this node at a particular sub-range of the node's
151    /// text. Panics if the range is empty or exceeds the length of the wrapped
152    /// text.
153    #[track_caller]
154    pub fn warn_at(
155        &mut self,
156        Range { start, end }: Range<usize>,
157        message: impl Into<EcoString>,
158    ) {
159        assert!(end <= self.len()); // This isn't checked by `SubRange::new`.
160        let sub_range = SubRange::new(start, end).expect("a valid sub-range");
161        let kind = self.kind();
162        let child = std::mem::replace(&mut self.data, Node::Leaf(EcoString::new(), kind));
163        let warn = Arc::new(WarningWrapper::new(child, Some(sub_range), message.into()));
164        self.data = Node::Warning(warn, kind);
165    }
166
167    /// Add a user-presentable hint to an existing error or warning. Panics if
168    /// this is not an error or warning.
169    #[track_caller]
170    pub fn hint(&mut self, hint: impl Into<EcoString>) {
171        let hints = self.hints_mut().expect("expected an error or warning");
172        hints.push((hint.into(), None));
173    }
174
175    /// Add a user-presentable hint to an existing error or warning at a
176    /// sub-range of the text. Panics if the range is empty or exceeds the
177    /// length of the wrapped text. Panics if this is not an error or warning
178    /// node.
179    #[track_caller]
180    pub fn hint_at(
181        &mut self,
182        Range { start, end }: Range<usize>,
183        hint: impl Into<EcoString>,
184    ) {
185        assert!(end <= self.len()); // This isn't checked by `SubRange::new`.
186        let sub_range = SubRange::new(start, end).expect("a valid sub-range");
187        let hints = self.hints_mut().expect("expected an error or warning");
188        hints.push((hint.into(), Some(sub_range)));
189    }
190
191    /// Add multiple hints while building an error or warning. Panics if this is
192    /// not an error or warning.
193    #[track_caller]
194    pub fn with_hints(mut self, new_hints: impl IntoIterator<Item = EcoString>) -> Self {
195        let hints = self.hints_mut().expect("expected an error or warning");
196        let iter = new_hints.into_iter().map(|h| (h, None));
197        hints.extend(iter);
198        self
199    }
200
201    /// Create a dummy node of the given kind.
202    ///
203    /// Panics if `kind` is [`SyntaxKind::Error`].
204    #[track_caller]
205    pub const fn placeholder(kind: SyntaxKind) -> Self {
206        if kind.is_error() {
207            panic!("cannot create error placeholder");
208        }
209        Self {
210            data: Node::Leaf(EcoString::new(), kind),
211            span: Span::detached(),
212        }
213    }
214
215    /// The type of the node.
216    pub fn kind(&self) -> SyntaxKind {
217        match self.data {
218            Node::Leaf(_, kind)
219            | Node::Inner(_, kind)
220            | Node::Error(_, kind)
221            | Node::Warning(_, kind) => kind,
222        }
223    }
224
225    /// Return `true` if the length is 0.
226    pub fn is_empty(&self) -> bool {
227        self.len() == 0
228    }
229
230    /// The byte length of the node in the source text.
231    pub fn len(&self) -> usize {
232        match self.node_ref() {
233            NodeRef::Leaf(text) => text.len(),
234            NodeRef::Inner(inner) => inner.len,
235            NodeRef::Error(err) => err.text.len(),
236        }
237    }
238
239    /// The span of the node.
240    pub fn span(&self) -> Span {
241        self.span
242    }
243
244    /// The text of the node if it is a leaf or error node.
245    ///
246    /// Returns the empty string if this is an inner node.
247    pub fn leaf_text(&self) -> &EcoString {
248        static EMPTY: EcoString = EcoString::new();
249        match self.node_ref() {
250            NodeRef::Leaf(text) => text,
251            NodeRef::Inner(_) => &EMPTY,
252            NodeRef::Error(err) => &err.text,
253        }
254    }
255
256    /// Clone the full text from the node. If this is an inner node, it will
257    /// traverse the tree to build the text which may be expensive.
258    pub fn full_text(&self) -> EcoString {
259        match &self.data {
260            Node::Leaf(leaf, _) => leaf.clone(),
261            Node::Error(err, _) => err.text.clone(),
262            Node::Inner(_, _) | Node::Warning(_, _) => {
263                let mut buffer = EcoString::with_capacity(self.len());
264                self.traverse(|node| {
265                    match node.node_ref() {
266                        NodeRef::Leaf(text) => buffer.push_str(text),
267                        NodeRef::Inner(_) => {}
268                        NodeRef::Error(err) => buffer.push_str(&err.text),
269                    }
270                    node.children()
271                });
272                buffer
273            }
274        }
275    }
276
277    /// The node's children.
278    pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> {
279        match self.node_ref() {
280            NodeRef::Leaf(_) | NodeRef::Error(_) => [].iter(),
281            NodeRef::Inner(inner) => inner.children.iter(),
282        }
283    }
284
285    /// Whether the node has diagnostic errors and/or warnings in it or its
286    /// children. [`Diagnosis`] has public fields, so you can write
287    /// `node.diagnosis().errors` to determine if a node is erroneous.
288    ///
289    /// This can be used to determine whether [`Self::errors_and_warnings`] will
290    /// return an empty vector without traversing the tree if it will not.
291    pub fn diagnosis(&self) -> Diagnosis {
292        let diagnosis = match self.node_ref() {
293            NodeRef::Leaf(_) => Diagnosis::default(),
294            NodeRef::Inner(inner) => inner.diagnosis,
295            NodeRef::Error(_) => Diagnosis { errors: true, warnings: false },
296        };
297        match &self.data {
298            Node::Warning(_, _) => Diagnosis { warnings: true, errors: diagnosis.errors },
299            _ => diagnosis,
300        }
301    }
302
303    /// The error and warning diagnostics for this node and its descendants.
304    pub fn errors_and_warnings(&self) -> (Vec<SyntaxDiagnostic>, Vec<SyntaxDiagnostic>) {
305        let mut errors = Vec::new();
306        let mut warnings = Vec::new();
307        self.traverse(|node| {
308            let mut data = &node.data;
309            loop {
310                match data {
311                    Node::Inner(inner, _) if inner.diagnosis.either() => {
312                        break inner.children.iter();
313                    }
314                    Node::Leaf(_, _) | Node::Inner(_, _) => break [].iter(),
315                    Node::Error(err, _) => {
316                        errors.push(err.diagnostic(node.span));
317                        break [].iter();
318                    }
319                    Node::Warning(warn, _) => {
320                        warnings.push(warn.diagnostic(node.span));
321                        data = &warn.child;
322                    }
323                }
324            }
325        });
326        (errors, warnings)
327    }
328
329    /// Set a synthetic span for the node and all its descendants.
330    pub fn synthesize(&mut self, span: Span) {
331        // Sub-ranges are removed since the overall range is not accurate.
332        self.synthesize_with(0, &|_, _| span, &|_, sub_range| *sub_range = None);
333    }
334
335    /// Set a raw range span for each node.
336    ///
337    /// The range is determined by mapping the node's ranges through the given
338    /// `mapper`.
339    ///
340    /// Returns an error with the mapper's length if it was shorter than the
341    /// length of the source text.
342    pub fn synthesize_mapped(
343        &mut self,
344        id: FileId,
345        mapper: &RangeMapper,
346    ) -> Result<(), EcoString> {
347        if self.len() > mapper.total_len() {
348            // TODO: Should we error if not exactly equal?
349            return Err(eco_format!(
350                "text length ({}) is greater than mapper length ({})",
351                self.len(),
352                mapper.total_len(),
353            ));
354        }
355        self.synthesize_with(
356            0,
357            &|offset, len| Span::from_range(id, mapper.map(offset..offset + len)),
358            &|offset, sub_range| {
359                if let Some(sr) = sub_range {
360                    *sr = mapper.map_sub_range(offset, *sr);
361                }
362            },
363        );
364        Ok(())
365    }
366
367    /// Set a custom span for each node given its offset and length, and update
368    /// any sub-ranges based on their offset.
369    ///
370    /// Should be called with `offset = 0` on the root node.
371    fn synthesize_with(
372        &mut self,
373        mut offset: usize,
374        map_span: &impl Fn(usize, usize) -> Span,
375        update_sub_range: &impl Fn(usize, &mut Option<SubRange>),
376    ) {
377        let mut data = &mut self.data;
378        loop {
379            match data {
380                Node::Leaf(leaf, _) => {
381                    self.span = map_span(offset, leaf.len());
382                    break;
383                }
384                Node::Inner(inner, _) => {
385                    let inner = Arc::make_mut(inner);
386                    self.span = map_span(offset, inner.len);
387                    inner.upper = self.span.number();
388                    for child in &mut inner.children {
389                        child.synthesize_with(offset, map_span, update_sub_range);
390                        offset += child.len();
391                    }
392                    break;
393                }
394                Node::Error(err, _) => {
395                    let err = Arc::make_mut(err);
396                    for (_hint, sub_range) in err.hints.make_mut() {
397                        update_sub_range(offset, sub_range);
398                    }
399                    self.span = map_span(offset, err.text.len());
400                    break;
401                }
402                Node::Warning(warn, _) => {
403                    let warn = Arc::make_mut(warn);
404                    update_sub_range(offset, &mut warn.sub_range);
405                    for (_hint, sub_range) in warn.hints.make_mut() {
406                        update_sub_range(offset, sub_range);
407                    }
408                    data = &mut warn.child;
409                }
410            }
411        }
412    }
413
414    /// Whether the two syntax nodes are the same apart from spans.
415    pub fn spanless_eq(&self, other: &Self) -> bool {
416        self.kind() == other.kind() && {
417            let mut data_a = &self.data;
418            let mut data_b = &other.data;
419            loop {
420                match (data_a, data_b) {
421                    (Node::Leaf(a, _), Node::Leaf(b, _)) => break a == b,
422                    (Node::Inner(a, _), Node::Inner(b, _)) => {
423                        break a.spanless_eq(b);
424                    }
425                    (Node::Error(a, _), Node::Error(b, _)) => break a == b,
426                    (Node::Warning(a, _), Node::Warning(b, _))
427                        if a.message == b.message && a.hints == b.hints =>
428                    {
429                        data_a = &a.child;
430                        data_b = &b.child;
431                    }
432                    _ => break false,
433                }
434            }
435        }
436    }
437}
438
439impl SyntaxNode {
440    /// Convert the child to another kind.
441    ///
442    /// Panics if trying to convert to or from an error.
443    #[track_caller]
444    pub(super) fn convert_to_kind(&mut self, new_kind: SyntaxKind) {
445        if new_kind.is_error() {
446            panic!("cannot convert to an error, use `convert_to_error` instead");
447        } else if self.kind().is_error() {
448            // `.kind()` checks both errors and warnings that wrap errors.
449            panic!("cannot convert an error to a different kind");
450        }
451        // Must assign through warnings as well, since they duplicate the kind.
452        let mut data = &mut self.data;
453        loop {
454            match data {
455                Node::Leaf(_, kind) | Node::Inner(_, kind) => {
456                    *kind = new_kind;
457                    break;
458                }
459                Node::Error(_, _) => unreachable!(),
460                Node::Warning(warn, kind) => {
461                    *kind = new_kind;
462                    data = &mut Arc::make_mut(warn).child;
463                }
464            }
465        }
466    }
467
468    /// Convert the child to an error, if it isn't already one.
469    pub(super) fn convert_to_error(&mut self, message: impl Into<EcoString>) {
470        if !self.kind().is_error() {
471            let text = std::mem::take(self).full_text();
472            *self = SyntaxNode::error(message.into(), text);
473        }
474    }
475
476    /// Convert the child to an error stating that the given thing was
477    /// expected, but the current kind was found.
478    pub(super) fn expected(&mut self, expected: &str) {
479        let kind = self.kind();
480        self.convert_to_error(eco_format!("expected {expected}, found {}", kind.name()));
481        if kind.is_keyword() && matches!(expected, "identifier" | "pattern") {
482            self.hint(eco_format!(
483                "keyword `{text}` is not allowed as an identifier; try `{text}_` instead",
484                text = self.leaf_text(),
485            ));
486        }
487    }
488
489    /// Convert the child to an error stating it was unexpected.
490    pub(super) fn unexpected(&mut self) {
491        self.convert_to_error(eco_format!("unexpected {}", self.kind().name()));
492    }
493
494    /// Assign spans to each node.
495    pub(super) fn numberize(
496        &mut self,
497        id: FileId,
498        within: Range<u64>,
499    ) -> NumberingResult {
500        if within.start >= within.end {
501            Err(Unnumberable)
502        } else if let Some((inner, span)) = self.inner_and_span_mut() {
503            inner.numberize(span, id, None, within)
504        } else {
505            self.span =
506                Span::from_number(id, SpanNumber((within.start + within.end) / 2));
507            Ok(())
508        }
509    }
510
511    /// Traverse the tree in-order, calling `f` on each node and recursing on
512    /// the returned nodes. Note that `f` can prune the traversal at any point
513    /// by yielding `[].iter()` instead of the actual children slice of an inner
514    /// node.
515    fn traverse(&self, mut f: impl FnMut(&Self) -> std::slice::Iter<'_, Self>) {
516        fn recursive_step(
517            node: &SyntaxNode,
518            f: &mut impl FnMut(&SyntaxNode) -> std::slice::Iter<'_, SyntaxNode>,
519        ) {
520            for child in f(node) {
521                recursive_step(child, f);
522            }
523        }
524        // We pass in `&mut impl FnMut` so our caller doesn't have to.
525        recursive_step(self, &mut f);
526    }
527
528    /// Whether this is a leaf node.
529    pub(super) fn is_leaf(&self) -> bool {
530        matches!(self.node_ref(), NodeRef::Leaf(_))
531        // TODO: Should we also treat non-empty errors as leaves?
532    }
533
534    /// Whether this is an inner node.
535    pub(super) fn is_inner(&self) -> bool {
536        matches!(self.node_ref(), NodeRef::Inner(_))
537    }
538
539    /// The number of descendants, including the node itself.
540    pub(super) fn descendants(&self) -> usize {
541        match self.node_ref() {
542            NodeRef::Leaf(_) | NodeRef::Error(_) => 1,
543            NodeRef::Inner(inner) => inner.descendants,
544        }
545    }
546
547    /// The node's children, mutably.
548    pub(super) fn children_mut(&mut self) -> &mut [SyntaxNode] {
549        if let Some((inner, _)) = self.inner_and_span_mut() {
550            &mut inner.children
551        } else {
552            &mut []
553        }
554    }
555
556    /// Replaces a range of children with a replacement.
557    ///
558    /// May have mutated the children if it returns `Err(_)`.
559    pub(super) fn replace_children(
560        &mut self,
561        range: Range<usize>,
562        replacement: Vec<SyntaxNode>,
563    ) -> NumberingResult {
564        if let Some((inner, span)) = self.inner_and_span_mut() {
565            inner.replace_children(span, range, replacement)
566        } else {
567            Ok(())
568        }
569    }
570
571    /// Update this node after changes were made to one of its children.
572    pub(super) fn update_parent(
573        &mut self,
574        prev_len: usize,
575        new_len: usize,
576        prev_descendants: usize,
577        new_descendants: usize,
578    ) {
579        if let Some((inner, _)) = self.inner_and_span_mut() {
580            inner.update_parent(prev_len, new_len, prev_descendants, new_descendants)
581        }
582    }
583
584    /// The upper bound of assigned numbers in this subtree.
585    pub(super) fn upper(&self) -> u64 {
586        match self.node_ref() {
587            NodeRef::Leaf(_) | NodeRef::Error(_) => self.span.number() + 1,
588            NodeRef::Inner(inner) => inner.upper,
589        }
590    }
591}
592
593impl Debug for SyntaxNode {
594    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
595        self.data.fmt(f)
596    }
597}
598
599impl Debug for Node {
600    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
601        match self {
602            Node::Leaf(text, kind) => write!(f, "{kind:?}: {text:?}"),
603            Node::Inner(inner, kind) => inner.debug_fmt(f, *kind),
604            Node::Error(err, _) => err.fmt(f),
605            Node::Warning(warn, _) => warn.fmt(f),
606        }
607    }
608}
609
610impl Default for SyntaxNode {
611    fn default() -> Self {
612        Self::leaf(SyntaxKind::End, EcoString::new())
613    }
614}
615
616/// An inner node in the untyped syntax tree.
617#[derive(Clone, Eq, PartialEq, Hash)]
618struct InnerNode {
619    /// The byte length of the node in the source.
620    len: usize,
621    /// The number of nodes in the whole subtree, including this node.
622    descendants: usize,
623    /// Whether this node or any of its children contain an error/warning
624    /// diagnostic.
625    diagnosis: Diagnosis,
626    /// The upper bound of this node's numbering range.
627    upper: u64,
628    /// This node's children, losslessly make up this node.
629    children: Vec<SyntaxNode>,
630}
631
632impl InnerNode {
633    /// Create a new inner node with the given children.
634    fn new(children: Vec<SyntaxNode>) -> Self {
635        let mut len = 0;
636        let mut descendants = 1;
637        let mut diagnosis = Diagnosis::default();
638
639        for child in &children {
640            len += child.len();
641            descendants += child.descendants();
642            diagnosis = diagnosis.or(child.diagnosis());
643        }
644
645        Self { len, descendants, diagnosis, upper: 0, children }
646    }
647
648    /// Assign span numbers `within` an interval to this node's subtree or just
649    /// a `range` of its children.
650    fn numberize(
651        &mut self,
652        span: &mut Span,
653        id: FileId,
654        range: Option<Range<usize>>,
655        within: Range<u64>,
656    ) -> NumberingResult {
657        // Determine how many nodes we will number.
658        let descendants = match &range {
659            Some(range) if range.is_empty() => return Ok(()),
660            Some(range) => self.children[range.clone()]
661                .iter()
662                .map(SyntaxNode::descendants)
663                .sum::<usize>(),
664            None => self.descendants,
665        };
666
667        // Determine the distance between two neighbouring assigned numbers. If
668        // possible, we try to fit all numbers into the left half of `within`
669        // so that there is space for future insertions.
670        let space = within.end - within.start;
671        let mut stride = space / (2 * descendants as u64);
672        if stride == 0 {
673            stride = space / self.descendants as u64;
674            if stride == 0 {
675                return Err(Unnumberable);
676            }
677        }
678
679        // Number the node itself.
680        let mut start = within.start;
681        if range.is_none() {
682            let end = start + stride;
683            *span = Span::from_number(id, SpanNumber((start + end) / 2));
684            self.upper = within.end;
685            start = end;
686        }
687
688        // Number the children.
689        let len = self.children.len();
690        for child in &mut self.children[range.unwrap_or(0..len)] {
691            let end = start + child.descendants() as u64 * stride;
692            child.numberize(id, start..end)?;
693            start = end;
694        }
695
696        Ok(())
697    }
698
699    /// Whether the two inner nodes are the same apart from spans.
700    fn spanless_eq(&self, other: &Self) -> bool {
701        self.len == other.len
702            && self.descendants == other.descendants
703            && self.diagnosis == other.diagnosis
704            && self.children.len() == other.children.len()
705            && self
706                .children
707                .iter()
708                .zip(&other.children)
709                .all(|(a, b)| a.spanless_eq(b))
710    }
711
712    /// Replaces a range of children with a replacement.
713    ///
714    /// May have mutated the children if it returns `Err(_)`.
715    fn replace_children(
716        &mut self,
717        span: &mut Span,
718        mut range: Range<usize>,
719        replacement: Vec<SyntaxNode>,
720    ) -> NumberingResult {
721        let Some(id) = span.id() else { return Err(Unnumberable) };
722        let mut replacement_range = 0..replacement.len();
723
724        // Trim off common prefix.
725        while range.start < range.end
726            && replacement_range.start < replacement_range.end
727            && self.children[range.start]
728                .spanless_eq(&replacement[replacement_range.start])
729        {
730            range.start += 1;
731            replacement_range.start += 1;
732        }
733
734        // Trim off common suffix.
735        while range.start < range.end
736            && replacement_range.start < replacement_range.end
737            && self.children[range.end - 1]
738                .spanless_eq(&replacement[replacement_range.end - 1])
739        {
740            range.end -= 1;
741            replacement_range.end -= 1;
742        }
743
744        let mut replacement_vec = replacement;
745        let replacement = &replacement_vec[replacement_range.clone()];
746        let superseded = &self.children[range.clone()];
747
748        // Compute the new byte length.
749        self.len = self.len + replacement.iter().map(SyntaxNode::len).sum::<usize>()
750            - superseded.iter().map(SyntaxNode::len).sum::<usize>();
751
752        // Compute the new number of descendants.
753        self.descendants = self.descendants
754            + replacement.iter().map(SyntaxNode::descendants).sum::<usize>()
755            - superseded.iter().map(SyntaxNode::descendants).sum::<usize>();
756
757        // Update our diagnosis after the replacement.
758        // - If we had no errors/warnings before, we can just use the replaced
759        //   diagnosis
760        // - Or, if our replacement has errors _and_ warnings, we can use that
761        // - Otherwise, we need to update based on all of the children _outside_
762        //   the replaced range in case we replaced the erroneous children
763        let replaced_diagnosis = Diagnosis::any(replacement);
764        if !self.diagnosis.either() || replaced_diagnosis.both() {
765            self.diagnosis = replaced_diagnosis;
766        } else {
767            self.diagnosis = replaced_diagnosis.or(Diagnosis::or(
768                Diagnosis::any(&self.children[..range.start]),
769                Diagnosis::any(&self.children[range.end..]),
770            ));
771        }
772
773        // Perform the replacement.
774        self.children
775            .splice(range.clone(), replacement_vec.drain(replacement_range.clone()));
776        range.end = range.start + replacement_range.len();
777
778        // Renumber the new children. Retries until it works, taking
779        // exponentially more children into account.
780        let mut left = 0;
781        let mut right = 0;
782        let max_left = range.start;
783        let max_right = self.children.len() - range.end;
784        loop {
785            let renumber = range.start - left..range.end + right;
786
787            // The minimum assignable number is either
788            // - the upper bound of the node right before the to-be-renumbered
789            //   children,
790            // - or this inner node's span number plus one if renumbering starts
791            //   at the first child.
792            let start_number = renumber
793                .start
794                .checked_sub(1)
795                .and_then(|i| self.children.get(i))
796                .map_or(span.number() + 1, |child| child.upper());
797
798            // The upper bound for renumbering is either
799            // - the span number of the first child after the to-be-renumbered
800            //   children,
801            // - or this node's upper bound if renumbering ends behind the last
802            //   child.
803            let end_number = self
804                .children
805                .get(renumber.end)
806                .map_or(self.upper, |next| next.span().number());
807
808            // Try to renumber.
809            let within = start_number..end_number;
810            if self.numberize(span, id, Some(renumber), within).is_ok() {
811                return Ok(());
812            }
813
814            // If it didn't even work with all children, we give up.
815            if left == max_left && right == max_right {
816                return Err(Unnumberable);
817            }
818
819            // Exponential expansion to both sides.
820            left = (left + 1).next_power_of_two().min(max_left);
821            right = (right + 1).next_power_of_two().min(max_right);
822        }
823    }
824
825    /// Update this node after changes were made to one of its children.
826    fn update_parent(
827        &mut self,
828        prev_len: usize,
829        new_len: usize,
830        prev_descendants: usize,
831        new_descendants: usize,
832    ) {
833        self.len = self.len + new_len - prev_len;
834        self.descendants = self.descendants + new_descendants - prev_descendants;
835        self.diagnosis = Diagnosis::any(&self.children);
836    }
837
838    /// Format the inner node with its `SyntaxKind` for debugging.
839    fn debug_fmt(&self, f: &mut Formatter, kind: SyntaxKind) -> fmt::Result {
840        write!(f, "{kind:?}: {}", self.len)?;
841        if !self.children.is_empty() {
842            f.write_str(" ")?;
843            f.debug_list().entries(&self.children).finish()?;
844        }
845        Ok(())
846    }
847}
848
849/// Whether a node has diagnostic errors and/or warnings in it or its children.
850#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash)]
851pub struct Diagnosis {
852    pub errors: bool,
853    pub warnings: bool,
854}
855
856impl Diagnosis {
857    /// Whether there were errors or warnings.
858    pub fn either(self) -> bool {
859        self.errors | self.warnings
860    }
861
862    /// Whether there were both errors and warnings.
863    pub fn both(self) -> bool {
864        self.errors & self.warnings
865    }
866
867    /// Apply the `OR` of both fields separately.
868    pub fn or(mut self, other: Self) -> Self {
869        self.errors |= other.errors;
870        self.warnings |= other.warnings;
871        self
872    }
873
874    /// Whether any node in the given slice has errors or warnings.
875    fn any(slice: &[SyntaxNode]) -> Self {
876        slice
877            .iter()
878            .map(SyntaxNode::diagnosis)
879            .fold(Self::default(), Self::or)
880    }
881}
882
883/// A syntactical error or warning. This is mainly used by converting it to a
884/// `SourceDiagnostic` during evaluation.
885#[derive(Debug, Clone, Eq, PartialEq, Hash)]
886pub struct SyntaxDiagnostic {
887    /// `true` if the diagnostic is an error, `false` if it's a warning.
888    pub is_error: bool,
889    /// The span targeted by the diagnostic.
890    pub span: DiagSpan,
891    /// The main diagnostic message.
892    pub message: EcoString,
893    /// Additional hints to the user indicating how this issue could be avoided
894    /// or worked around.
895    pub hints: EcoVec<Spanned<EcoString, DiagSpan>>,
896}
897
898/// An error node in the untyped syntax tree.
899#[derive(Clone, Eq, PartialEq, Hash)]
900struct ErrorNode {
901    /// The source text of the node.
902    text: EcoString,
903    /// The error message.
904    message: EcoString,
905    /// Additional hints to the user indicating how this error could be avoided
906    /// or worked around.
907    hints: EcoVec<(EcoString, Option<SubRange>)>,
908}
909
910impl ErrorNode {
911    /// Create a new error node.
912    fn new(message: EcoString, text: EcoString) -> Self {
913        Self { text, message, hints: eco_vec![] }
914    }
915
916    /// Produce the syntax diagnostic for an error.
917    fn diagnostic(&self, span: Span) -> SyntaxDiagnostic {
918        SyntaxDiagnostic {
919            is_error: true,
920            span: span.into(),
921            message: self.message.clone(),
922            hints: build_diagnostic_hints(span, &self.hints),
923        }
924    }
925}
926
927impl Debug for ErrorNode {
928    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
929        if self.text.is_empty() && self.hints.is_empty() {
930            write!(f, "Error: {:?}", self.message)
931        } else {
932            let mut out = f.debug_struct("Error:");
933            out.field("text", &self.text);
934            out.field("message", &self.message);
935            for (hint, sub_range) in &self.hints {
936                let field = if let Some(sub_range) = sub_range {
937                    let selected = &self.text[sub_range.to_relative()];
938                    &format!("hint @({selected:?})")
939                } else {
940                    "hint"
941                };
942                out.field(field, hint);
943            }
944            out.finish()
945        }
946    }
947}
948
949/// A warning message wrapped around a node in the tree.
950///
951/// Warnings transparently wrap another node and do not have spans or text of
952/// their own. This means their child cannot be directly found or mutated, only
953/// affected _through_ the warning, usually via the [`SyntaxNode::node_ref`] and
954/// [`SyntaxNode::inner_and_span_mut`] methods.
955#[derive(Clone, Eq, PartialEq, Hash)]
956struct WarningWrapper {
957    /// The wrapped node data.
958    child: Node,
959    /// A relative sub-range for targeting text not grouped by an existing span.
960    ///
961    /// Warnings may need to target a range of text that isn't actually grouped
962    /// by the syntax tree, this sub-range can select that text.
963    sub_range: Option<SubRange>,
964    /// The warning message.
965    message: EcoString,
966    /// Additional hints to the user indicating how this warning could be
967    /// avoided or worked around.
968    hints: EcoVec<(EcoString, Option<SubRange>)>,
969}
970
971impl WarningWrapper {
972    /// Wrap an existing syntax node in a warning node.
973    fn new(child: Node, sub_range: Option<SubRange>, message: EcoString) -> Self {
974        Self { child, sub_range, message, hints: eco_vec![] }
975    }
976
977    /// Produce the syntax diagnostic for a warning.
978    fn diagnostic(&self, span: Span) -> SyntaxDiagnostic {
979        SyntaxDiagnostic {
980            is_error: false,
981            span: DiagSpan::from_span(span, self.sub_range),
982            message: self.message.clone(),
983            hints: build_diagnostic_hints(span, &self.hints),
984        }
985    }
986}
987
988impl Debug for WarningWrapper {
989    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
990        let full_text = LazyCell::new(|| {
991            let data = self.child.clone();
992            let temp_node = SyntaxNode { data, span: Span::detached() };
993            temp_node.full_text()
994        });
995        let debug_field = |field, message, sub_range: Option<SubRange>| {
996            // Inner closure has `move`, so need to explicitly capture by ref.
997            let full_text = &full_text;
998            debug(move |f| {
999                if let Some(sr) = sub_range {
1000                    let selected = &full_text[sr.to_relative()];
1001                    write!(f, "{field} @({selected:?}): {message:?}")
1002                } else {
1003                    write!(f, "{field}: {message:?}")
1004                }
1005            })
1006        };
1007
1008        write!(f, "Warning: ")?;
1009        // Use `debug_set` instead of `debug_struct` so we don't have to add a
1010        // field name when outputting the child.
1011        let mut out = f.debug_set();
1012        out.entry(&debug_field("message", &self.message, self.sub_range));
1013        for (hint, sub_range) in &self.hints {
1014            out.entry(&debug_field("hint", hint, *sub_range));
1015        }
1016        out.entry(&self.child);
1017        out.finish()
1018    }
1019}
1020
1021/// Map a vector of hints with optional sub-ranges to one with optional
1022/// diagnostic spans derived from a parent span.
1023fn build_diagnostic_hints(
1024    parent_span: Span,
1025    hints: &EcoVec<(EcoString, Option<SubRange>)>,
1026) -> EcoVec<Spanned<EcoString, DiagSpan>> {
1027    hints
1028        .iter()
1029        .map(|(message, sub_range)| {
1030            let msg = message.clone();
1031            match *sub_range {
1032                Some(sr) => Spanned::new(msg, DiagSpan::from_span(parent_span, Some(sr))),
1033                None => Spanned::detached(msg),
1034            }
1035        })
1036        .collect()
1037}
1038
1039/// A syntax node in a context.
1040///
1041/// Knows its exact offset in the file and provides access to its
1042/// children, parent and siblings.
1043///
1044/// **Note that all sibling and leaf accessors skip over trivia!**
1045#[derive(Clone)]
1046pub struct LinkedNode<'a> {
1047    /// The underlying syntax node.
1048    node: &'a SyntaxNode,
1049    /// The parent of this node.
1050    parent: Option<Rc<Self>>,
1051    /// The index of this node in its parent's children array.
1052    index: usize,
1053    /// This node's byte offset in the source file.
1054    offset: usize,
1055}
1056
1057impl<'a> LinkedNode<'a> {
1058    /// Start a new traversal at a root node.
1059    pub fn new(root: &'a SyntaxNode) -> Self {
1060        Self { node: root, parent: None, index: 0, offset: 0 }
1061    }
1062
1063    /// Get the contained syntax node.
1064    pub fn get(&self) -> &'a SyntaxNode {
1065        self.node
1066    }
1067
1068    /// The index of this node in its parent's children list.
1069    pub fn index(&self) -> usize {
1070        self.index
1071    }
1072
1073    /// The absolute byte offset of this node in the source file.
1074    pub fn offset(&self) -> usize {
1075        self.offset
1076    }
1077
1078    /// The byte range of this node in the source file.
1079    pub fn range(&self) -> Range<usize> {
1080        self.offset..self.offset + self.node.len()
1081    }
1082
1083    /// An iterator over this node's children.
1084    pub fn children(&self) -> LinkedChildren<'a> {
1085        LinkedChildren {
1086            parent: Rc::new(self.clone()),
1087            iter: self.node.children().enumerate(),
1088            front: self.offset,
1089            back: self.offset + self.len(),
1090        }
1091    }
1092
1093    /// Find a descendant with the given span.
1094    pub fn find(&self, span: Span) -> Option<Self> {
1095        match span.get() {
1096            SpanKind::Detached => None,
1097            SpanKind::Number { id: _, num } => self.find_number(num),
1098            SpanKind::Range { id: _, range } => self.find_range(range.start, range.end),
1099        }
1100    }
1101
1102    /// Find the descendant whose span number matches the given number.
1103    ///
1104    /// This relies on the ordering guarantees of numbered spans:
1105    /// - The number of a parent is smaller than the numbers of all its children
1106    /// - The numbers of sibling nodes always increase from left to right
1107    pub(crate) fn find_number(&self, target: SpanNumber) -> Option<Self> {
1108        let number = self.span().number();
1109        if number == target.0 {
1110            return Some(self.clone());
1111        }
1112
1113        // The parent of a subtree has a smaller span number than all of its
1114        // descendants. Therefore, we can bail out early if the target span's
1115        // number is smaller than our number.
1116        if self.node.is_inner() && number < target.0 {
1117            // Use `self.children()`, not `inner.children()` to preserve being
1118            // in a `LinkedNode`.
1119            let mut children = self.children().peekable();
1120            while let Some(child) = children.next() {
1121                // Every node in this child's subtree has a smaller span number than
1122                // the next sibling. Therefore we only need to recurse if the next
1123                // sibling's span number is larger than the target span's number.
1124                if children.peek().is_none_or(|next| next.span().number() > target.0)
1125                    && let Some(found) = child.find_number(target)
1126                {
1127                    return Some(found);
1128                }
1129            }
1130        }
1131
1132        None
1133    }
1134
1135    /// Find the descendant whose byte range matches the given range exactly.
1136    pub(crate) fn find_range(&self, start: usize, end: usize) -> Option<Self> {
1137        if start == self.offset && end == self.offset + self.len() {
1138            return Some(self.clone());
1139        }
1140        for child in self.children() {
1141            // Descend into the single child which fully covers the range.
1142            if child.offset <= start && end <= child.offset + child.len() {
1143                return child.find_range(start, end);
1144            }
1145        }
1146        None
1147    }
1148
1149    /// Get the [`SyntaxMode`] we will be in when immediately after this node.
1150    ///
1151    /// Unlike some other `LinkedNode` methods, this does not treat all trivia
1152    /// the same: it returns `None` for both comments and the bodies of raw text
1153    /// and returns `Some` for whitespace (based on the parent's mode). The only
1154    /// other way this would return `None` is when inside a partial tree, i.e.
1155    /// one not rooted in `Markup`, `Math`, or `Code`.
1156    ///
1157    /// Also note that errors inherit the mode of their parent.
1158    pub fn mode_after(&self) -> Option<SyntaxMode> {
1159        match self.kind().mode_after() {
1160            ModeAfter::Known(mode) => Some(mode),
1161            // Comments and the bodies of raw text have no mode.
1162            ModeAfter::None => None,
1163            ModeAfter::Text if self.parent_kind() == Some(SyntaxKind::Raw) => None,
1164            ModeAfter::RawDelim if self.index == 0 => None,
1165            // Text not under raw is always markup.
1166            ModeAfter::Text => Some(SyntaxMode::Markup),
1167            // An opening dollar sign starts math mode.
1168            ModeAfter::Dollar if self.index == 0 => Some(SyntaxMode::Math),
1169            // Spaces at the left/right of an equation are still in math mode.
1170            ModeAfter::Space if self.parent_kind() == Some(SyntaxKind::Equation) => {
1171                Some(SyntaxMode::Math)
1172            }
1173            // The position after something embedded with a hash is still code.
1174            ModeAfter::Embeddable
1175                if self
1176                    .prev_sibling_with_trivia()
1177                    .is_some_and(|prev| prev.kind() == SyntaxKind::Hash) =>
1178            {
1179                Some(SyntaxMode::Code)
1180            }
1181            // Otherwise, we're simply based on our parent's mode.
1182            ModeAfter::Parent
1183            | ModeAfter::RawDelim
1184            | ModeAfter::Space
1185            | ModeAfter::Dollar
1186            | ModeAfter::Embeddable => self.parent_mode(),
1187        }
1188    }
1189
1190    /// Get the [`SyntaxMode`] we will be in when immediately after the parent
1191    /// of this node.
1192    pub fn parent_mode(&self) -> Option<SyntaxMode> {
1193        self.parent().and_then(Self::mode_after)
1194    }
1195}
1196
1197/// Access to parents and siblings.
1198impl LinkedNode<'_> {
1199    /// Get this node's parent.
1200    pub fn parent(&self) -> Option<&Self> {
1201        self.parent.as_deref()
1202    }
1203
1204    /// Get the first previous non-trivia sibling node.
1205    pub fn prev_sibling(&self) -> Option<Self> {
1206        let parent = self.parent.as_ref()?;
1207        let children = parent.node.children().as_slice();
1208        let mut offset = self.offset;
1209        for (index, node) in children[..self.index].iter().enumerate().rev() {
1210            offset -= node.len();
1211            if !node.kind().is_trivia() {
1212                let parent = Some(parent.clone());
1213                return Some(Self { node, parent, index, offset });
1214            }
1215        }
1216        None
1217    }
1218
1219    /// Get the first previous sibling node, including potential trivia.
1220    pub fn prev_sibling_with_trivia(&self) -> Option<Self> {
1221        let parent = self.parent.as_ref()?;
1222        let children = parent.node.children().as_slice();
1223        let (index, node) = children[..self.index].iter().enumerate().next_back()?;
1224        let offset = self.offset - node.len();
1225        let parent = Some(parent.clone());
1226        Some(Self { node, parent, index, offset })
1227    }
1228
1229    /// Get the next non-trivia sibling node.
1230    pub fn next_sibling(&self) -> Option<Self> {
1231        let parent = self.parent.as_ref()?;
1232        let children = parent.node.children();
1233        let mut offset = self.offset + self.len();
1234        for (index, node) in children.enumerate().skip(self.index + 1) {
1235            if !node.kind().is_trivia() {
1236                let parent = Some(parent.clone());
1237                return Some(Self { node, parent, index, offset });
1238            }
1239            offset += node.len();
1240        }
1241        None
1242    }
1243
1244    /// Get the next sibling node, including potential trivia.
1245    pub fn next_sibling_with_trivia(&self) -> Option<Self> {
1246        let parent = self.parent.as_ref()?;
1247        let children = parent.node.children();
1248        let (index, node) = children.enumerate().nth(self.index + 1)?;
1249        let offset = self.offset + self.len();
1250        let parent = Some(parent.clone());
1251        Some(Self { node, parent, index, offset })
1252    }
1253
1254    /// Get the kind of this node's parent.
1255    pub fn parent_kind(&self) -> Option<SyntaxKind> {
1256        Some(self.parent()?.node.kind())
1257    }
1258
1259    /// Get the kind of this node's first previous non-trivia sibling.
1260    pub fn prev_sibling_kind(&self) -> Option<SyntaxKind> {
1261        Some(self.prev_sibling()?.node.kind())
1262    }
1263
1264    /// Get the kind of this node's next non-trivia sibling.
1265    pub fn next_sibling_kind(&self) -> Option<SyntaxKind> {
1266        Some(self.next_sibling()?.node.kind())
1267    }
1268}
1269
1270/// Indicates whether the cursor is before the related byte index, or after.
1271#[derive(Debug, Clone)]
1272pub enum Side {
1273    Before,
1274    After,
1275}
1276
1277/// Access to leaves.
1278impl LinkedNode<'_> {
1279    /// Get the rightmost non-trivia leaf before this node.
1280    pub fn prev_leaf(&self) -> Option<Self> {
1281        let mut node = self.clone();
1282        while let Some(prev) = node.prev_sibling() {
1283            if let Some(leaf) = prev.rightmost_leaf() {
1284                return Some(leaf);
1285            }
1286            node = prev;
1287        }
1288        self.parent()?.prev_leaf()
1289    }
1290
1291    /// Find the leftmost contained non-trivia leaf.
1292    pub fn leftmost_leaf(&self) -> Option<Self> {
1293        if self.is_leaf() && !self.kind().is_trivia() && !self.kind().is_error() {
1294            return Some(self.clone());
1295        }
1296
1297        for child in self.children() {
1298            if let Some(leaf) = child.leftmost_leaf() {
1299                return Some(leaf);
1300            }
1301        }
1302
1303        None
1304    }
1305
1306    /// Get the leaf immediately before the specified byte offset.
1307    fn leaf_before(&self, cursor: usize) -> Option<Self> {
1308        if self.node.children().len() == 0 && cursor <= self.offset + self.len() {
1309            return Some(self.clone());
1310        }
1311
1312        let mut offset = self.offset;
1313        let count = self.node.children().len();
1314        for (i, child) in self.children().enumerate() {
1315            let len = child.len();
1316            if (offset < cursor && cursor <= offset + len)
1317                || (offset == cursor && i + 1 == count)
1318            {
1319                return child.leaf_before(cursor);
1320            }
1321            offset += len;
1322        }
1323
1324        None
1325    }
1326
1327    /// Get the leaf after the specified byte offset.
1328    fn leaf_after(&self, cursor: usize) -> Option<Self> {
1329        if self.node.children().len() == 0 && cursor < self.offset + self.len() {
1330            return Some(self.clone());
1331        }
1332
1333        let mut offset = self.offset;
1334        for child in self.children() {
1335            let len = child.len();
1336            if offset <= cursor && cursor < offset + len {
1337                return child.leaf_after(cursor);
1338            }
1339            offset += len;
1340        }
1341
1342        None
1343    }
1344
1345    /// Get the leaf at the specified byte offset.
1346    pub fn leaf_at(&self, cursor: usize, side: Side) -> Option<Self> {
1347        match side {
1348            Side::Before => self.leaf_before(cursor),
1349            Side::After => self.leaf_after(cursor),
1350        }
1351    }
1352
1353    /// Find the rightmost contained non-trivia leaf.
1354    pub fn rightmost_leaf(&self) -> Option<Self> {
1355        if self.is_leaf() && !self.kind().is_trivia() {
1356            return Some(self.clone());
1357        }
1358
1359        for child in self.children().rev() {
1360            if let Some(leaf) = child.rightmost_leaf() {
1361                return Some(leaf);
1362            }
1363        }
1364
1365        None
1366    }
1367
1368    /// Get the leftmost non-trivia leaf after this node.
1369    pub fn next_leaf(&self) -> Option<Self> {
1370        let mut node = self.clone();
1371        while let Some(next) = node.next_sibling() {
1372            if let Some(leaf) = next.leftmost_leaf() {
1373                return Some(leaf);
1374            }
1375            node = next;
1376        }
1377        self.parent()?.next_leaf()
1378    }
1379}
1380
1381impl Deref for LinkedNode<'_> {
1382    type Target = SyntaxNode;
1383
1384    /// Dereference to a syntax node. Note that this shortens the lifetime, so
1385    /// you may need to use [`get()`](Self::get) instead in some situations.
1386    fn deref(&self) -> &Self::Target {
1387        self.get()
1388    }
1389}
1390
1391impl Debug for LinkedNode<'_> {
1392    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1393        self.node.fmt(f)
1394    }
1395}
1396
1397/// An iterator over the children of a linked node.
1398pub struct LinkedChildren<'a> {
1399    /// The parent whose children we're iterating.
1400    parent: Rc<LinkedNode<'a>>,
1401    /// The underlying syntax nodes and their indices.
1402    iter: std::iter::Enumerate<std::slice::Iter<'a, SyntaxNode>>,
1403    /// The byte offset of the next child's start.
1404    front: usize,
1405    /// The byte offset after the final child.
1406    back: usize,
1407}
1408
1409impl<'a> Iterator for LinkedChildren<'a> {
1410    type Item = LinkedNode<'a>;
1411
1412    fn next(&mut self) -> Option<Self::Item> {
1413        let (index, node) = self.iter.next()?;
1414        let offset = self.front;
1415        self.front += node.len();
1416        Some(LinkedNode {
1417            node,
1418            parent: Some(self.parent.clone()),
1419            index,
1420            offset,
1421        })
1422    }
1423
1424    fn size_hint(&self) -> (usize, Option<usize>) {
1425        self.iter.size_hint()
1426    }
1427}
1428
1429impl DoubleEndedIterator for LinkedChildren<'_> {
1430    fn next_back(&mut self) -> Option<Self::Item> {
1431        let (index, node) = self.iter.next_back()?;
1432        self.back -= node.len();
1433        Some(LinkedNode {
1434            node,
1435            parent: Some(self.parent.clone()),
1436            index,
1437            offset: self.back,
1438        })
1439    }
1440}
1441
1442impl ExactSizeIterator for LinkedChildren<'_> {}
1443
1444/// Result of numbering a node within an interval.
1445pub(super) type NumberingResult = Result<(), Unnumberable>;
1446
1447/// Indicates that a node cannot be numbered within a given interval.
1448#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1449pub(super) struct Unnumberable;
1450
1451impl Display for Unnumberable {
1452    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1453        f.pad("cannot number within this interval")
1454    }
1455}
1456
1457impl std::error::Error for Unnumberable {}
1458
1459#[cfg(test)]
1460mod tests {
1461    use super::*;
1462    use crate::Source;
1463
1464    /// Test the debug output of a `SyntaxNode`.
1465    #[test]
1466    fn test_debug() {
1467        // A standard syntax tree:
1468        assert_eq!(
1469            format!("{:#?}", crate::parse("= Head <label>")),
1470            "\
1471Markup: 14 [
1472    Heading: 6 [
1473        HeadingMarker: \"=\",
1474        Space: \" \",
1475        Markup: 4 [
1476            Text: \"Head\",
1477        ],
1478    ],
1479    Space: \" \",
1480    Label: \"<label>\",
1481]"
1482        );
1483        // A basic syntax error:
1484        assert_eq!(
1485            format!("{:#?}", crate::parse("#")),
1486            "\
1487Markup: 1 [
1488    Hash: \"#\",
1489    Error: \"expected expression\",
1490]"
1491        );
1492        // A syntax error with multiple hints:
1493        assert_eq!(
1494            format!("{:#?}", crate::parse("##")),
1495            "\
1496Markup: 2 [
1497    Hash: \"#\",
1498    Error: {
1499        text: \"#\",
1500        message: \"the character `#` is not valid in code\",
1501        hint: \"the preceding hash is causing this to parse in code mode\",
1502        hint: \"try escaping the preceding hash: `\\\\#`\",
1503    },
1504]"
1505        );
1506        // A warning with a hint:
1507        assert_eq!(
1508            format!("{:#?}", crate::parse("**")),
1509            "\
1510Markup: 2 [
1511    Warning: {
1512        message: \"no text within stars\",
1513        hint: \"using multiple consecutive stars (e.g. **) has no additional effect\",
1514        Strong: 2 [
1515            Star: \"*\",
1516            Markup: 0,
1517            Star: \"*\",
1518        ],
1519    },
1520]"
1521        );
1522    }
1523
1524    #[test]
1525    fn test_debug_sub_range() {
1526        // An example warning for text at a sub-range:
1527        let mut root = crate::parse("= =head");
1528        let heading_body = &mut root.children_mut()[0];
1529        heading_body.warn_at(0..3, "equal space equal!");
1530        heading_body.hint("try equal equal space?");
1531        assert_eq!(
1532            format!("{root:#?}"),
1533            "\
1534Markup: 7 [
1535    Warning: {
1536        message @(\"= =\"): \"equal space equal!\",
1537        hint: \"try equal equal space?\",
1538        Heading: 7 [
1539            HeadingMarker: \"=\",
1540            Space: \" \",
1541            Markup: 5 [
1542                Text: \"=head\",
1543            ],
1544        ],
1545    },
1546]"
1547        );
1548
1549        // An example for hints at sub-ranges:
1550        let mut root = crate::parse("<unclosed");
1551        let node = &mut root.children_mut()[0];
1552        // Hint on the "unclosed label" error:
1553        node.hint_at(0..1, "greater");
1554        node.hint_at(3..8, "open!");
1555        // Adding a warning with hints around the error:
1556        node.warn_at(3..9, "opened?");
1557        node.hint_at(0..9, "full text"); // no special treatment
1558        assert_eq!(
1559            format!("{root:#?}"),
1560            "\
1561Markup: 9 [
1562    Warning: {
1563        message @(\"closed\"): \"opened?\",
1564        hint @(\"<unclosed\"): \"full text\",
1565        Error: {
1566            text: \"<unclosed\",
1567            message: \"unclosed label\",
1568            hint @(\"<\"): \"greater\",
1569            hint @(\"close\"): \"open!\",
1570        },
1571    },
1572]"
1573        );
1574    }
1575
1576    #[test]
1577    fn test_linked_node() {
1578        let source = Source::detached("#set text(12pt, red)");
1579
1580        // Find "text" with Before.
1581        let node = LinkedNode::new(source.root()).leaf_at(7, Side::Before).unwrap();
1582        assert_eq!(node.offset(), 5);
1583        assert_eq!(node.leaf_text(), "text");
1584
1585        // Find "text" with After.
1586        let node = LinkedNode::new(source.root()).leaf_at(7, Side::After).unwrap();
1587        assert_eq!(node.offset(), 5);
1588        assert_eq!(node.leaf_text(), "text");
1589
1590        // Go back to "#set". Skips the space.
1591        let prev = node.prev_sibling().unwrap();
1592        assert_eq!(prev.offset(), 1);
1593        assert_eq!(prev.leaf_text(), "set");
1594    }
1595
1596    #[test]
1597    fn test_linked_node_non_trivia_leaf() {
1598        let source = Source::detached("#set fun(12pt, red)");
1599        let leaf = LinkedNode::new(source.root()).leaf_at(6, Side::Before).unwrap();
1600        let prev = leaf.prev_leaf().unwrap();
1601        assert_eq!(leaf.leaf_text(), "fun");
1602        assert_eq!(prev.leaf_text(), "set");
1603
1604        // Check position 9 with Before.
1605        let source = Source::detached("#let x = 10");
1606        let leaf = LinkedNode::new(source.root()).leaf_at(9, Side::Before).unwrap();
1607        let prev = leaf.prev_leaf().unwrap();
1608        let next = leaf.next_leaf().unwrap();
1609        assert_eq!(prev.leaf_text(), "=");
1610        assert_eq!(leaf.leaf_text(), " ");
1611        assert_eq!(next.leaf_text(), "10");
1612
1613        // Check position 9 with After.
1614        let source = Source::detached("#let x = 10");
1615        let leaf = LinkedNode::new(source.root()).leaf_at(9, Side::After).unwrap();
1616        let prev = leaf.prev_leaf().unwrap();
1617        assert!(leaf.next_leaf().is_none());
1618        assert_eq!(prev.leaf_text(), "=");
1619        assert_eq!(leaf.leaf_text(), "10");
1620    }
1621}