1use std::fmt::{Display, Formatter, Result};
2use std::sync::Arc;
3use std::vec::IntoIter;
4
5use crate::{Source, Span, Spanned, lexer::punctuation_would_merge};
6
7#[path = "token_stream/delim.rs"]
8pub mod delim;
9use delim::{Delimiter, DelimiterKind};
10
11#[path = "token_stream/punct.rs"]
12mod punct;
13pub use punct::Punct;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum LiteralKind {
18 String,
20 RawString,
22 Integer,
24 Float,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct LiteralToken {
31 pub kind: LiteralKind,
33 span: Span,
34 leading_trivia: LeadingTrivia,
35 trailing_trivia: TrailingTrivia,
36}
37
38impl LiteralToken {
39 pub fn from_span(kind: LiteralKind, span: Span) -> Self {
41 Self {
42 kind,
43 span,
44 leading_trivia: LeadingTrivia::default(),
45 trailing_trivia: TrailingTrivia::default(),
46 }
47 }
48
49 pub fn new(kind: LiteralKind, text: impl Into<Arc<str>>, span: Span) -> Self {
51 Self {
52 kind,
53 span: span_for_spelling(text.into(), span),
54 leading_trivia: LeadingTrivia::default(),
55 trailing_trivia: TrailingTrivia::default(),
56 }
57 }
58
59 pub fn text(&self) -> &str {
65 self.span
66 .text()
67 .expect("literal spans must resolve to source text")
68 }
69}
70
71impl Spanned for LiteralToken {
72 fn try_span(&self) -> Option<Span> {
73 Some(self.span.clone())
74 }
75}
76
77impl Lex for LiteralToken {
78 fn to_tokens(&self, output: &mut TokenStream) {
79 output.push(TokenTree::Literal(self.clone()));
80 }
81}
82
83impl Terminal for LiteralToken {
84 fn leading_trivia(&self) -> &LeadingTrivia {
85 &self.leading_trivia
86 }
87
88 fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
89 &mut self.leading_trivia
90 }
91
92 fn trailing_trivia(&self) -> &TrailingTrivia {
93 &self.trailing_trivia
94 }
95
96 fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
97 &mut self.trailing_trivia
98 }
99}
100
101#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct IdentToken {
104 span: Span,
105 source_qualifier: Option<Span>,
106 index_qualifier: Option<Span>,
107 leading_trivia: LeadingTrivia,
108 trailing_trivia: TrailingTrivia,
109}
110
111impl IdentToken {
112 pub fn from_span(span: Span) -> Self {
118 let text = span
119 .text()
120 .expect("identifier spans must resolve to source text");
121 let (source_qualifier, index_qualifier) = identifier_qualifier_spans(text, &span);
122 Self {
123 span,
124 source_qualifier,
125 index_qualifier,
126 leading_trivia: LeadingTrivia::default(),
127 trailing_trivia: TrailingTrivia::default(),
128 }
129 }
130
131 pub fn new(text: impl Into<Arc<str>>, span: Span) -> Self {
133 Self::from_span(span_for_spelling(text.into(), span))
134 }
135
136 pub fn text(&self) -> &str {
142 self.span
143 .text()
144 .expect("identifier spans must resolve to source text")
145 }
146
147 pub fn source_qualifier(&self) -> Option<&Span> {
149 self.source_qualifier.as_ref()
150 }
151
152 pub fn index_qualifier(&self) -> Option<&Span> {
154 self.index_qualifier.as_ref()
155 }
156}
157
158impl Spanned for IdentToken {
159 fn try_span(&self) -> Option<Span> {
160 Some(self.span.clone())
161 }
162}
163
164impl Lex for IdentToken {
165 fn to_tokens(&self, output: &mut TokenStream) {
166 output.push(TokenTree::Ident(self.clone()));
167 }
168}
169
170impl Terminal for IdentToken {
171 fn leading_trivia(&self) -> &LeadingTrivia {
172 &self.leading_trivia
173 }
174
175 fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
176 &mut self.leading_trivia
177 }
178
179 fn trailing_trivia(&self) -> &TrailingTrivia {
180 &self.trailing_trivia
181 }
182
183 fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
184 &mut self.trailing_trivia
185 }
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
189pub struct TokenGroup {
191 delimiter: Delimiter,
192 stream: TokenStream,
193 leading_trivia: LeadingTrivia,
194 trailing_trivia: TrailingTrivia,
195}
196
197impl Spanned for TokenGroup {
198 fn try_span(&self) -> Option<Span> {
199 self.delimiter.try_span()
200 }
201}
202
203impl TokenGroup {
204 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
206 Self {
207 delimiter,
208 stream,
209 leading_trivia: LeadingTrivia::default(),
210 trailing_trivia: TrailingTrivia::default(),
211 }
212 }
213
214 pub fn delimiter(&self) -> &Delimiter {
216 &self.delimiter
217 }
218
219 pub fn delim_kind(&self) -> DelimiterKind {
221 self.delimiter.kind
222 }
223
224 pub fn stream(&self) -> &TokenStream {
226 &self.stream
227 }
228
229 pub fn stream_mut(&mut self) -> &mut TokenStream {
231 &mut self.stream
232 }
233
234 pub fn into_stream(self) -> TokenStream {
236 self.stream
237 }
238}
239
240impl Lex for TokenGroup {
241 fn to_tokens(&self, output: &mut TokenStream) {
242 output.push(TokenTree::Group(self.clone()));
243 }
244}
245
246impl Terminal for TokenGroup {
247 fn leading_trivia(&self) -> &LeadingTrivia {
248 &self.leading_trivia
249 }
250
251 fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
252 &mut self.leading_trivia
253 }
254
255 fn trailing_trivia(&self) -> &TrailingTrivia {
256 &self.trailing_trivia
257 }
258
259 fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
260 &mut self.trailing_trivia
261 }
262}
263
264#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
265pub enum TriviaKind {
267 LineComment,
269 BlockComment,
271}
272
273#[derive(Debug, Clone, PartialEq, Eq, Hash, Spanned)]
274pub struct Trivia {
276 kind: TriviaKind,
277 span: Span,
278}
279
280impl Trivia {
281 pub fn from_span(kind: TriviaKind, span: Span) -> Self {
283 Self { kind, span }
284 }
285
286 pub fn new(kind: TriviaKind, text: impl Into<Arc<str>>, span: Span) -> Self {
288 Self {
289 kind,
290 span: span_for_spelling(text.into(), span),
291 }
292 }
293
294 pub fn kind(&self) -> TriviaKind {
296 self.kind
297 }
298
299 pub fn text(&self) -> &str {
305 self.span
306 .text()
307 .expect("trivia spans must resolve to source text")
308 }
309}
310
311impl Lex for Trivia {
312 fn to_tokens(&self, output: &mut TokenStream) {
313 output.push_trailing_trivia(self.clone());
314 }
315}
316
317#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
318pub struct TrailingTrivia(Vec<Trivia>);
320
321impl TrailingTrivia {
322 pub fn new(trivia: impl IntoIterator<Item = Trivia>) -> Self {
324 Self(trivia.into_iter().collect())
325 }
326
327 pub fn as_slice(&self) -> &[Trivia] {
329 &self.0
330 }
331
332 pub fn as_mut_vec(&mut self) -> &mut Vec<Trivia> {
334 &mut self.0
335 }
336
337 pub fn is_empty(&self) -> bool {
339 self.0.is_empty()
340 }
341
342 pub fn into_vec(self) -> Vec<Trivia> {
344 self.0
345 }
346}
347
348impl FromIterator<Trivia> for TrailingTrivia {
349 fn from_iter<T: IntoIterator<Item = Trivia>>(iter: T) -> Self {
350 Self::new(iter)
351 }
352}
353
354impl Spanned for TrailingTrivia {
355 fn try_span(&self) -> Option<Span> {
356 Span::join_all(self.0.iter().map(Spanned::try_span))
357 }
358}
359
360impl Lex for TrailingTrivia {
361 fn to_tokens(&self, output: &mut TokenStream) {
362 self.0.to_tokens(output);
363 }
364}
365
366#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
367pub struct LeadingTrivia(Vec<Trivia>);
369
370impl LeadingTrivia {
371 pub fn new(trivia: impl IntoIterator<Item = Trivia>) -> Self {
373 Self(trivia.into_iter().collect())
374 }
375
376 pub fn as_slice(&self) -> &[Trivia] {
378 &self.0
379 }
380
381 pub fn as_mut_vec(&mut self) -> &mut Vec<Trivia> {
383 &mut self.0
384 }
385
386 pub fn is_empty(&self) -> bool {
388 self.0.is_empty()
389 }
390
391 pub fn into_vec(self) -> Vec<Trivia> {
393 self.0
394 }
395}
396
397impl FromIterator<Trivia> for LeadingTrivia {
398 fn from_iter<T: IntoIterator<Item = Trivia>>(iter: T) -> Self {
399 Self::new(iter)
400 }
401}
402
403impl Spanned for LeadingTrivia {
404 fn try_span(&self) -> Option<Span> {
405 Span::join_all(self.0.iter().map(Spanned::try_span))
406 }
407}
408
409impl Lex for LeadingTrivia {
410 fn to_tokens(&self, output: &mut TokenStream) {
411 for trivia in self.0.iter().cloned() {
412 output.push_leading_trivia(trivia);
413 }
414 }
415}
416
417#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Spanned)]
418pub struct CommentTrivia {
424 outer: Vec<Trivia>,
425 inner: Vec<Trivia>,
426}
427
428impl CommentTrivia {
429 pub fn outer(&self) -> &[Trivia] {
431 &self.outer
432 }
433
434 pub fn inner(&self) -> &[Trivia] {
436 &self.inner
437 }
438
439 pub fn is_empty(&self) -> bool {
441 self.outer.is_empty() && self.inner.is_empty()
442 }
443
444 pub(crate) fn take_from_cell(tokens: &mut TokenStream) -> Self {
445 let mut outer = Vec::new();
446 if let Some(first) = tokens.0.first_mut() {
447 let leading = first.leading_trivia_mut().as_mut_vec();
448 let mut retained = Vec::with_capacity(leading.len());
449 for trivia in std::mem::take(leading) {
450 if trivia.kind() == TriviaKind::LineComment {
451 outer.push(trivia);
452 } else {
453 retained.push(trivia);
454 }
455 }
456 *leading = retained;
457 }
458 let mut inner = take_stream_comments(tokens);
459 sort_comments(&mut outer);
460 sort_comments(&mut inner);
461 Self { outer, inner }
462 }
463
464 pub(crate) fn take_inner(tokens: &mut TokenStream) -> Self {
465 let mut inner = take_stream_comments(tokens);
466 sort_comments(&mut inner);
467 Self {
468 outer: Vec::new(),
469 inner,
470 }
471 }
472
473 pub(crate) fn append(&mut self, mut comments: Self) {
474 self.outer.append(&mut comments.outer);
475 self.inner.append(&mut comments.inner);
476 sort_comments(&mut self.outer);
477 sort_comments(&mut self.inner);
478 }
479
480 #[doc(hidden)]
483 pub fn __apply_to(&self, output: &mut TokenStream) {
484 for comment in self.outer.iter().rev().cloned() {
485 output.prepend_comment(comment);
486 }
487 for comment in self.inner.iter().cloned() {
488 output.insert_inner_comment(comment);
489 }
490 }
491}
492
493fn sort_comments(comments: &mut [Trivia]) {
494 comments.sort_by_key(|comment| comment.span().start().unwrap_or(usize::MAX));
495}
496
497fn take_stream_comments(stream: &mut TokenStream) -> Vec<Trivia> {
498 let mut comments = std::mem::take(&mut stream.1).into_vec();
499 for token in &mut stream.0 {
500 comments.extend(std::mem::take(token.leading_trivia_mut()).into_vec());
501 if let TokenTree::Group(group) = token {
502 comments.extend(take_stream_comments(group.stream_mut()));
503 }
504 comments.extend(std::mem::take(token.trailing_trivia_mut()).into_vec());
505 }
506 comments.extend(std::mem::take(&mut stream.2).into_vec());
507 comments
508}
509
510pub trait Terminal: Spanned {
512 fn leading_trivia(&self) -> &LeadingTrivia;
514
515 fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia;
517
518 fn trailing_trivia(&self) -> &TrailingTrivia;
520
521 fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia;
523
524 fn set_leading_trivia(&mut self, trivia: impl IntoIterator<Item = Trivia>)
526 where
527 Self: Sized,
528 {
529 *self.leading_trivia_mut() = LeadingTrivia::new(trivia);
530 }
531
532 fn set_trailing_trivia(&mut self, trivia: impl IntoIterator<Item = Trivia>)
534 where
535 Self: Sized,
536 {
537 *self.trailing_trivia_mut() = TrailingTrivia::new(trivia);
538 }
539}
540
541fn identifier_qualifier_spans(spelling: &str, span: &Span) -> (Option<Span>, Option<Span>) {
542 let separators = spelling
543 .match_indices('$')
544 .map(|(index, _)| index)
545 .collect::<Vec<_>>();
546 let source = separators.first().and_then(|separator| {
547 let name = &spelling[..*separator];
548 (!name.is_empty() && name.bytes().all(is_identifier_byte))
549 .then(|| span.subspan(0, separator + 1))
550 });
551 let index = separators.last().and_then(|separator| {
552 let digits = &spelling[separator + 1..];
553 (!digits.is_empty() && digits.bytes().all(|byte| byte.is_ascii_digit()))
554 .then(|| span.subspan(*separator, spelling.len()))
555 });
556 (source, index)
557}
558
559fn is_identifier_byte(byte: u8) -> bool {
560 byte == b'_' || byte.is_ascii_alphanumeric()
561}
562
563fn span_for_spelling(text: Arc<str>, span: Span) -> Span {
564 if span.text() == Some(text.as_ref()) {
565 span
566 } else {
567 let source = Source::with_file(span.file(), text);
568 let len = source.text().len();
569 Span::ranged(source, 0..len)
570 }
571}
572
573#[derive(Debug, Clone, PartialEq, Eq, Spanned)]
574pub enum TokenTree {
576 Group(TokenGroup),
578 Literal(LiteralToken),
580 Punct(Punct),
582 Ident(IdentToken),
584}
585
586impl TokenTree {
587 pub fn spelling(&self) -> Option<&str> {
589 match self {
590 Self::Literal(token) => Some(token.text()),
591 Self::Punct(token) => Some(token.text()),
592 Self::Ident(token) => Some(token.text()),
593 Self::Group(_) => None,
594 }
595 }
596
597 pub(crate) fn description(&self) -> String {
598 match self {
599 Self::Group(group) => group.delim_kind().to_string(),
600 token => token.spelling().unwrap_or("").to_owned(),
601 }
602 }
603
604 pub fn leading_trivia(&self) -> &LeadingTrivia {
606 match self {
607 Self::Group(token) => token.leading_trivia(),
608 Self::Literal(token) => token.leading_trivia(),
609 Self::Punct(token) => token.leading_trivia(),
610 Self::Ident(token) => token.leading_trivia(),
611 }
612 }
613
614 pub fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
616 match self {
617 Self::Group(token) => token.leading_trivia_mut(),
618 Self::Literal(token) => token.leading_trivia_mut(),
619 Self::Punct(token) => token.leading_trivia_mut(),
620 Self::Ident(token) => token.leading_trivia_mut(),
621 }
622 }
623
624 pub fn trailing_trivia(&self) -> &TrailingTrivia {
626 match self {
627 Self::Group(token) => token.trailing_trivia(),
628 Self::Literal(token) => token.trailing_trivia(),
629 Self::Punct(token) => token.trailing_trivia(),
630 Self::Ident(token) => token.trailing_trivia(),
631 }
632 }
633
634 pub fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
636 match self {
637 Self::Group(token) => token.trailing_trivia_mut(),
638 Self::Literal(token) => token.trailing_trivia_mut(),
639 Self::Punct(token) => token.trailing_trivia_mut(),
640 Self::Ident(token) => token.trailing_trivia_mut(),
641 }
642 }
643}
644impl Lex for TokenTree {
645 fn to_tokens(&self, output: &mut TokenStream) {
646 output.push(self.clone());
647 }
648}
649
650#[derive(Debug, Clone, Default, PartialEq, Eq, Spanned)]
651pub struct TokenStream(Vec<TokenTree>, TrailingTrivia, LeadingTrivia, Option<Span>);
653
654impl TokenStream {
655 pub fn new() -> Self {
657 Self::default()
658 }
659
660 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &TokenTree> + ExactSizeIterator {
662 self.0.iter()
663 }
664
665 pub fn is_empty(&self) -> bool {
667 self.0.is_empty()
668 }
669
670 pub(crate) fn len(&self) -> usize {
671 self.0.len()
672 }
673
674 pub(crate) fn get(&self, position: usize) -> Option<&TokenTree> {
675 self.0.get(position)
676 }
677
678 pub(crate) fn last(&self) -> Option<&TokenTree> {
679 self.0.last()
680 }
681
682 pub(crate) fn has_significant_tokens(&self) -> bool {
683 !self.0.is_empty()
684 }
685
686 pub(crate) fn has_trivia(&self) -> bool {
687 !self.1.is_empty() || !self.2.is_empty()
688 }
689
690 pub(crate) fn prefix_trivia(&self) -> &[Trivia] {
691 self.1.as_slice()
692 }
693
694 pub(crate) fn suffix_trivia(&self) -> &[Trivia] {
695 self.2.as_slice()
696 }
697
698 pub(crate) fn source(&self) -> Option<Arc<Source>> {
699 let mut source = self.3.as_ref().map(|span| Arc::clone(span.source()));
700 coherent_stream_source(self, &mut source)
701 .then_some(source)
702 .flatten()
703 }
704
705 pub(crate) fn set_physical_eof(&mut self, eof: Span) {
706 self.3 = Some(eof);
707 }
708
709 pub(crate) fn take_physical_eof(&mut self) -> Option<Span> {
710 self.3.take()
711 }
712
713 pub(crate) fn take_final_punctuation(
714 &mut self,
715 spelling: &str,
716 ) -> Option<(Punct, TrailingTrivia)> {
717 let position = self.0.len().checked_sub(1)?;
718 let TokenTree::Punct(punctuation) = self.0.get(position)? else {
719 return None;
720 };
721 if punctuation.text() != spelling {
722 return None;
723 }
724 let TokenTree::Punct(mut punctuation) = self.0.remove(position) else {
725 unreachable!("the final significant token was punctuation")
726 };
727 let trailing_trivia = std::mem::take(punctuation.trailing_trivia_mut());
728 Some((punctuation, trailing_trivia))
729 }
730
731 pub(crate) fn take_leading_trivia(&mut self) -> TrailingTrivia {
732 let mut trivia = std::mem::take(&mut self.1).into_vec();
733 trivia.extend(std::mem::take(&mut self.2).into_vec());
734 TrailingTrivia::new(trivia)
735 }
736
737 pub(crate) fn take_prefix_trivia(&mut self) -> TrailingTrivia {
738 std::mem::take(&mut self.1)
739 }
740
741 pub(crate) fn take_suffix_trivia(&mut self) -> LeadingTrivia {
742 std::mem::take(&mut self.2)
743 }
744
745 pub(crate) fn push(&mut self, mut token: TokenTree) {
746 if let Some(TokenTree::Group(group)) = self.0.last_mut()
747 && !group.delimiter().is_closed()
748 {
749 group.stream_mut().push(token);
750 } else {
751 token
752 .leading_trivia_mut()
753 .as_mut_vec()
754 .splice(..0, std::mem::take(&mut self.2).into_vec());
755 self.0.push(token);
756 }
757 }
758
759 pub(crate) fn push_line_comment(&mut self, comment: Trivia) {
760 if let Some(TokenTree::Group(group)) = self.0.last_mut()
761 && !group.delimiter().is_closed()
762 {
763 group.stream_mut().push_line_comment(comment);
764 } else if let Some(comment) = complete_line_comment(&comment) {
765 push_line_comment_block(self.2.as_mut_vec(), comment);
766 } else if let Some(token) = self.0.last_mut() {
767 token.trailing_trivia_mut().as_mut_vec().push(comment);
768 } else {
769 self.1.as_mut_vec().push(comment);
770 }
771 }
772
773 #[doc(hidden)]
774 pub fn push_leading_trivia(&mut self, trivia: Trivia) {
775 if let Some(TokenTree::Group(group)) = self.0.last_mut()
776 && !group.delimiter().is_closed()
777 {
778 group.stream_mut().push_leading_trivia(trivia);
779 } else {
780 self.2.as_mut_vec().push(trivia);
781 }
782 }
783
784 pub(crate) fn push_block_comment(&mut self, comment: Trivia) {
785 if let Some(TokenTree::Group(group)) = self.0.last_mut()
786 && !group.delimiter().is_closed()
787 {
788 group.stream_mut().push_block_comment(comment);
789 } else if let Some(token) = self.0.last_mut() {
790 token.trailing_trivia_mut().as_mut_vec().push(comment);
791 } else if !self.2.is_empty() {
792 self.2.as_mut_vec().push(comment);
793 } else {
794 self.1.as_mut_vec().push(comment);
795 }
796 }
797
798 pub(crate) fn push_trailing_trivia(&mut self, trivia: Trivia) {
799 if let Some(token) = self.0.last_mut() {
800 token.trailing_trivia_mut().as_mut_vec().push(trivia);
801 } else {
802 self.1.as_mut_vec().push(trivia);
803 }
804 }
805
806 pub(crate) fn complete_last_group(&mut self, kind: DelimiterKind, close: Span) -> bool {
807 let Some(TokenTree::Group(group)) = self.0.last_mut() else {
808 return false;
809 };
810 if group.stream.complete_last_group(kind, close.clone()) {
811 return true;
812 }
813 if group.delim_kind() != kind || group.delimiter().is_closed() {
814 return false;
815 }
816 group.delimiter.spans.complete(close);
817 true
818 }
819
820 pub(crate) fn last_innermost(&self) -> Option<&TokenTree> {
821 let last = self.last()?;
822 match last {
823 TokenTree::Group(group) if !group.delimiter().is_closed() => {
824 group.stream().last_innermost().or(Some(last))
825 }
826 _ => Some(last),
827 }
828 }
829
830 fn prepend_comment(&mut self, comment: Trivia) {
831 if let Some(first) = self.0.first_mut() {
832 first.leading_trivia_mut().as_mut_vec().insert(0, comment);
833 } else {
834 self.1.as_mut_vec().insert(0, comment);
835 }
836 }
837
838 fn insert_inner_comment(&mut self, comment: Trivia) {
839 let start = comment.span().start();
840 if let Some(start) = start {
841 for token in &mut self.0 {
842 if let TokenTree::Group(group) = token {
843 let span = group.span();
844 if span.shares_source(&comment.span())
845 && span.start().is_some_and(|open| open <= start)
846 && span.end().is_some_and(|close| start <= close)
847 {
848 group.stream_mut().insert_inner_comment(comment);
849 return;
850 }
851 }
852 }
853
854 if let Some(token) = self.0.iter_mut().rev().find(|token| {
855 let span = token.span();
856 span.shares_source(&comment.span())
857 && span.start().is_some_and(|token_start| token_start <= start)
858 }) {
859 token.trailing_trivia_mut().as_mut_vec().push(comment);
860 return;
861 }
862
863 if self
864 .0
865 .iter()
866 .any(|token| token.span().shares_source(&comment.span()))
867 {
868 self.1.as_mut_vec().push(comment);
869 return;
870 }
871 }
872
873 if let Some(last) = self.0.last_mut() {
874 last.trailing_trivia_mut().as_mut_vec().push(comment);
875 } else {
876 self.1.as_mut_vec().push(comment);
877 }
878 }
879
880 #[doc(hidden)]
881 pub fn starts_with_whitespace(&self) -> bool {
882 false
883 }
884
885 #[doc(hidden)]
886 pub fn ends_with_whitespace(&self) -> bool {
887 false
888 }
889
890 #[doc(hidden)]
891 pub fn ends_with_line_break(&self) -> bool {
892 self.0
893 .last()
894 .is_some_and(|token| gap_after_contains(token, '\n'))
895 }
896
897 #[doc(hidden)]
898 pub fn ends_with_semicolon(&self) -> bool {
899 matches!(self.0.last(), Some(TokenTree::Punct(token)) if token.text() == ";")
900 }
901
902 #[doc(hidden)]
910 pub fn append_fragment<T: Lex + ?Sized>(&mut self, fragment: &T) {
911 let fragment = fragment.to_token_stream();
912 self.extend([fragment]);
913 }
914
915 pub fn pop(&mut self) -> Option<TokenTree> {
917 self.0.pop()
918 }
919
920 pub fn to_source(&self) -> String {
922 self.to_string()
923 }
924}
925
926fn complete_line_comment(comment: &Trivia) -> Option<Trivia> {
927 let span = comment.span();
928 let (Some(start), Some(end)) = (span.start(), span.end()) else {
929 return None;
930 };
931 let source = span.source();
932 let line_start = source.text()[..start]
933 .rfind('\n')
934 .map_or(0, |newline| newline + 1);
935 source.text()[line_start..start]
936 .bytes()
937 .all(|byte| matches!(byte, b' ' | b'\t' | b'\r'))
938 .then(|| {
939 Trivia::from_span(
940 TriviaKind::LineComment,
941 Span::ranged(Arc::clone(source), line_start..end),
942 )
943 })
944}
945
946fn push_line_comment_block(comments: &mut Vec<Trivia>, comment: Trivia) {
947 let Some(previous) = comments.last_mut() else {
948 comments.push(comment);
949 return;
950 };
951 if previous.kind() != TriviaKind::LineComment || !previous.span().shares_source(&comment.span())
952 {
953 comments.push(comment);
954 return;
955 }
956 let (Some(previous_start), Some(previous_end), Some(comment_start), Some(comment_end)) = (
957 previous.span().start(),
958 previous.span().end(),
959 comment.span().start(),
960 comment.span().end(),
961 ) else {
962 comments.push(comment);
963 return;
964 };
965 let previous_span = previous.span();
966 let gap = &previous_span.source().text()[previous_end..comment_start];
967 let same_block = gap
968 .strip_prefix("\r\n")
969 .or_else(|| gap.strip_prefix('\n'))
970 .is_some_and(|indent| indent.bytes().all(|byte| matches!(byte, b' ' | b'\t')));
971 if same_block {
972 *previous = Trivia::from_span(
973 TriviaKind::LineComment,
974 Span::ranged(
975 Arc::clone(previous.span().source()),
976 previous_start..comment_end,
977 ),
978 );
979 } else {
980 comments.push(comment);
981 }
982}
983
984fn coherent_stream_source(stream: &TokenStream, source: &mut Option<Arc<Source>>) -> bool {
985 for trivia in stream.prefix_trivia().iter().chain(stream.suffix_trivia()) {
986 if !record_source(trivia.span(), source) {
987 return false;
988 }
989 }
990 for token in stream.iter() {
991 if !record_source(token.span(), source)
992 || !token
993 .leading_trivia()
994 .as_slice()
995 .iter()
996 .chain(token.trailing_trivia().as_slice())
997 .all(|trivia| record_source(trivia.span(), source))
998 {
999 return false;
1000 }
1001 if let TokenTree::Group(group) = token
1002 && !coherent_stream_source(group.stream(), source)
1003 {
1004 return false;
1005 }
1006 }
1007 true
1008}
1009
1010fn record_source(span: Span, source: &mut Option<Arc<Source>>) -> bool {
1011 match source {
1012 Some(expected) => Arc::ptr_eq(expected, span.source()),
1013 None => {
1014 *source = Some(Arc::clone(span.source()));
1015 true
1016 }
1017 }
1018}
1019
1020impl Display for TokenStream {
1021 fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
1022 write_stream(formatter, self)
1023 }
1024}
1025fn needs_separator(left: &TokenTree, right: &TokenTree) -> bool {
1026 let left_span = left.span();
1027 let right_span = right.span();
1028 if left_span.shares_source(&right_span) && left_span.end() == right_span.start() {
1029 return false;
1030 }
1031 let wordlike = |tree: &TokenTree| {
1032 matches!(
1033 tree,
1034 TokenTree::Ident(_) | TokenTree::Literal(_) | TokenTree::Group(_)
1035 )
1036 };
1037 (wordlike(left) && wordlike(right))
1038 || matches!((left, right), (TokenTree::Punct(left), TokenTree::Punct(right))
1039 if punctuation_would_merge(left.text(), right.text()))
1040}
1041
1042fn write_stream(formatter: &mut Formatter<'_>, stream: &TokenStream) -> Result {
1043 let mut previous_span = write_trivia(formatter, None, stream.1.as_slice())?;
1044 let mut previous_atom = None::<&TokenTree>;
1045 for tree in &stream.0 {
1046 if !tree.leading_trivia().is_empty() {
1047 previous_span =
1048 write_trivia(formatter, previous_span, tree.leading_trivia().as_slice())?;
1049 previous_atom = None;
1050 }
1051 if let Some(left) = previous_span {
1052 let recovered_space = write_source_spaces(formatter, left, tree.span())?;
1053 if !recovered_space && previous_atom.is_some_and(|left| needs_separator(left, tree)) {
1054 formatter.write_str(" ")?;
1055 }
1056 }
1057 write_tree(formatter, tree)?;
1058 previous_span = Some(tree.span());
1059 previous_atom = Some(tree);
1060 if !tree.trailing_trivia().is_empty() {
1061 previous_span =
1062 write_trivia(formatter, previous_span, tree.trailing_trivia().as_slice())?;
1063 previous_atom = None;
1064 }
1065 }
1066 write_trivia(formatter, previous_span, stream.2.as_slice())?;
1067 Ok(())
1068}
1069
1070fn write_trivia(
1071 formatter: &mut Formatter<'_>,
1072 mut previous: Option<Span>,
1073 trivia: &[Trivia],
1074) -> std::result::Result<Option<Span>, std::fmt::Error> {
1075 for item in trivia {
1076 if let Some(left) = previous {
1077 write_source_spaces(formatter, left, item.span())?;
1078 }
1079 formatter.write_str(item.text())?;
1080 previous = Some(item.span());
1081 }
1082 Ok(previous)
1083}
1084
1085fn write_source_spaces(
1086 formatter: &mut Formatter<'_>,
1087 left: Span,
1088 right: Span,
1089) -> std::result::Result<bool, std::fmt::Error> {
1090 if !left.shares_source(&right) {
1091 return Ok(false);
1092 }
1093 let (Some(end), Some(start)) = (left.end(), right.start()) else {
1094 return Ok(false);
1095 };
1096 if end > start {
1097 return Ok(false);
1098 }
1099 let gap = &left.source().text()[end..start];
1100 if gap.bytes().all(|byte| byte.is_ascii_whitespace()) {
1101 formatter.write_str(gap)?;
1102 Ok(true)
1103 } else {
1104 Ok(false)
1105 }
1106}
1107
1108fn write_tree(formatter: &mut Formatter<'_>, tree: &TokenTree) -> Result {
1109 match tree {
1110 TokenTree::Group(group) => {
1111 formatter.write_str(group.delim_kind().opening())?;
1112 let opening = group.delimiter().opening_span();
1113 if let Some(first) = group.stream.iter().next() {
1114 write_source_spaces(formatter, opening.clone(), first.span())?;
1115 }
1116 write_stream(formatter, &group.stream)?;
1117 if let Some(closing) = group.delimiter().closing_span() {
1118 let left = group
1119 .stream
1120 .iter()
1121 .next_back()
1122 .map_or(opening, Spanned::span);
1123 write_source_spaces(formatter, left, closing)?;
1124 formatter.write_str(group.delim_kind().closing())?;
1125 }
1126 Ok(())
1127 }
1128 TokenTree::Literal(literal) => formatter.write_str(literal.text()),
1129 TokenTree::Punct(punct) => formatter.write_str(punct.text()),
1130 TokenTree::Ident(ident) => formatter.write_str(ident.text()),
1131 }
1132}
1133
1134fn gap_after_contains(token: &TokenTree, character: char) -> bool {
1135 let span = token
1136 .trailing_trivia()
1137 .as_slice()
1138 .last()
1139 .map_or_else(|| token.span(), Spanned::span);
1140 let Some(end) = span.end() else {
1141 return false;
1142 };
1143 span.source().text()[end..].contains(character)
1144}
1145
1146impl<T: Lex> Extend<T> for TokenStream {
1154 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1155 for item in iter {
1156 item.to_tokens(self);
1157 }
1158 }
1159}
1160
1161impl FromIterator<TokenTree> for TokenStream {
1162 fn from_iter<T: IntoIterator<Item = TokenTree>>(iter: T) -> Self {
1163 Self(
1164 iter.into_iter().collect(),
1165 TrailingTrivia::default(),
1166 LeadingTrivia::default(),
1167 None,
1168 )
1169 }
1170}
1171
1172impl IntoIterator for TokenStream {
1173 type Item = TokenTree;
1174 type IntoIter = IntoIter<TokenTree>;
1175 fn into_iter(self) -> Self::IntoIter {
1176 self.0.into_iter()
1177 }
1178}
1179
1180impl Lex for TokenStream {
1181 fn to_tokens(&self, output: &mut TokenStream) {
1182 let preserve_eof = output.0.is_empty() && output.1.is_empty() && output.2.is_empty();
1183 for trivia in self.1.as_slice().iter().cloned() {
1184 output.push_trailing_trivia(trivia);
1185 }
1186 for token in self.0.iter().cloned() {
1187 output.push(token);
1188 }
1189 output
1190 .2
1191 .as_mut_vec()
1192 .extend(self.2.as_slice().iter().cloned());
1193 output.3 = preserve_eof.then(|| self.3.clone()).flatten();
1194 }
1195}
1196
1197pub trait Lex {
1199 fn to_tokens(&self, output: &mut TokenStream);
1201
1202 fn to_token_stream(&self) -> TokenStream {
1204 let mut output = TokenStream::new();
1205 self.to_tokens(&mut output);
1206 output
1207 }
1208
1209 fn to_m2(&self) -> String {
1211 self.to_token_stream().to_source()
1212 }
1213}
1214
1215impl<T: Lex + ?Sized> Lex for &T {
1216 fn to_tokens(&self, output: &mut TokenStream) {
1217 (*self).to_tokens(output);
1218 }
1219}
1220
1221impl<T: Lex + ?Sized> Lex for Box<T> {
1222 fn to_tokens(&self, output: &mut TokenStream) {
1223 self.as_ref().to_tokens(output);
1224 }
1225}
1226
1227impl<T: Lex> Lex for Option<T> {
1228 fn to_tokens(&self, output: &mut TokenStream) {
1229 if let Some(value) = self {
1230 value.to_tokens(output);
1231 }
1232 }
1233}
1234
1235impl<T: Lex> Lex for [T] {
1236 fn to_tokens(&self, output: &mut TokenStream) {
1237 for token in self {
1238 token.to_tokens(output);
1239 }
1240 }
1241}
1242
1243impl<T: Lex> Lex for Vec<T> {
1244 fn to_tokens(&self, output: &mut TokenStream) {
1245 self.as_slice().to_tokens(output);
1246 }
1247}