1use crate::{
2 used_proc_macro::{
3 token_stream::IntoIter,
4 Delimiter, Group, Ident, Punct, Literal, TokenStream, TokenTree, Spacing, Span,
5 },
6 parsing_shared::{parenthesize_ts, out_ident},
7 mmatches, try_,
8};
9
10use core::{
11 iter::{Peekable, once},
12 ops::Range,
13};
14
15use alloc::{
16 string::{String, ToString},
17 format,
18};
19
20
21
22pub(crate) mod cmp_ts;
23pub(crate) mod list_generation;
24
25
26
27pub(crate) fn macro_span() -> Span {
28 #[cfg(not(feature = "rust_1_45"))]
29 let span = Span::call_site();
30
31 #[cfg(feature = "rust_1_45")]
32 let span = Span::mixed_site();
33
34 span
35}
36
37
38macro_rules! match_token {
39 ($msg:expr, $matched:expr => $($branches:tt)* ) => {
40 match $matched {
41 $($branches)*
42 Some(tt) => {
43 return Err(crate::Error::one_tt(tt.span(), &$msg));
46 }
47 None =>{
48 return Err(crate::Error::end($msg))
49 }
50 }
51 };
52} pub(crate) use match_token;
53
54
55#[allow(dead_code)]
56pub(crate) fn parse_integer<I>(mut input: I) -> crate::Result<usize>
57where
58 I: Iterator<Item = TokenTree>
59{
60 match_token!{"expected a decimal integer", input.next() =>
61 Some(TokenTree::Literal(lit)) => {
62 lit.to_string().parse::<usize>()
63 .map_err(|_| crate::Error::one_tt(lit.span(), "expected a decimal integer") )
64 }
65 }
66}
67
68pub(crate) fn parse_count_param<I>(input: I) -> crate::Result<(usize, Span)>
69where
70 I: IntoIterator<Item = TokenTree>,
71{
72 const MSG: &str = "\
73 expected either `count(....)` or an integer literal\
74 ";
75
76 let sident;
77
78 let mut input = input.into_iter();
79
80 match_token!{MSG, input.next() =>
81 Some(TokenTree::Ident(ident)) if {
82 sident = ident.to_string();
83 sident == "count"
84 } => {
85 match_token!{"expected parentheses", input.next() =>
86 Some(TokenTree::Group(group)) => {
87 Ok((group.stream().into_iter().count() as usize, group.span()))
88 }
89 }
90 }
91 Some(TokenTree::Group(group)) if mmatches!(group.delimiter(), Delimiter::None) => {
92 let mut iter = group.stream().into_iter();
93 let res = parse_count_param(&mut iter);
94
95 if let Some(tt) = iter.next() {
96 return Err(Error::one_tt(tt.span(), "Expected no more tokens after integer"));
97 }
98
99 res
100 }
101 Some(TokenTree::Literal(lit)) => {
102 const IL_MSG: &str = "could not parse integer literal";
103
104 let int = try_!(lit.to_string().parse::<usize>(),
105 map_err = |_| crate::Error::one_tt(lit.span(), IL_MSG)
106 );
107
108 Ok((int, lit.span()))
109 }
110 }
111}
112
113
114
115pub(crate) struct CountAnd<U> {
116 pub(crate) count: usize,
117 #[allow(dead_code)]
118 pub(crate) count_span: Span,
119 pub(crate) other: U,
120}
121
122pub(crate) fn parse_count_and<I, F, U>(iter: I, func: F) -> crate::Result<CountAnd<U>>
123where
124 I: IntoIterator<Item = TokenTree>,
125 F: FnOnce(&mut I::IntoIter) -> crate::Result<U>,
126{
127 let mut iter = iter.into_iter();
128
129 let (count, count_span) = try_!(parse_count_param(&mut iter));
130
131 try_!(parse_check_punct(&mut iter, ','));
132
133 let other = try_!(func(&mut iter));
134
135 try_!(expect_no_tokens(iter));
136
137 Ok(CountAnd{count, count_span, other})
138}
139
140
141pub(crate) struct RangeB {
144 pub(crate) start: usize,
145 pub(crate) end: Option<usize>,
146 pub(crate) spans: Spans,
147}
148
149pub(crate) fn parse_start_bound(input: &mut Peekable<IntoIter>) -> crate::Result<(usize, Span)> {
150 match input.peek() {
151 Some(TokenTree::Punct(p)) if p.as_char() == '.' => Ok((0, p.span())),
152 _=> parse_count_param(&mut *input)
153 }
154}
155
156pub(crate) fn parse_range_param(input: &mut Peekable<IntoIter>) -> crate::Result<RangeB> {
157 let (start, start_span) = try_!(parse_start_bound(&mut *input));
158 let (end, end_span);
159
160 let range_ty = try_!(parse_range_operator(&mut *input));
161
162 match range_ty {
163 RangeType::Inclusive|RangeType::Exclusive=> {
164 let (end_, end_span_) = try_!(parse_count_param(input));
165 end = if let RangeType::Inclusive = range_ty {
166 Some(end_.saturating_add(1))
167 } else {
168 Some(end_)
169 };
170 end_span = end_span_;
171 }
172 RangeType::RangeStart => {
173 end = None;
174 end_span = start_span;
175 }
176 }
177
178 let spans = Spans {start: start_span, end: end_span};
179 Ok(RangeB{start, end, spans})
180}
181
182pub(crate) fn parse_bounded_range_param(
183 input: &mut Peekable<IntoIter>,
184) -> crate::Result<Range<usize>> {
185 let RangeB{start, end, spans} = try_!(parse_range_param(input));
186 const ERR_MSG: &str = "Expected a finite range";
187 let end = match end {
188 Some(x) => x,
189 None => return Err(crate::Error::with_spans(spans, ERR_MSG)),
190 };
191 Ok(start .. end)
192}
193
194pub(crate) fn parse_unbounded_range_param(
195 input: &mut Peekable<IntoIter>,
196) -> crate::Result<Range<usize>> {
197 let RangeB{start, end, ..} = try_!(parse_range_param(input));
198 let end = end.unwrap_or(!0);
199 Ok(start .. end)
200}
201
202pub(crate) fn parse_int_or_range_param(
204 input: &mut Peekable<IntoIter>,
205) -> crate::Result<RangeB> {
206 let (start, start_span) = try_!(parse_start_bound(&mut *input));
207 let mut end_span = start_span;
208
209 let end = match try_!(parse_range_operator_opt(&mut *input)) {
210 Some(RangeType::RangeStart) => None,
211 Some(range_ty) => {
212 let (end_, end_span_) = try_!(parse_count_param(input));
213 end_span = end_span_;
214 if let RangeType::Inclusive = range_ty {
215 Some(end_.saturating_add(1))
216 } else {
217 Some(end_)
218 }
219 },
220 None => Some(start.saturating_add(1)),
221 };
222
223 let spans = Spans{start: start_span, end: end_span};
224 Ok(RangeB{start, end, spans})
225}
226
227
228
229pub(crate) enum RangeType {
230 Inclusive,
231 Exclusive,
232 RangeStart,
233}
234
235fn parse_range_operator_inner(input: &mut Peekable<IntoIter>) -> crate::Result<RangeType> {
236 match_token!{"expected a range", input.next() =>
237 Some(TokenTree::Punct(_)) => {}
238 }
239
240 match input.peek() {
241 Some(TokenTree::Punct(punct)) if punct.as_char() == '=' => {
242 input.next();
243 Ok(RangeType::Inclusive)
244 },
245 Some(_) => Ok(RangeType::Exclusive),
246 None=> Ok(RangeType::RangeStart),
247 }
248}
249
250fn parse_range_operator(input: &mut Peekable<IntoIter>) -> crate::Result<RangeType> {
251 match_token!{"expected a range", input.next() =>
252 Some(TokenTree::Punct(punct)) if
253 punct.as_char() == '.' && mmatches!(punct.spacing(), Spacing::Joint)
254 => {
255 parse_range_operator_inner(input)
256 }
257 }
258}
259
260fn parse_range_operator_opt(input: &mut Peekable<IntoIter>) -> crate::Result<Option<RangeType>> {
261 match input.next() {
262 Some(TokenTree::Punct(punct)) if
263 punct.as_char() == '.' && mmatches!(punct.spacing(), Spacing::Joint)
264 => {
265 parse_range_operator_inner(input).map(Some)
266 }
267 Some(tt) => Err(crate::Error::one_tt(tt.span(), "expected a range")),
268 None => Ok(None)
269 }
270}
271
272
273pub(crate) fn parse_parentheses<I>(mut input: I) -> crate::Result<Group>
276where
277 I: Iterator<Item = TokenTree>
278{
279 match_token!{"expected parentheses", input.next() =>
280 Some(TokenTree::Group(group)) if mmatches!(group.delimiter(), Delimiter::Parenthesis) => {
281 Ok(group)
282 }
283 }
284}
285
286#[allow(dead_code)]
287pub(crate) fn assert_parentheses(tt: TokenTree) -> crate::Result<Group> {
288 match tt {
289 TokenTree::Group(group) if mmatches!(group.delimiter(), Delimiter::Parenthesis) =>
290 Ok(group),
291 tt => Err(crate::Error::one_tt(tt.span(), "expected parentheses"))
292 }
293}
294
295pub(crate) fn parse_group<I>(mut input: I) -> crate::Result<Group>
296where
297 I: Iterator<Item = TokenTree>
298{
299 match_token!{"expected `(`, `{`, or `[`", input.next() =>
300 Some(TokenTree::Group(group)) if !mmatches!(group.delimiter(), Delimiter::None) => {
301 Ok(group)
302 }
303 }
304}
305
306pub(crate) fn parse_ident<I>(mut input: I) -> crate::Result<Ident>
309where
310 I: Iterator<Item = TokenTree>
311{
312 match_token!{"expected identifier", input.next() =>
313 Some(TokenTree::Group(group)) if mmatches!(group.delimiter(), Delimiter::None) => {
314 parse_ident(group.stream().into_iter())
315 }
316 Some(TokenTree::Ident(ident)) => {
317 Ok(ident)
318 }
319 }
320}
321
322pub(crate) fn parse_keyword<I>(mut input: I, keyword: &str) -> crate::Result<Ident>
325where
326 I: Iterator<Item = TokenTree>
327{
328 match_token!{&format!("expected {:?}", keyword), input.next() =>
329 Some(TokenTree::Ident(ident)) if ident.to_string() == keyword => {
330 Ok(ident)
331 }
332 }
333}
334
335pub(crate) fn parse_check_punct<I>(mut input: I, punct: char) -> crate::Result<Punct>
338where
339 I: Iterator<Item = TokenTree>
340{
341 match_token!{&format!("expected {:?}", punct), input.next() =>
342 Some(TokenTree::Punct(p)) if p.as_char() == punct => {
343 Ok(p)
344 }
345 }
346}
347
348pub(crate) struct PathAndSpan {
356 pub(crate) path: TokenStream,
357 pub(crate) start_span: Span,
358 pub(crate) end_span: Span,
359 pub(crate) terminator: Option<TokenTree>,
360}
361
362pub(crate) fn parse_path_and_span<I>(
363 iter: I
364) -> crate::Result<PathAndSpan>
365where
366 I: IntoIterator<Item = TokenTree>
367{
368 let mut this = PathAndSpan{
369 path: TokenStream::new(),
370 start_span: Span::call_site(),
371 end_span: Span::call_site(),
372 terminator: None,
373 };
374
375 let mut start = true;
376
377 for tt in iter {
378 if start {
379 this.start_span = tt.span();
380 start = false;
381 } else {
382 this.end_span = tt.span();
383 };
384
385 macro_rules! return_ {
386 ($tt:expr) => ({
387 this.terminator = Some($tt);
388 return Ok(this);
389 });
390 }
391
392 match tt {
393 TokenTree::Group(group) => {
394 if mmatches!(group.delimiter(), Delimiter::None) {
395 this.path.extend(group.stream());
396 } else {
397 return_!(TokenTree::Group(group))
398 }
399 }
400 TokenTree::Punct(punct) => {
401 if punct.as_char() == ':' {
402 this.path.extend(once(TokenTree::Punct(punct)));
403 } else {
404 return_!(TokenTree::Punct(punct))
405 }
406 },
407 tt @ TokenTree::Literal(_) => return_!(tt),
408 x @ TokenTree::Ident(_) => {
409 this.path.extend(once(x));
410 }
411 }
412 }
413
414 Ok(this)
415}
416
417
418pub(crate) fn expect_no_tokens<I>(iter: I) -> Result<(), crate::Error>
422where
423 I: IntoIterator<Item = TokenTree>
424{
425 if let Some(tt) = iter.into_iter().next() {
426 let msg = "expected no more tokens, starting from this one";
427 Err(crate::Error::one_tt(tt.span(), msg))
428 } else {
429 Ok(())
430 }
431}
432
433
434pub(crate) fn usize_tt(n: usize, span: Span) -> TokenTree {
437 let mut lit = Literal::usize_unsuffixed(n);
438 lit.set_span(span);
439 TokenTree::Literal(lit)
440}
441
442pub(crate) fn out_parenthesized_tt(tt: TokenTree, out: &mut TokenStream) {
445 let span = tt.span();
446 out.extend(once(parenthesize_ts(tt.into(), span)));
447}
448
449pub(crate) fn braced_ts(ts: TokenStream, span: Span) -> TokenTree {
450 let mut group = Group::new(Delimiter::Brace, ts);
451 group.set_span(span);
452 TokenTree::Group(group)
453}
454
455pub(crate) fn out_braced_tt(tt: TokenTree, out: &mut TokenStream) {
456 let span = tt.span();
457 out.extend(once(braced_ts(tt.into(), span)));
458}
459
460#[derive(Copy, Clone)]
463pub(crate) struct Spans {
464 pub(crate) start: Span,
465 pub(crate) end: Span,
466}
467
468impl Spans {
469 #[inline(always)]
470 pub(crate) fn new(start: Span, end: Span) -> Self {
471 Self{start, end}
472 }
473}
474
475pub(crate) struct RepeatTimes<I> {
478 cloned: I,
479 iter: I,
480 times: usize,
481}
482
483impl<I> RepeatTimes<I>
484where
485 I: Iterator + Clone
486{
487 pub fn new(times: usize, iter: I) -> Self {
488 let cloned = iter.clone();
489 Self{cloned, iter, times}
490 }
491}
492
493impl<I> Iterator for RepeatTimes<I>
494where
495 I: Iterator + Clone
496{
497 type Item = I::Item;
498
499 fn next(&mut self) -> Option<I::Item> {
500 loop {
501 match self.iter.next() {
502 x @ Some(_) => return x,
503 None if self.times <= 1 => return None,
504 None => {
505 self.iter = self.cloned.clone();
506 self.times -= 1;
507 }
508 }
509 }
510 }
511}
512
513pub(crate) struct Error {
517 spans: Spans,
518 message: String,
519}
520
521impl Error {
522 #[allow(dead_code)]
523 pub(crate) fn new(start_span: Span, end_span: Span, message: &str) -> Self {
524 Self {
525 spans: Spans::new(start_span, end_span),
526 message: message.into(),
527 }
528 }
529
530 pub(crate) fn with_spans(spans: Spans, message: &str) -> Self {
531 Self {
532 spans,
533 message: message.into(),
534 }
535 }
536
537 pub(crate) fn one_tt(span: Span, message: &str) -> Self {
538 Self {
539 spans: Spans::new(span, span),
540 message: message.into(),
541 }
542 }
543
544 pub(crate) fn end(message_: &str) -> Self {
545 let mut message = "tokens ended before parsing finished, ".to_string();
546 message.push_str(message_);
547
548 Self {
549 spans: Spans::new(Span::call_site(), Span::call_site()),
550 message,
551 }
552 }
553
554 pub(crate) fn start_span(&self) -> Span {
555 self.spans.start
556 }
557 #[allow(dead_code)]
558 pub(crate) fn end_span(&self) -> Span {
559 self.spans.end
560 }
561
562 pub(crate) fn into_compile_error(self) -> TokenStream {
563 self.to_compile_error()
564 }
565 pub(crate) fn to_compile_error(&self) -> TokenStream {
566 let Error { ref message, spans: Spans{start: start_span, end: end_span} } = *self;
567
568 let mut out = TokenStream::new();
569
570 out_ident("compile_error", start_span, &mut out);
571
572 let mut bang = Punct::new('!', Spacing::Alone);
573 bang.set_span(start_span);
574 out.extend(once(TokenTree::Punct(bang)));
575
576 let mut msg = Literal::string(message);
577 msg.set_span(end_span);
578 let msg = TokenStream::from(TokenTree::from(msg));
579
580 let mut group = Group::new(Delimiter::Brace, msg);
581 group.set_span(end_span);
582 out.extend(once(TokenTree::Group(group)));
583
584 out
585 }
586}
587
588impl From<Error> for TokenStream {
589 fn from(err: Error) -> TokenStream {
590 err.into_compile_error()
591 }
592}
593
594
595