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#[derive(Clone, Eq, PartialEq, Hash)]
18pub struct SyntaxNode {
19 data: Node,
21 span: Span,
23 }
26
27#[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
60enum NodeRef<'a> {
62 Leaf(&'a EcoString),
63 Inner(&'a Arc<InnerNode>),
64 Error(&'a Arc<ErrorNode>),
65}
66
67impl SyntaxNode {
68 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 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 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 #[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 #[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 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 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 #[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()); 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 #[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 #[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()); 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 #[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 #[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 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 pub fn is_empty(&self) -> bool {
227 self.len() == 0
228 }
229
230 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 pub fn span(&self) -> Span {
241 self.span
242 }
243
244 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 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 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 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 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 pub fn synthesize(&mut self, span: Span) {
331 self.synthesize_with(0, &|_, _| span, &|_, sub_range| *sub_range = None);
333 }
334
335 pub fn synthesize_mapped(
343 &mut self,
344 id: FileId,
345 mapper: &RangeMapper,
346 ) -> Result<(), EcoString> {
347 if self.len() > mapper.total_len() {
348 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 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 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 #[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 panic!("cannot convert an error to a different kind");
450 }
451 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 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 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 pub(super) fn unexpected(&mut self) {
491 self.convert_to_error(eco_format!("unexpected {}", self.kind().name()));
492 }
493
494 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 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 recursive_step(self, &mut f);
526 }
527
528 pub(super) fn is_leaf(&self) -> bool {
530 matches!(self.node_ref(), NodeRef::Leaf(_))
531 }
533
534 pub(super) fn is_inner(&self) -> bool {
536 matches!(self.node_ref(), NodeRef::Inner(_))
537 }
538
539 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 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 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 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 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#[derive(Clone, Eq, PartialEq, Hash)]
618struct InnerNode {
619 len: usize,
621 descendants: usize,
623 diagnosis: Diagnosis,
626 upper: u64,
628 children: Vec<SyntaxNode>,
630}
631
632impl InnerNode {
633 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 fn numberize(
651 &mut self,
652 span: &mut Span,
653 id: FileId,
654 range: Option<Range<usize>>,
655 within: Range<u64>,
656 ) -> NumberingResult {
657 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 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 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 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 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 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 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 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 self.len = self.len + replacement.iter().map(SyntaxNode::len).sum::<usize>()
750 - superseded.iter().map(SyntaxNode::len).sum::<usize>();
751
752 self.descendants = self.descendants
754 + replacement.iter().map(SyntaxNode::descendants).sum::<usize>()
755 - superseded.iter().map(SyntaxNode::descendants).sum::<usize>();
756
757 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 self.children
775 .splice(range.clone(), replacement_vec.drain(replacement_range.clone()));
776 range.end = range.start + replacement_range.len();
777
778 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 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 let end_number = self
804 .children
805 .get(renumber.end)
806 .map_or(self.upper, |next| next.span().number());
807
808 let within = start_number..end_number;
810 if self.numberize(span, id, Some(renumber), within).is_ok() {
811 return Ok(());
812 }
813
814 if left == max_left && right == max_right {
816 return Err(Unnumberable);
817 }
818
819 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 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 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#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash)]
851pub struct Diagnosis {
852 pub errors: bool,
853 pub warnings: bool,
854}
855
856impl Diagnosis {
857 pub fn either(self) -> bool {
859 self.errors | self.warnings
860 }
861
862 pub fn both(self) -> bool {
864 self.errors & self.warnings
865 }
866
867 pub fn or(mut self, other: Self) -> Self {
869 self.errors |= other.errors;
870 self.warnings |= other.warnings;
871 self
872 }
873
874 fn any(slice: &[SyntaxNode]) -> Self {
876 slice
877 .iter()
878 .map(SyntaxNode::diagnosis)
879 .fold(Self::default(), Self::or)
880 }
881}
882
883#[derive(Debug, Clone, Eq, PartialEq, Hash)]
886pub struct SyntaxDiagnostic {
887 pub is_error: bool,
889 pub span: DiagSpan,
891 pub message: EcoString,
893 pub hints: EcoVec<Spanned<EcoString, DiagSpan>>,
896}
897
898#[derive(Clone, Eq, PartialEq, Hash)]
900struct ErrorNode {
901 text: EcoString,
903 message: EcoString,
905 hints: EcoVec<(EcoString, Option<SubRange>)>,
908}
909
910impl ErrorNode {
911 fn new(message: EcoString, text: EcoString) -> Self {
913 Self { text, message, hints: eco_vec![] }
914 }
915
916 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#[derive(Clone, Eq, PartialEq, Hash)]
956struct WarningWrapper {
957 child: Node,
959 sub_range: Option<SubRange>,
964 message: EcoString,
966 hints: EcoVec<(EcoString, Option<SubRange>)>,
969}
970
971impl WarningWrapper {
972 fn new(child: Node, sub_range: Option<SubRange>, message: EcoString) -> Self {
974 Self { child, sub_range, message, hints: eco_vec![] }
975 }
976
977 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 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 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
1021fn 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#[derive(Clone)]
1046pub struct LinkedNode<'a> {
1047 node: &'a SyntaxNode,
1049 parent: Option<Rc<Self>>,
1051 index: usize,
1053 offset: usize,
1055}
1056
1057impl<'a> LinkedNode<'a> {
1058 pub fn new(root: &'a SyntaxNode) -> Self {
1060 Self { node: root, parent: None, index: 0, offset: 0 }
1061 }
1062
1063 pub fn get(&self) -> &'a SyntaxNode {
1065 self.node
1066 }
1067
1068 pub fn index(&self) -> usize {
1070 self.index
1071 }
1072
1073 pub fn offset(&self) -> usize {
1075 self.offset
1076 }
1077
1078 pub fn range(&self) -> Range<usize> {
1080 self.offset..self.offset + self.node.len()
1081 }
1082
1083 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 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 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 if self.node.is_inner() && number < target.0 {
1117 let mut children = self.children().peekable();
1120 while let Some(child) = children.next() {
1121 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 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 if child.offset <= start && end <= child.offset + child.len() {
1143 return child.find_range(start, end);
1144 }
1145 }
1146 None
1147 }
1148
1149 pub fn mode_after(&self) -> Option<SyntaxMode> {
1159 match self.kind().mode_after() {
1160 ModeAfter::Known(mode) => Some(mode),
1161 ModeAfter::None => None,
1163 ModeAfter::Text if self.parent_kind() == Some(SyntaxKind::Raw) => None,
1164 ModeAfter::RawDelim if self.index == 0 => None,
1165 ModeAfter::Text => Some(SyntaxMode::Markup),
1167 ModeAfter::Dollar if self.index == 0 => Some(SyntaxMode::Math),
1169 ModeAfter::Space if self.parent_kind() == Some(SyntaxKind::Equation) => {
1171 Some(SyntaxMode::Math)
1172 }
1173 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 ModeAfter::Parent
1183 | ModeAfter::RawDelim
1184 | ModeAfter::Space
1185 | ModeAfter::Dollar
1186 | ModeAfter::Embeddable => self.parent_mode(),
1187 }
1188 }
1189
1190 pub fn parent_mode(&self) -> Option<SyntaxMode> {
1193 self.parent().and_then(Self::mode_after)
1194 }
1195}
1196
1197impl LinkedNode<'_> {
1199 pub fn parent(&self) -> Option<&Self> {
1201 self.parent.as_deref()
1202 }
1203
1204 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 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 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 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 pub fn parent_kind(&self) -> Option<SyntaxKind> {
1256 Some(self.parent()?.node.kind())
1257 }
1258
1259 pub fn prev_sibling_kind(&self) -> Option<SyntaxKind> {
1261 Some(self.prev_sibling()?.node.kind())
1262 }
1263
1264 pub fn next_sibling_kind(&self) -> Option<SyntaxKind> {
1266 Some(self.next_sibling()?.node.kind())
1267 }
1268}
1269
1270#[derive(Debug, Clone)]
1272pub enum Side {
1273 Before,
1274 After,
1275}
1276
1277impl LinkedNode<'_> {
1279 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 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 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 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 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 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 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 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
1397pub struct LinkedChildren<'a> {
1399 parent: Rc<LinkedNode<'a>>,
1401 iter: std::iter::Enumerate<std::slice::Iter<'a, SyntaxNode>>,
1403 front: usize,
1405 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
1444pub(super) type NumberingResult = Result<(), Unnumberable>;
1446
1447#[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]
1466 fn test_debug() {
1467 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 assert_eq!(
1485 format!("{:#?}", crate::parse("#")),
1486 "\
1487Markup: 1 [
1488 Hash: \"#\",
1489 Error: \"expected expression\",
1490]"
1491 );
1492 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 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 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 let mut root = crate::parse("<unclosed");
1551 let node = &mut root.children_mut()[0];
1552 node.hint_at(0..1, "greater");
1554 node.hint_at(3..8, "open!");
1555 node.warn_at(3..9, "opened?");
1557 node.hint_at(0..9, "full text"); 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 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 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 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 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 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}