1fad3a1d3Sopenharmony_ci//! Parsing interface for parsing a token stream into a syntax tree node.
2fad3a1d3Sopenharmony_ci//!
3fad3a1d3Sopenharmony_ci//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]
4fad3a1d3Sopenharmony_ci//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying
5fad3a1d3Sopenharmony_ci//! these parser functions is a lower level mechanism built around the
6fad3a1d3Sopenharmony_ci//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
7fad3a1d3Sopenharmony_ci//! tokens in a token stream.
8fad3a1d3Sopenharmony_ci//!
9fad3a1d3Sopenharmony_ci//! [`Result<T>`]: Result
10fad3a1d3Sopenharmony_ci//! [`Cursor`]: crate::buffer::Cursor
11fad3a1d3Sopenharmony_ci//!
12fad3a1d3Sopenharmony_ci//! # Example
13fad3a1d3Sopenharmony_ci//!
14fad3a1d3Sopenharmony_ci//! Here is a snippet of parsing code to get a feel for the style of the
15fad3a1d3Sopenharmony_ci//! library. We define data structures for a subset of Rust syntax including
16fad3a1d3Sopenharmony_ci//! enums (not shown) and structs, then provide implementations of the [`Parse`]
17fad3a1d3Sopenharmony_ci//! trait to parse these syntax tree data structures from a token stream.
18fad3a1d3Sopenharmony_ci//!
19fad3a1d3Sopenharmony_ci//! Once `Parse` impls have been defined, they can be called conveniently from a
20fad3a1d3Sopenharmony_ci//! procedural macro through [`parse_macro_input!`] as shown at the bottom of
21fad3a1d3Sopenharmony_ci//! the snippet. If the caller provides syntactically invalid input to the
22fad3a1d3Sopenharmony_ci//! procedural macro, they will receive a helpful compiler error message
23fad3a1d3Sopenharmony_ci//! pointing out the exact token that triggered the failure to parse.
24fad3a1d3Sopenharmony_ci//!
25fad3a1d3Sopenharmony_ci//! [`parse_macro_input!`]: crate::parse_macro_input!
26fad3a1d3Sopenharmony_ci//!
27fad3a1d3Sopenharmony_ci//! ```
28fad3a1d3Sopenharmony_ci//! # extern crate proc_macro;
29fad3a1d3Sopenharmony_ci//! #
30fad3a1d3Sopenharmony_ci//! use proc_macro::TokenStream;
31fad3a1d3Sopenharmony_ci//! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token};
32fad3a1d3Sopenharmony_ci//! use syn::parse::{Parse, ParseStream};
33fad3a1d3Sopenharmony_ci//! use syn::punctuated::Punctuated;
34fad3a1d3Sopenharmony_ci//!
35fad3a1d3Sopenharmony_ci//! enum Item {
36fad3a1d3Sopenharmony_ci//!     Struct(ItemStruct),
37fad3a1d3Sopenharmony_ci//!     Enum(ItemEnum),
38fad3a1d3Sopenharmony_ci//! }
39fad3a1d3Sopenharmony_ci//!
40fad3a1d3Sopenharmony_ci//! struct ItemStruct {
41fad3a1d3Sopenharmony_ci//!     struct_token: Token![struct],
42fad3a1d3Sopenharmony_ci//!     ident: Ident,
43fad3a1d3Sopenharmony_ci//!     brace_token: token::Brace,
44fad3a1d3Sopenharmony_ci//!     fields: Punctuated<Field, Token![,]>,
45fad3a1d3Sopenharmony_ci//! }
46fad3a1d3Sopenharmony_ci//! #
47fad3a1d3Sopenharmony_ci//! # enum ItemEnum {}
48fad3a1d3Sopenharmony_ci//!
49fad3a1d3Sopenharmony_ci//! impl Parse for Item {
50fad3a1d3Sopenharmony_ci//!     fn parse(input: ParseStream) -> Result<Self> {
51fad3a1d3Sopenharmony_ci//!         let lookahead = input.lookahead1();
52fad3a1d3Sopenharmony_ci//!         if lookahead.peek(Token![struct]) {
53fad3a1d3Sopenharmony_ci//!             input.parse().map(Item::Struct)
54fad3a1d3Sopenharmony_ci//!         } else if lookahead.peek(Token![enum]) {
55fad3a1d3Sopenharmony_ci//!             input.parse().map(Item::Enum)
56fad3a1d3Sopenharmony_ci//!         } else {
57fad3a1d3Sopenharmony_ci//!             Err(lookahead.error())
58fad3a1d3Sopenharmony_ci//!         }
59fad3a1d3Sopenharmony_ci//!     }
60fad3a1d3Sopenharmony_ci//! }
61fad3a1d3Sopenharmony_ci//!
62fad3a1d3Sopenharmony_ci//! impl Parse for ItemStruct {
63fad3a1d3Sopenharmony_ci//!     fn parse(input: ParseStream) -> Result<Self> {
64fad3a1d3Sopenharmony_ci//!         let content;
65fad3a1d3Sopenharmony_ci//!         Ok(ItemStruct {
66fad3a1d3Sopenharmony_ci//!             struct_token: input.parse()?,
67fad3a1d3Sopenharmony_ci//!             ident: input.parse()?,
68fad3a1d3Sopenharmony_ci//!             brace_token: braced!(content in input),
69fad3a1d3Sopenharmony_ci//!             fields: content.parse_terminated(Field::parse_named, Token![,])?,
70fad3a1d3Sopenharmony_ci//!         })
71fad3a1d3Sopenharmony_ci//!     }
72fad3a1d3Sopenharmony_ci//! }
73fad3a1d3Sopenharmony_ci//! #
74fad3a1d3Sopenharmony_ci//! # impl Parse for ItemEnum {
75fad3a1d3Sopenharmony_ci//! #     fn parse(input: ParseStream) -> Result<Self> {
76fad3a1d3Sopenharmony_ci//! #         unimplemented!()
77fad3a1d3Sopenharmony_ci//! #     }
78fad3a1d3Sopenharmony_ci//! # }
79fad3a1d3Sopenharmony_ci//!
80fad3a1d3Sopenharmony_ci//! # const IGNORE: &str = stringify! {
81fad3a1d3Sopenharmony_ci//! #[proc_macro]
82fad3a1d3Sopenharmony_ci//! # };
83fad3a1d3Sopenharmony_ci//! pub fn my_macro(tokens: TokenStream) -> TokenStream {
84fad3a1d3Sopenharmony_ci//!     let input = parse_macro_input!(tokens as Item);
85fad3a1d3Sopenharmony_ci//!
86fad3a1d3Sopenharmony_ci//!     /* ... */
87fad3a1d3Sopenharmony_ci//! #   TokenStream::new()
88fad3a1d3Sopenharmony_ci//! }
89fad3a1d3Sopenharmony_ci//! ```
90fad3a1d3Sopenharmony_ci//!
91fad3a1d3Sopenharmony_ci//! # The `syn::parse*` functions
92fad3a1d3Sopenharmony_ci//!
93fad3a1d3Sopenharmony_ci//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve
94fad3a1d3Sopenharmony_ci//! as an entry point for parsing syntax tree nodes that can be parsed in an
95fad3a1d3Sopenharmony_ci//! obvious default way. These functions can return any syntax tree node that
96fad3a1d3Sopenharmony_ci//! implements the [`Parse`] trait, which includes most types in Syn.
97fad3a1d3Sopenharmony_ci//!
98fad3a1d3Sopenharmony_ci//! [`syn::parse`]: crate::parse()
99fad3a1d3Sopenharmony_ci//! [`syn::parse2`]: crate::parse2()
100fad3a1d3Sopenharmony_ci//! [`syn::parse_str`]: crate::parse_str()
101fad3a1d3Sopenharmony_ci//!
102fad3a1d3Sopenharmony_ci//! ```
103fad3a1d3Sopenharmony_ci//! use syn::Type;
104fad3a1d3Sopenharmony_ci//!
105fad3a1d3Sopenharmony_ci//! # fn run_parser() -> syn::Result<()> {
106fad3a1d3Sopenharmony_ci//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
107fad3a1d3Sopenharmony_ci//! #     Ok(())
108fad3a1d3Sopenharmony_ci//! # }
109fad3a1d3Sopenharmony_ci//! #
110fad3a1d3Sopenharmony_ci//! # run_parser().unwrap();
111fad3a1d3Sopenharmony_ci//! ```
112fad3a1d3Sopenharmony_ci//!
113fad3a1d3Sopenharmony_ci//! The [`parse_quote!`] macro also uses this approach.
114fad3a1d3Sopenharmony_ci//!
115fad3a1d3Sopenharmony_ci//! [`parse_quote!`]: crate::parse_quote!
116fad3a1d3Sopenharmony_ci//!
117fad3a1d3Sopenharmony_ci//! # The `Parser` trait
118fad3a1d3Sopenharmony_ci//!
119fad3a1d3Sopenharmony_ci//! Some types can be parsed in several ways depending on context. For example
120fad3a1d3Sopenharmony_ci//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like
121fad3a1d3Sopenharmony_ci//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]
122fad3a1d3Sopenharmony_ci//! may or may not allow trailing punctuation, and parsing it the wrong way
123fad3a1d3Sopenharmony_ci//! would either reject valid input or accept invalid input.
124fad3a1d3Sopenharmony_ci//!
125fad3a1d3Sopenharmony_ci//! [`Attribute`]: crate::Attribute
126fad3a1d3Sopenharmony_ci//! [`Punctuated`]: crate::punctuated
127fad3a1d3Sopenharmony_ci//!
128fad3a1d3Sopenharmony_ci//! The `Parse` trait is not implemented in these cases because there is no good
129fad3a1d3Sopenharmony_ci//! behavior to consider the default.
130fad3a1d3Sopenharmony_ci//!
131fad3a1d3Sopenharmony_ci//! ```compile_fail
132fad3a1d3Sopenharmony_ci//! # extern crate proc_macro;
133fad3a1d3Sopenharmony_ci//! #
134fad3a1d3Sopenharmony_ci//! # use syn::punctuated::Punctuated;
135fad3a1d3Sopenharmony_ci//! # use syn::{PathSegment, Result, Token};
136fad3a1d3Sopenharmony_ci//! #
137fad3a1d3Sopenharmony_ci//! # fn f(tokens: proc_macro::TokenStream) -> Result<()> {
138fad3a1d3Sopenharmony_ci//! #
139fad3a1d3Sopenharmony_ci//! // Can't parse `Punctuated` without knowing whether trailing punctuation
140fad3a1d3Sopenharmony_ci//! // should be allowed in this context.
141fad3a1d3Sopenharmony_ci//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;
142fad3a1d3Sopenharmony_ci//! #
143fad3a1d3Sopenharmony_ci//! #     Ok(())
144fad3a1d3Sopenharmony_ci//! # }
145fad3a1d3Sopenharmony_ci//! ```
146fad3a1d3Sopenharmony_ci//!
147fad3a1d3Sopenharmony_ci//! In these cases the types provide a choice of parser functions rather than a
148fad3a1d3Sopenharmony_ci//! single `Parse` implementation, and those parser functions can be invoked
149fad3a1d3Sopenharmony_ci//! through the [`Parser`] trait.
150fad3a1d3Sopenharmony_ci//!
151fad3a1d3Sopenharmony_ci//!
152fad3a1d3Sopenharmony_ci//! ```
153fad3a1d3Sopenharmony_ci//! # extern crate proc_macro;
154fad3a1d3Sopenharmony_ci//! #
155fad3a1d3Sopenharmony_ci//! use proc_macro::TokenStream;
156fad3a1d3Sopenharmony_ci//! use syn::parse::Parser;
157fad3a1d3Sopenharmony_ci//! use syn::punctuated::Punctuated;
158fad3a1d3Sopenharmony_ci//! use syn::{Attribute, Expr, PathSegment, Result, Token};
159fad3a1d3Sopenharmony_ci//!
160fad3a1d3Sopenharmony_ci//! fn call_some_parser_methods(input: TokenStream) -> Result<()> {
161fad3a1d3Sopenharmony_ci//!     // Parse a nonempty sequence of path segments separated by `::` punctuation
162fad3a1d3Sopenharmony_ci//!     // with no trailing punctuation.
163fad3a1d3Sopenharmony_ci//!     let tokens = input.clone();
164fad3a1d3Sopenharmony_ci//!     let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;
165fad3a1d3Sopenharmony_ci//!     let _path = parser.parse(tokens)?;
166fad3a1d3Sopenharmony_ci//!
167fad3a1d3Sopenharmony_ci//!     // Parse a possibly empty sequence of expressions terminated by commas with
168fad3a1d3Sopenharmony_ci//!     // an optional trailing punctuation.
169fad3a1d3Sopenharmony_ci//!     let tokens = input.clone();
170fad3a1d3Sopenharmony_ci//!     let parser = Punctuated::<Expr, Token![,]>::parse_terminated;
171fad3a1d3Sopenharmony_ci//!     let _args = parser.parse(tokens)?;
172fad3a1d3Sopenharmony_ci//!
173fad3a1d3Sopenharmony_ci//!     // Parse zero or more outer attributes but not inner attributes.
174fad3a1d3Sopenharmony_ci//!     let tokens = input.clone();
175fad3a1d3Sopenharmony_ci//!     let parser = Attribute::parse_outer;
176fad3a1d3Sopenharmony_ci//!     let _attrs = parser.parse(tokens)?;
177fad3a1d3Sopenharmony_ci//!
178fad3a1d3Sopenharmony_ci//!     Ok(())
179fad3a1d3Sopenharmony_ci//! }
180fad3a1d3Sopenharmony_ci//! ```
181fad3a1d3Sopenharmony_ci
182fad3a1d3Sopenharmony_ci#[path = "discouraged.rs"]
183fad3a1d3Sopenharmony_cipub mod discouraged;
184fad3a1d3Sopenharmony_ci
185fad3a1d3Sopenharmony_ciuse crate::buffer::{Cursor, TokenBuffer};
186fad3a1d3Sopenharmony_ciuse crate::error;
187fad3a1d3Sopenharmony_ciuse crate::lookahead;
188fad3a1d3Sopenharmony_ci#[cfg(feature = "proc-macro")]
189fad3a1d3Sopenharmony_ciuse crate::proc_macro;
190fad3a1d3Sopenharmony_ciuse crate::punctuated::Punctuated;
191fad3a1d3Sopenharmony_ciuse crate::token::Token;
192fad3a1d3Sopenharmony_ciuse proc_macro2::{self, Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
193fad3a1d3Sopenharmony_ciuse std::cell::Cell;
194fad3a1d3Sopenharmony_ciuse std::fmt::{self, Debug, Display};
195fad3a1d3Sopenharmony_ci#[cfg(feature = "extra-traits")]
196fad3a1d3Sopenharmony_ciuse std::hash::{Hash, Hasher};
197fad3a1d3Sopenharmony_ciuse std::marker::PhantomData;
198fad3a1d3Sopenharmony_ciuse std::mem;
199fad3a1d3Sopenharmony_ciuse std::ops::Deref;
200fad3a1d3Sopenharmony_ciuse std::rc::Rc;
201fad3a1d3Sopenharmony_ciuse std::str::FromStr;
202fad3a1d3Sopenharmony_ci
203fad3a1d3Sopenharmony_cipub use crate::error::{Error, Result};
204fad3a1d3Sopenharmony_cipub use crate::lookahead::{Lookahead1, Peek};
205fad3a1d3Sopenharmony_ci
206fad3a1d3Sopenharmony_ci/// Parsing interface implemented by all types that can be parsed in a default
207fad3a1d3Sopenharmony_ci/// way from a token stream.
208fad3a1d3Sopenharmony_ci///
209fad3a1d3Sopenharmony_ci/// Refer to the [module documentation] for details about implementing and using
210fad3a1d3Sopenharmony_ci/// the `Parse` trait.
211fad3a1d3Sopenharmony_ci///
212fad3a1d3Sopenharmony_ci/// [module documentation]: self
213fad3a1d3Sopenharmony_cipub trait Parse: Sized {
214fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self>;
215fad3a1d3Sopenharmony_ci}
216fad3a1d3Sopenharmony_ci
217fad3a1d3Sopenharmony_ci/// Input to a Syn parser function.
218fad3a1d3Sopenharmony_ci///
219fad3a1d3Sopenharmony_ci/// See the methods of this type under the documentation of [`ParseBuffer`]. For
220fad3a1d3Sopenharmony_ci/// an overview of parsing in Syn, refer to the [module documentation].
221fad3a1d3Sopenharmony_ci///
222fad3a1d3Sopenharmony_ci/// [module documentation]: self
223fad3a1d3Sopenharmony_cipub type ParseStream<'a> = &'a ParseBuffer<'a>;
224fad3a1d3Sopenharmony_ci
225fad3a1d3Sopenharmony_ci/// Cursor position within a buffered token stream.
226fad3a1d3Sopenharmony_ci///
227fad3a1d3Sopenharmony_ci/// This type is more commonly used through the type alias [`ParseStream`] which
228fad3a1d3Sopenharmony_ci/// is an alias for `&ParseBuffer`.
229fad3a1d3Sopenharmony_ci///
230fad3a1d3Sopenharmony_ci/// `ParseStream` is the input type for all parser functions in Syn. They have
231fad3a1d3Sopenharmony_ci/// the signature `fn(ParseStream) -> Result<T>`.
232fad3a1d3Sopenharmony_ci///
233fad3a1d3Sopenharmony_ci/// ## Calling a parser function
234fad3a1d3Sopenharmony_ci///
235fad3a1d3Sopenharmony_ci/// There is no public way to construct a `ParseBuffer`. Instead, if you are
236fad3a1d3Sopenharmony_ci/// looking to invoke a parser function that requires `ParseStream` as input,
237fad3a1d3Sopenharmony_ci/// you will need to go through one of the public parsing entry points.
238fad3a1d3Sopenharmony_ci///
239fad3a1d3Sopenharmony_ci/// - The [`parse_macro_input!`] macro if parsing input of a procedural macro;
240fad3a1d3Sopenharmony_ci/// - One of [the `syn::parse*` functions][syn-parse]; or
241fad3a1d3Sopenharmony_ci/// - A method of the [`Parser`] trait.
242fad3a1d3Sopenharmony_ci///
243fad3a1d3Sopenharmony_ci/// [`parse_macro_input!`]: crate::parse_macro_input!
244fad3a1d3Sopenharmony_ci/// [syn-parse]: self#the-synparse-functions
245fad3a1d3Sopenharmony_cipub struct ParseBuffer<'a> {
246fad3a1d3Sopenharmony_ci    scope: Span,
247fad3a1d3Sopenharmony_ci    // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.
248fad3a1d3Sopenharmony_ci    // The rest of the code in this module needs to be careful that only a
249fad3a1d3Sopenharmony_ci    // cursor derived from this `cell` is ever assigned to this `cell`.
250fad3a1d3Sopenharmony_ci    //
251fad3a1d3Sopenharmony_ci    // Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a
252fad3a1d3Sopenharmony_ci    // ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter
253fad3a1d3Sopenharmony_ci    // than 'a, and then assign a Cursor<'short> into the Cell.
254fad3a1d3Sopenharmony_ci    //
255fad3a1d3Sopenharmony_ci    // By extension, it would not be safe to expose an API that accepts a
256fad3a1d3Sopenharmony_ci    // Cursor<'a> and trusts that it lives as long as the cursor currently in
257fad3a1d3Sopenharmony_ci    // the cell.
258fad3a1d3Sopenharmony_ci    cell: Cell<Cursor<'static>>,
259fad3a1d3Sopenharmony_ci    marker: PhantomData<Cursor<'a>>,
260fad3a1d3Sopenharmony_ci    unexpected: Cell<Option<Rc<Cell<Unexpected>>>>,
261fad3a1d3Sopenharmony_ci}
262fad3a1d3Sopenharmony_ci
263fad3a1d3Sopenharmony_ciimpl<'a> Drop for ParseBuffer<'a> {
264fad3a1d3Sopenharmony_ci    fn drop(&mut self) {
265fad3a1d3Sopenharmony_ci        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(self.cursor()) {
266fad3a1d3Sopenharmony_ci            let (inner, old_span) = inner_unexpected(self);
267fad3a1d3Sopenharmony_ci            if old_span.is_none() {
268fad3a1d3Sopenharmony_ci                inner.set(Unexpected::Some(unexpected_span));
269fad3a1d3Sopenharmony_ci            }
270fad3a1d3Sopenharmony_ci        }
271fad3a1d3Sopenharmony_ci    }
272fad3a1d3Sopenharmony_ci}
273fad3a1d3Sopenharmony_ci
274fad3a1d3Sopenharmony_ciimpl<'a> Display for ParseBuffer<'a> {
275fad3a1d3Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
276fad3a1d3Sopenharmony_ci        Display::fmt(&self.cursor().token_stream(), f)
277fad3a1d3Sopenharmony_ci    }
278fad3a1d3Sopenharmony_ci}
279fad3a1d3Sopenharmony_ci
280fad3a1d3Sopenharmony_ciimpl<'a> Debug for ParseBuffer<'a> {
281fad3a1d3Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
282fad3a1d3Sopenharmony_ci        Debug::fmt(&self.cursor().token_stream(), f)
283fad3a1d3Sopenharmony_ci    }
284fad3a1d3Sopenharmony_ci}
285fad3a1d3Sopenharmony_ci
286fad3a1d3Sopenharmony_ci/// Cursor state associated with speculative parsing.
287fad3a1d3Sopenharmony_ci///
288fad3a1d3Sopenharmony_ci/// This type is the input of the closure provided to [`ParseStream::step`].
289fad3a1d3Sopenharmony_ci///
290fad3a1d3Sopenharmony_ci/// [`ParseStream::step`]: ParseBuffer::step
291fad3a1d3Sopenharmony_ci///
292fad3a1d3Sopenharmony_ci/// # Example
293fad3a1d3Sopenharmony_ci///
294fad3a1d3Sopenharmony_ci/// ```
295fad3a1d3Sopenharmony_ci/// use proc_macro2::TokenTree;
296fad3a1d3Sopenharmony_ci/// use syn::Result;
297fad3a1d3Sopenharmony_ci/// use syn::parse::ParseStream;
298fad3a1d3Sopenharmony_ci///
299fad3a1d3Sopenharmony_ci/// // This function advances the stream past the next occurrence of `@`. If
300fad3a1d3Sopenharmony_ci/// // no `@` is present in the stream, the stream position is unchanged and
301fad3a1d3Sopenharmony_ci/// // an error is returned.
302fad3a1d3Sopenharmony_ci/// fn skip_past_next_at(input: ParseStream) -> Result<()> {
303fad3a1d3Sopenharmony_ci///     input.step(|cursor| {
304fad3a1d3Sopenharmony_ci///         let mut rest = *cursor;
305fad3a1d3Sopenharmony_ci///         while let Some((tt, next)) = rest.token_tree() {
306fad3a1d3Sopenharmony_ci///             match &tt {
307fad3a1d3Sopenharmony_ci///                 TokenTree::Punct(punct) if punct.as_char() == '@' => {
308fad3a1d3Sopenharmony_ci///                     return Ok(((), next));
309fad3a1d3Sopenharmony_ci///                 }
310fad3a1d3Sopenharmony_ci///                 _ => rest = next,
311fad3a1d3Sopenharmony_ci///             }
312fad3a1d3Sopenharmony_ci///         }
313fad3a1d3Sopenharmony_ci///         Err(cursor.error("no `@` was found after this point"))
314fad3a1d3Sopenharmony_ci///     })
315fad3a1d3Sopenharmony_ci/// }
316fad3a1d3Sopenharmony_ci/// #
317fad3a1d3Sopenharmony_ci/// # fn remainder_after_skipping_past_next_at(
318fad3a1d3Sopenharmony_ci/// #     input: ParseStream,
319fad3a1d3Sopenharmony_ci/// # ) -> Result<proc_macro2::TokenStream> {
320fad3a1d3Sopenharmony_ci/// #     skip_past_next_at(input)?;
321fad3a1d3Sopenharmony_ci/// #     input.parse()
322fad3a1d3Sopenharmony_ci/// # }
323fad3a1d3Sopenharmony_ci/// #
324fad3a1d3Sopenharmony_ci/// # use syn::parse::Parser;
325fad3a1d3Sopenharmony_ci/// # let remainder = remainder_after_skipping_past_next_at
326fad3a1d3Sopenharmony_ci/// #     .parse_str("a @ b c")
327fad3a1d3Sopenharmony_ci/// #     .unwrap();
328fad3a1d3Sopenharmony_ci/// # assert_eq!(remainder.to_string(), "b c");
329fad3a1d3Sopenharmony_ci/// ```
330fad3a1d3Sopenharmony_cipub struct StepCursor<'c, 'a> {
331fad3a1d3Sopenharmony_ci    scope: Span,
332fad3a1d3Sopenharmony_ci    // This field is covariant in 'c.
333fad3a1d3Sopenharmony_ci    cursor: Cursor<'c>,
334fad3a1d3Sopenharmony_ci    // This field is contravariant in 'c. Together these make StepCursor
335fad3a1d3Sopenharmony_ci    // invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a
336fad3a1d3Sopenharmony_ci    // different lifetime but can upcast into a StepCursor with a shorter
337fad3a1d3Sopenharmony_ci    // lifetime 'a.
338fad3a1d3Sopenharmony_ci    //
339fad3a1d3Sopenharmony_ci    // As long as we only ever construct a StepCursor for which 'c outlives 'a,
340fad3a1d3Sopenharmony_ci    // this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c
341fad3a1d3Sopenharmony_ci    // outlives 'a.
342fad3a1d3Sopenharmony_ci    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
343fad3a1d3Sopenharmony_ci}
344fad3a1d3Sopenharmony_ci
345fad3a1d3Sopenharmony_ciimpl<'c, 'a> Deref for StepCursor<'c, 'a> {
346fad3a1d3Sopenharmony_ci    type Target = Cursor<'c>;
347fad3a1d3Sopenharmony_ci
348fad3a1d3Sopenharmony_ci    fn deref(&self) -> &Self::Target {
349fad3a1d3Sopenharmony_ci        &self.cursor
350fad3a1d3Sopenharmony_ci    }
351fad3a1d3Sopenharmony_ci}
352fad3a1d3Sopenharmony_ci
353fad3a1d3Sopenharmony_ciimpl<'c, 'a> Copy for StepCursor<'c, 'a> {}
354fad3a1d3Sopenharmony_ci
355fad3a1d3Sopenharmony_ciimpl<'c, 'a> Clone for StepCursor<'c, 'a> {
356fad3a1d3Sopenharmony_ci    fn clone(&self) -> Self {
357fad3a1d3Sopenharmony_ci        *self
358fad3a1d3Sopenharmony_ci    }
359fad3a1d3Sopenharmony_ci}
360fad3a1d3Sopenharmony_ci
361fad3a1d3Sopenharmony_ciimpl<'c, 'a> StepCursor<'c, 'a> {
362fad3a1d3Sopenharmony_ci    /// Triggers an error at the current position of the parse stream.
363fad3a1d3Sopenharmony_ci    ///
364fad3a1d3Sopenharmony_ci    /// The `ParseStream::step` invocation will return this same error without
365fad3a1d3Sopenharmony_ci    /// advancing the stream state.
366fad3a1d3Sopenharmony_ci    pub fn error<T: Display>(self, message: T) -> Error {
367fad3a1d3Sopenharmony_ci        error::new_at(self.scope, self.cursor, message)
368fad3a1d3Sopenharmony_ci    }
369fad3a1d3Sopenharmony_ci}
370fad3a1d3Sopenharmony_ci
371fad3a1d3Sopenharmony_cipub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> {
372fad3a1d3Sopenharmony_ci    // Refer to the comments within the StepCursor definition. We use the
373fad3a1d3Sopenharmony_ci    // fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a.
374fad3a1d3Sopenharmony_ci    // Cursor is covariant in its lifetime parameter so we can cast a
375fad3a1d3Sopenharmony_ci    // Cursor<'c> to one with the shorter lifetime Cursor<'a>.
376fad3a1d3Sopenharmony_ci    let _ = proof;
377fad3a1d3Sopenharmony_ci    unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }
378fad3a1d3Sopenharmony_ci}
379fad3a1d3Sopenharmony_ci
380fad3a1d3Sopenharmony_cipub(crate) fn new_parse_buffer(
381fad3a1d3Sopenharmony_ci    scope: Span,
382fad3a1d3Sopenharmony_ci    cursor: Cursor,
383fad3a1d3Sopenharmony_ci    unexpected: Rc<Cell<Unexpected>>,
384fad3a1d3Sopenharmony_ci) -> ParseBuffer {
385fad3a1d3Sopenharmony_ci    ParseBuffer {
386fad3a1d3Sopenharmony_ci        scope,
387fad3a1d3Sopenharmony_ci        // See comment on `cell` in the struct definition.
388fad3a1d3Sopenharmony_ci        cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }),
389fad3a1d3Sopenharmony_ci        marker: PhantomData,
390fad3a1d3Sopenharmony_ci        unexpected: Cell::new(Some(unexpected)),
391fad3a1d3Sopenharmony_ci    }
392fad3a1d3Sopenharmony_ci}
393fad3a1d3Sopenharmony_ci
394fad3a1d3Sopenharmony_cipub(crate) enum Unexpected {
395fad3a1d3Sopenharmony_ci    None,
396fad3a1d3Sopenharmony_ci    Some(Span),
397fad3a1d3Sopenharmony_ci    Chain(Rc<Cell<Unexpected>>),
398fad3a1d3Sopenharmony_ci}
399fad3a1d3Sopenharmony_ci
400fad3a1d3Sopenharmony_ciimpl Default for Unexpected {
401fad3a1d3Sopenharmony_ci    fn default() -> Self {
402fad3a1d3Sopenharmony_ci        Unexpected::None
403fad3a1d3Sopenharmony_ci    }
404fad3a1d3Sopenharmony_ci}
405fad3a1d3Sopenharmony_ci
406fad3a1d3Sopenharmony_ciimpl Clone for Unexpected {
407fad3a1d3Sopenharmony_ci    fn clone(&self) -> Self {
408fad3a1d3Sopenharmony_ci        match self {
409fad3a1d3Sopenharmony_ci            Unexpected::None => Unexpected::None,
410fad3a1d3Sopenharmony_ci            Unexpected::Some(span) => Unexpected::Some(*span),
411fad3a1d3Sopenharmony_ci            Unexpected::Chain(next) => Unexpected::Chain(next.clone()),
412fad3a1d3Sopenharmony_ci        }
413fad3a1d3Sopenharmony_ci    }
414fad3a1d3Sopenharmony_ci}
415fad3a1d3Sopenharmony_ci
416fad3a1d3Sopenharmony_ci// We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily
417fad3a1d3Sopenharmony_ci// swapping in a None is cheap.
418fad3a1d3Sopenharmony_cifn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T {
419fad3a1d3Sopenharmony_ci    let prev = cell.take();
420fad3a1d3Sopenharmony_ci    let ret = prev.clone();
421fad3a1d3Sopenharmony_ci    cell.set(prev);
422fad3a1d3Sopenharmony_ci    ret
423fad3a1d3Sopenharmony_ci}
424fad3a1d3Sopenharmony_ci
425fad3a1d3Sopenharmony_cifn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<Span>) {
426fad3a1d3Sopenharmony_ci    let mut unexpected = get_unexpected(buffer);
427fad3a1d3Sopenharmony_ci    loop {
428fad3a1d3Sopenharmony_ci        match cell_clone(&unexpected) {
429fad3a1d3Sopenharmony_ci            Unexpected::None => return (unexpected, None),
430fad3a1d3Sopenharmony_ci            Unexpected::Some(span) => return (unexpected, Some(span)),
431fad3a1d3Sopenharmony_ci            Unexpected::Chain(next) => unexpected = next,
432fad3a1d3Sopenharmony_ci        }
433fad3a1d3Sopenharmony_ci    }
434fad3a1d3Sopenharmony_ci}
435fad3a1d3Sopenharmony_ci
436fad3a1d3Sopenharmony_cipub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> {
437fad3a1d3Sopenharmony_ci    cell_clone(&buffer.unexpected).unwrap()
438fad3a1d3Sopenharmony_ci}
439fad3a1d3Sopenharmony_ci
440fad3a1d3Sopenharmony_cifn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<Span> {
441fad3a1d3Sopenharmony_ci    if cursor.eof() {
442fad3a1d3Sopenharmony_ci        return None;
443fad3a1d3Sopenharmony_ci    }
444fad3a1d3Sopenharmony_ci    while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) {
445fad3a1d3Sopenharmony_ci        if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) {
446fad3a1d3Sopenharmony_ci            return Some(unexpected);
447fad3a1d3Sopenharmony_ci        }
448fad3a1d3Sopenharmony_ci        cursor = rest;
449fad3a1d3Sopenharmony_ci    }
450fad3a1d3Sopenharmony_ci    if cursor.eof() {
451fad3a1d3Sopenharmony_ci        None
452fad3a1d3Sopenharmony_ci    } else {
453fad3a1d3Sopenharmony_ci        Some(cursor.span())
454fad3a1d3Sopenharmony_ci    }
455fad3a1d3Sopenharmony_ci}
456fad3a1d3Sopenharmony_ci
457fad3a1d3Sopenharmony_ciimpl<'a> ParseBuffer<'a> {
458fad3a1d3Sopenharmony_ci    /// Parses a syntax tree node of type `T`, advancing the position of our
459fad3a1d3Sopenharmony_ci    /// parse stream past it.
460fad3a1d3Sopenharmony_ci    pub fn parse<T: Parse>(&self) -> Result<T> {
461fad3a1d3Sopenharmony_ci        T::parse(self)
462fad3a1d3Sopenharmony_ci    }
463fad3a1d3Sopenharmony_ci
464fad3a1d3Sopenharmony_ci    /// Calls the given parser function to parse a syntax tree node of type `T`
465fad3a1d3Sopenharmony_ci    /// from this stream.
466fad3a1d3Sopenharmony_ci    ///
467fad3a1d3Sopenharmony_ci    /// # Example
468fad3a1d3Sopenharmony_ci    ///
469fad3a1d3Sopenharmony_ci    /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of
470fad3a1d3Sopenharmony_ci    /// zero or more outer attributes.
471fad3a1d3Sopenharmony_ci    ///
472fad3a1d3Sopenharmony_ci    /// [`Attribute::parse_outer`]: crate::Attribute::parse_outer
473fad3a1d3Sopenharmony_ci    ///
474fad3a1d3Sopenharmony_ci    /// ```
475fad3a1d3Sopenharmony_ci    /// use syn::{Attribute, Ident, Result, Token};
476fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
477fad3a1d3Sopenharmony_ci    ///
478fad3a1d3Sopenharmony_ci    /// // Parses a unit struct with attributes.
479fad3a1d3Sopenharmony_ci    /// //
480fad3a1d3Sopenharmony_ci    /// //     #[path = "s.tmpl"]
481fad3a1d3Sopenharmony_ci    /// //     struct S;
482fad3a1d3Sopenharmony_ci    /// struct UnitStruct {
483fad3a1d3Sopenharmony_ci    ///     attrs: Vec<Attribute>,
484fad3a1d3Sopenharmony_ci    ///     struct_token: Token![struct],
485fad3a1d3Sopenharmony_ci    ///     name: Ident,
486fad3a1d3Sopenharmony_ci    ///     semi_token: Token![;],
487fad3a1d3Sopenharmony_ci    /// }
488fad3a1d3Sopenharmony_ci    ///
489fad3a1d3Sopenharmony_ci    /// impl Parse for UnitStruct {
490fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
491fad3a1d3Sopenharmony_ci    ///         Ok(UnitStruct {
492fad3a1d3Sopenharmony_ci    ///             attrs: input.call(Attribute::parse_outer)?,
493fad3a1d3Sopenharmony_ci    ///             struct_token: input.parse()?,
494fad3a1d3Sopenharmony_ci    ///             name: input.parse()?,
495fad3a1d3Sopenharmony_ci    ///             semi_token: input.parse()?,
496fad3a1d3Sopenharmony_ci    ///         })
497fad3a1d3Sopenharmony_ci    ///     }
498fad3a1d3Sopenharmony_ci    /// }
499fad3a1d3Sopenharmony_ci    /// ```
500fad3a1d3Sopenharmony_ci    pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
501fad3a1d3Sopenharmony_ci        function(self)
502fad3a1d3Sopenharmony_ci    }
503fad3a1d3Sopenharmony_ci
504fad3a1d3Sopenharmony_ci    /// Looks at the next token in the parse stream to determine whether it
505fad3a1d3Sopenharmony_ci    /// matches the requested type of token.
506fad3a1d3Sopenharmony_ci    ///
507fad3a1d3Sopenharmony_ci    /// Does not advance the position of the parse stream.
508fad3a1d3Sopenharmony_ci    ///
509fad3a1d3Sopenharmony_ci    /// # Syntax
510fad3a1d3Sopenharmony_ci    ///
511fad3a1d3Sopenharmony_ci    /// Note that this method does not use turbofish syntax. Pass the peek type
512fad3a1d3Sopenharmony_ci    /// inside of parentheses.
513fad3a1d3Sopenharmony_ci    ///
514fad3a1d3Sopenharmony_ci    /// - `input.peek(Token![struct])`
515fad3a1d3Sopenharmony_ci    /// - `input.peek(Token![==])`
516fad3a1d3Sopenharmony_ci    /// - `input.peek(syn::Ident)`&emsp;*(does not accept keywords)*
517fad3a1d3Sopenharmony_ci    /// - `input.peek(syn::Ident::peek_any)`
518fad3a1d3Sopenharmony_ci    /// - `input.peek(Lifetime)`
519fad3a1d3Sopenharmony_ci    /// - `input.peek(token::Brace)`
520fad3a1d3Sopenharmony_ci    ///
521fad3a1d3Sopenharmony_ci    /// # Example
522fad3a1d3Sopenharmony_ci    ///
523fad3a1d3Sopenharmony_ci    /// In this example we finish parsing the list of supertraits when the next
524fad3a1d3Sopenharmony_ci    /// token in the input is either `where` or an opening curly brace.
525fad3a1d3Sopenharmony_ci    ///
526fad3a1d3Sopenharmony_ci    /// ```
527fad3a1d3Sopenharmony_ci    /// use syn::{braced, token, Generics, Ident, Result, Token, TypeParamBound};
528fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
529fad3a1d3Sopenharmony_ci    /// use syn::punctuated::Punctuated;
530fad3a1d3Sopenharmony_ci    ///
531fad3a1d3Sopenharmony_ci    /// // Parses a trait definition containing no associated items.
532fad3a1d3Sopenharmony_ci    /// //
533fad3a1d3Sopenharmony_ci    /// //     trait Marker<'de, T>: A + B<'de> where Box<T>: Clone {}
534fad3a1d3Sopenharmony_ci    /// struct MarkerTrait {
535fad3a1d3Sopenharmony_ci    ///     trait_token: Token![trait],
536fad3a1d3Sopenharmony_ci    ///     ident: Ident,
537fad3a1d3Sopenharmony_ci    ///     generics: Generics,
538fad3a1d3Sopenharmony_ci    ///     colon_token: Option<Token![:]>,
539fad3a1d3Sopenharmony_ci    ///     supertraits: Punctuated<TypeParamBound, Token![+]>,
540fad3a1d3Sopenharmony_ci    ///     brace_token: token::Brace,
541fad3a1d3Sopenharmony_ci    /// }
542fad3a1d3Sopenharmony_ci    ///
543fad3a1d3Sopenharmony_ci    /// impl Parse for MarkerTrait {
544fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
545fad3a1d3Sopenharmony_ci    ///         let trait_token: Token![trait] = input.parse()?;
546fad3a1d3Sopenharmony_ci    ///         let ident: Ident = input.parse()?;
547fad3a1d3Sopenharmony_ci    ///         let mut generics: Generics = input.parse()?;
548fad3a1d3Sopenharmony_ci    ///         let colon_token: Option<Token![:]> = input.parse()?;
549fad3a1d3Sopenharmony_ci    ///
550fad3a1d3Sopenharmony_ci    ///         let mut supertraits = Punctuated::new();
551fad3a1d3Sopenharmony_ci    ///         if colon_token.is_some() {
552fad3a1d3Sopenharmony_ci    ///             loop {
553fad3a1d3Sopenharmony_ci    ///                 supertraits.push_value(input.parse()?);
554fad3a1d3Sopenharmony_ci    ///                 if input.peek(Token![where]) || input.peek(token::Brace) {
555fad3a1d3Sopenharmony_ci    ///                     break;
556fad3a1d3Sopenharmony_ci    ///                 }
557fad3a1d3Sopenharmony_ci    ///                 supertraits.push_punct(input.parse()?);
558fad3a1d3Sopenharmony_ci    ///             }
559fad3a1d3Sopenharmony_ci    ///         }
560fad3a1d3Sopenharmony_ci    ///
561fad3a1d3Sopenharmony_ci    ///         generics.where_clause = input.parse()?;
562fad3a1d3Sopenharmony_ci    ///         let content;
563fad3a1d3Sopenharmony_ci    ///         let empty_brace_token = braced!(content in input);
564fad3a1d3Sopenharmony_ci    ///
565fad3a1d3Sopenharmony_ci    ///         Ok(MarkerTrait {
566fad3a1d3Sopenharmony_ci    ///             trait_token,
567fad3a1d3Sopenharmony_ci    ///             ident,
568fad3a1d3Sopenharmony_ci    ///             generics,
569fad3a1d3Sopenharmony_ci    ///             colon_token,
570fad3a1d3Sopenharmony_ci    ///             supertraits,
571fad3a1d3Sopenharmony_ci    ///             brace_token: empty_brace_token,
572fad3a1d3Sopenharmony_ci    ///         })
573fad3a1d3Sopenharmony_ci    ///     }
574fad3a1d3Sopenharmony_ci    /// }
575fad3a1d3Sopenharmony_ci    /// ```
576fad3a1d3Sopenharmony_ci    pub fn peek<T: Peek>(&self, token: T) -> bool {
577fad3a1d3Sopenharmony_ci        let _ = token;
578fad3a1d3Sopenharmony_ci        T::Token::peek(self.cursor())
579fad3a1d3Sopenharmony_ci    }
580fad3a1d3Sopenharmony_ci
581fad3a1d3Sopenharmony_ci    /// Looks at the second-next token in the parse stream.
582fad3a1d3Sopenharmony_ci    ///
583fad3a1d3Sopenharmony_ci    /// This is commonly useful as a way to implement contextual keywords.
584fad3a1d3Sopenharmony_ci    ///
585fad3a1d3Sopenharmony_ci    /// # Example
586fad3a1d3Sopenharmony_ci    ///
587fad3a1d3Sopenharmony_ci    /// This example needs to use `peek2` because the symbol `union` is not a
588fad3a1d3Sopenharmony_ci    /// keyword in Rust. We can't use just `peek` and decide to parse a union if
589fad3a1d3Sopenharmony_ci    /// the very next token is `union`, because someone is free to write a `mod
590fad3a1d3Sopenharmony_ci    /// union` and a macro invocation that looks like `union::some_macro! { ...
591fad3a1d3Sopenharmony_ci    /// }`. In other words `union` is a contextual keyword.
592fad3a1d3Sopenharmony_ci    ///
593fad3a1d3Sopenharmony_ci    /// ```
594fad3a1d3Sopenharmony_ci    /// use syn::{Ident, ItemUnion, Macro, Result, Token};
595fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
596fad3a1d3Sopenharmony_ci    ///
597fad3a1d3Sopenharmony_ci    /// // Parses either a union or a macro invocation.
598fad3a1d3Sopenharmony_ci    /// enum UnionOrMacro {
599fad3a1d3Sopenharmony_ci    ///     // union MaybeUninit<T> { uninit: (), value: T }
600fad3a1d3Sopenharmony_ci    ///     Union(ItemUnion),
601fad3a1d3Sopenharmony_ci    ///     // lazy_static! { ... }
602fad3a1d3Sopenharmony_ci    ///     Macro(Macro),
603fad3a1d3Sopenharmony_ci    /// }
604fad3a1d3Sopenharmony_ci    ///
605fad3a1d3Sopenharmony_ci    /// impl Parse for UnionOrMacro {
606fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
607fad3a1d3Sopenharmony_ci    ///         if input.peek(Token![union]) && input.peek2(Ident) {
608fad3a1d3Sopenharmony_ci    ///             input.parse().map(UnionOrMacro::Union)
609fad3a1d3Sopenharmony_ci    ///         } else {
610fad3a1d3Sopenharmony_ci    ///             input.parse().map(UnionOrMacro::Macro)
611fad3a1d3Sopenharmony_ci    ///         }
612fad3a1d3Sopenharmony_ci    ///     }
613fad3a1d3Sopenharmony_ci    /// }
614fad3a1d3Sopenharmony_ci    /// ```
615fad3a1d3Sopenharmony_ci    pub fn peek2<T: Peek>(&self, token: T) -> bool {
616fad3a1d3Sopenharmony_ci        fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
617fad3a1d3Sopenharmony_ci            if let Some(group) = buffer.cursor().group(Delimiter::None) {
618fad3a1d3Sopenharmony_ci                if group.0.skip().map_or(false, peek) {
619fad3a1d3Sopenharmony_ci                    return true;
620fad3a1d3Sopenharmony_ci                }
621fad3a1d3Sopenharmony_ci            }
622fad3a1d3Sopenharmony_ci            buffer.cursor().skip().map_or(false, peek)
623fad3a1d3Sopenharmony_ci        }
624fad3a1d3Sopenharmony_ci
625fad3a1d3Sopenharmony_ci        let _ = token;
626fad3a1d3Sopenharmony_ci        peek2(self, T::Token::peek)
627fad3a1d3Sopenharmony_ci    }
628fad3a1d3Sopenharmony_ci
629fad3a1d3Sopenharmony_ci    /// Looks at the third-next token in the parse stream.
630fad3a1d3Sopenharmony_ci    pub fn peek3<T: Peek>(&self, token: T) -> bool {
631fad3a1d3Sopenharmony_ci        fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
632fad3a1d3Sopenharmony_ci            if let Some(group) = buffer.cursor().group(Delimiter::None) {
633fad3a1d3Sopenharmony_ci                if group.0.skip().and_then(Cursor::skip).map_or(false, peek) {
634fad3a1d3Sopenharmony_ci                    return true;
635fad3a1d3Sopenharmony_ci                }
636fad3a1d3Sopenharmony_ci            }
637fad3a1d3Sopenharmony_ci            buffer
638fad3a1d3Sopenharmony_ci                .cursor()
639fad3a1d3Sopenharmony_ci                .skip()
640fad3a1d3Sopenharmony_ci                .and_then(Cursor::skip)
641fad3a1d3Sopenharmony_ci                .map_or(false, peek)
642fad3a1d3Sopenharmony_ci        }
643fad3a1d3Sopenharmony_ci
644fad3a1d3Sopenharmony_ci        let _ = token;
645fad3a1d3Sopenharmony_ci        peek3(self, T::Token::peek)
646fad3a1d3Sopenharmony_ci    }
647fad3a1d3Sopenharmony_ci
648fad3a1d3Sopenharmony_ci    /// Parses zero or more occurrences of `T` separated by punctuation of type
649fad3a1d3Sopenharmony_ci    /// `P`, with optional trailing punctuation.
650fad3a1d3Sopenharmony_ci    ///
651fad3a1d3Sopenharmony_ci    /// Parsing continues until the end of this parse stream. The entire content
652fad3a1d3Sopenharmony_ci    /// of this parse stream must consist of `T` and `P`.
653fad3a1d3Sopenharmony_ci    ///
654fad3a1d3Sopenharmony_ci    /// # Example
655fad3a1d3Sopenharmony_ci    ///
656fad3a1d3Sopenharmony_ci    /// ```
657fad3a1d3Sopenharmony_ci    /// # use quote::quote;
658fad3a1d3Sopenharmony_ci    /// #
659fad3a1d3Sopenharmony_ci    /// use syn::{parenthesized, token, Ident, Result, Token, Type};
660fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
661fad3a1d3Sopenharmony_ci    /// use syn::punctuated::Punctuated;
662fad3a1d3Sopenharmony_ci    ///
663fad3a1d3Sopenharmony_ci    /// // Parse a simplified tuple struct syntax like:
664fad3a1d3Sopenharmony_ci    /// //
665fad3a1d3Sopenharmony_ci    /// //     struct S(A, B);
666fad3a1d3Sopenharmony_ci    /// struct TupleStruct {
667fad3a1d3Sopenharmony_ci    ///     struct_token: Token![struct],
668fad3a1d3Sopenharmony_ci    ///     ident: Ident,
669fad3a1d3Sopenharmony_ci    ///     paren_token: token::Paren,
670fad3a1d3Sopenharmony_ci    ///     fields: Punctuated<Type, Token![,]>,
671fad3a1d3Sopenharmony_ci    ///     semi_token: Token![;],
672fad3a1d3Sopenharmony_ci    /// }
673fad3a1d3Sopenharmony_ci    ///
674fad3a1d3Sopenharmony_ci    /// impl Parse for TupleStruct {
675fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
676fad3a1d3Sopenharmony_ci    ///         let content;
677fad3a1d3Sopenharmony_ci    ///         Ok(TupleStruct {
678fad3a1d3Sopenharmony_ci    ///             struct_token: input.parse()?,
679fad3a1d3Sopenharmony_ci    ///             ident: input.parse()?,
680fad3a1d3Sopenharmony_ci    ///             paren_token: parenthesized!(content in input),
681fad3a1d3Sopenharmony_ci    ///             fields: content.parse_terminated(Type::parse, Token![,])?,
682fad3a1d3Sopenharmony_ci    ///             semi_token: input.parse()?,
683fad3a1d3Sopenharmony_ci    ///         })
684fad3a1d3Sopenharmony_ci    ///     }
685fad3a1d3Sopenharmony_ci    /// }
686fad3a1d3Sopenharmony_ci    /// #
687fad3a1d3Sopenharmony_ci    /// # let input = quote! {
688fad3a1d3Sopenharmony_ci    /// #     struct S(A, B);
689fad3a1d3Sopenharmony_ci    /// # };
690fad3a1d3Sopenharmony_ci    /// # syn::parse2::<TupleStruct>(input).unwrap();
691fad3a1d3Sopenharmony_ci    /// ```
692fad3a1d3Sopenharmony_ci    ///
693fad3a1d3Sopenharmony_ci    /// # See also
694fad3a1d3Sopenharmony_ci    ///
695fad3a1d3Sopenharmony_ci    /// If your separator is anything more complicated than an invocation of the
696fad3a1d3Sopenharmony_ci    /// `Token!` macro, this method won't be applicable and you can instead
697fad3a1d3Sopenharmony_ci    /// directly use `Punctuated`'s parser functions: [`parse_terminated`],
698fad3a1d3Sopenharmony_ci    /// [`parse_separated_nonempty`] etc.
699fad3a1d3Sopenharmony_ci    ///
700fad3a1d3Sopenharmony_ci    /// [`parse_terminated`]: Punctuated::parse_terminated
701fad3a1d3Sopenharmony_ci    /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
702fad3a1d3Sopenharmony_ci    ///
703fad3a1d3Sopenharmony_ci    /// ```
704fad3a1d3Sopenharmony_ci    /// use syn::{custom_keyword, Expr, Result, Token};
705fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
706fad3a1d3Sopenharmony_ci    /// use syn::punctuated::Punctuated;
707fad3a1d3Sopenharmony_ci    ///
708fad3a1d3Sopenharmony_ci    /// mod kw {
709fad3a1d3Sopenharmony_ci    ///     syn::custom_keyword!(fin);
710fad3a1d3Sopenharmony_ci    /// }
711fad3a1d3Sopenharmony_ci    ///
712fad3a1d3Sopenharmony_ci    /// struct Fin(kw::fin, Token![;]);
713fad3a1d3Sopenharmony_ci    ///
714fad3a1d3Sopenharmony_ci    /// impl Parse for Fin {
715fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
716fad3a1d3Sopenharmony_ci    ///         Ok(Self(input.parse()?, input.parse()?))
717fad3a1d3Sopenharmony_ci    ///     }
718fad3a1d3Sopenharmony_ci    /// }
719fad3a1d3Sopenharmony_ci    ///
720fad3a1d3Sopenharmony_ci    /// struct Thing {
721fad3a1d3Sopenharmony_ci    ///     steps: Punctuated<Expr, Fin>,
722fad3a1d3Sopenharmony_ci    /// }
723fad3a1d3Sopenharmony_ci    ///
724fad3a1d3Sopenharmony_ci    /// impl Parse for Thing {
725fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
726fad3a1d3Sopenharmony_ci    /// # if true {
727fad3a1d3Sopenharmony_ci    ///         Ok(Thing {
728fad3a1d3Sopenharmony_ci    ///             steps: Punctuated::parse_terminated(input)?,
729fad3a1d3Sopenharmony_ci    ///         })
730fad3a1d3Sopenharmony_ci    /// # } else {
731fad3a1d3Sopenharmony_ci    ///         // or equivalently, this means the same thing:
732fad3a1d3Sopenharmony_ci    /// #       Ok(Thing {
733fad3a1d3Sopenharmony_ci    ///             steps: input.call(Punctuated::parse_terminated)?,
734fad3a1d3Sopenharmony_ci    /// #       })
735fad3a1d3Sopenharmony_ci    /// # }
736fad3a1d3Sopenharmony_ci    ///     }
737fad3a1d3Sopenharmony_ci    /// }
738fad3a1d3Sopenharmony_ci    /// ```
739fad3a1d3Sopenharmony_ci    pub fn parse_terminated<T, P>(
740fad3a1d3Sopenharmony_ci        &self,
741fad3a1d3Sopenharmony_ci        parser: fn(ParseStream) -> Result<T>,
742fad3a1d3Sopenharmony_ci        separator: P,
743fad3a1d3Sopenharmony_ci    ) -> Result<Punctuated<T, P::Token>>
744fad3a1d3Sopenharmony_ci    where
745fad3a1d3Sopenharmony_ci        P: Peek,
746fad3a1d3Sopenharmony_ci        P::Token: Parse,
747fad3a1d3Sopenharmony_ci    {
748fad3a1d3Sopenharmony_ci        let _ = separator;
749fad3a1d3Sopenharmony_ci        Punctuated::parse_terminated_with(self, parser)
750fad3a1d3Sopenharmony_ci    }
751fad3a1d3Sopenharmony_ci
752fad3a1d3Sopenharmony_ci    /// Returns whether there are tokens remaining in this stream.
753fad3a1d3Sopenharmony_ci    ///
754fad3a1d3Sopenharmony_ci    /// This method returns true at the end of the content of a set of
755fad3a1d3Sopenharmony_ci    /// delimiters, as well as at the very end of the complete macro input.
756fad3a1d3Sopenharmony_ci    ///
757fad3a1d3Sopenharmony_ci    /// # Example
758fad3a1d3Sopenharmony_ci    ///
759fad3a1d3Sopenharmony_ci    /// ```
760fad3a1d3Sopenharmony_ci    /// use syn::{braced, token, Ident, Item, Result, Token};
761fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
762fad3a1d3Sopenharmony_ci    ///
763fad3a1d3Sopenharmony_ci    /// // Parses a Rust `mod m { ... }` containing zero or more items.
764fad3a1d3Sopenharmony_ci    /// struct Mod {
765fad3a1d3Sopenharmony_ci    ///     mod_token: Token![mod],
766fad3a1d3Sopenharmony_ci    ///     name: Ident,
767fad3a1d3Sopenharmony_ci    ///     brace_token: token::Brace,
768fad3a1d3Sopenharmony_ci    ///     items: Vec<Item>,
769fad3a1d3Sopenharmony_ci    /// }
770fad3a1d3Sopenharmony_ci    ///
771fad3a1d3Sopenharmony_ci    /// impl Parse for Mod {
772fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
773fad3a1d3Sopenharmony_ci    ///         let content;
774fad3a1d3Sopenharmony_ci    ///         Ok(Mod {
775fad3a1d3Sopenharmony_ci    ///             mod_token: input.parse()?,
776fad3a1d3Sopenharmony_ci    ///             name: input.parse()?,
777fad3a1d3Sopenharmony_ci    ///             brace_token: braced!(content in input),
778fad3a1d3Sopenharmony_ci    ///             items: {
779fad3a1d3Sopenharmony_ci    ///                 let mut items = Vec::new();
780fad3a1d3Sopenharmony_ci    ///                 while !content.is_empty() {
781fad3a1d3Sopenharmony_ci    ///                     items.push(content.parse()?);
782fad3a1d3Sopenharmony_ci    ///                 }
783fad3a1d3Sopenharmony_ci    ///                 items
784fad3a1d3Sopenharmony_ci    ///             },
785fad3a1d3Sopenharmony_ci    ///         })
786fad3a1d3Sopenharmony_ci    ///     }
787fad3a1d3Sopenharmony_ci    /// }
788fad3a1d3Sopenharmony_ci    /// ```
789fad3a1d3Sopenharmony_ci    pub fn is_empty(&self) -> bool {
790fad3a1d3Sopenharmony_ci        self.cursor().eof()
791fad3a1d3Sopenharmony_ci    }
792fad3a1d3Sopenharmony_ci
793fad3a1d3Sopenharmony_ci    /// Constructs a helper for peeking at the next token in this stream and
794fad3a1d3Sopenharmony_ci    /// building an error message if it is not one of a set of expected tokens.
795fad3a1d3Sopenharmony_ci    ///
796fad3a1d3Sopenharmony_ci    /// # Example
797fad3a1d3Sopenharmony_ci    ///
798fad3a1d3Sopenharmony_ci    /// ```
799fad3a1d3Sopenharmony_ci    /// use syn::{ConstParam, Ident, Lifetime, LifetimeParam, Result, Token, TypeParam};
800fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
801fad3a1d3Sopenharmony_ci    ///
802fad3a1d3Sopenharmony_ci    /// // A generic parameter, a single one of the comma-separated elements inside
803fad3a1d3Sopenharmony_ci    /// // angle brackets in:
804fad3a1d3Sopenharmony_ci    /// //
805fad3a1d3Sopenharmony_ci    /// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
806fad3a1d3Sopenharmony_ci    /// //
807fad3a1d3Sopenharmony_ci    /// // On invalid input, lookahead gives us a reasonable error message.
808fad3a1d3Sopenharmony_ci    /// //
809fad3a1d3Sopenharmony_ci    /// //     error: expected one of: identifier, lifetime, `const`
810fad3a1d3Sopenharmony_ci    /// //       |
811fad3a1d3Sopenharmony_ci    /// //     5 |     fn f<!Sized>() {}
812fad3a1d3Sopenharmony_ci    /// //       |          ^
813fad3a1d3Sopenharmony_ci    /// enum GenericParam {
814fad3a1d3Sopenharmony_ci    ///     Type(TypeParam),
815fad3a1d3Sopenharmony_ci    ///     Lifetime(LifetimeParam),
816fad3a1d3Sopenharmony_ci    ///     Const(ConstParam),
817fad3a1d3Sopenharmony_ci    /// }
818fad3a1d3Sopenharmony_ci    ///
819fad3a1d3Sopenharmony_ci    /// impl Parse for GenericParam {
820fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
821fad3a1d3Sopenharmony_ci    ///         let lookahead = input.lookahead1();
822fad3a1d3Sopenharmony_ci    ///         if lookahead.peek(Ident) {
823fad3a1d3Sopenharmony_ci    ///             input.parse().map(GenericParam::Type)
824fad3a1d3Sopenharmony_ci    ///         } else if lookahead.peek(Lifetime) {
825fad3a1d3Sopenharmony_ci    ///             input.parse().map(GenericParam::Lifetime)
826fad3a1d3Sopenharmony_ci    ///         } else if lookahead.peek(Token![const]) {
827fad3a1d3Sopenharmony_ci    ///             input.parse().map(GenericParam::Const)
828fad3a1d3Sopenharmony_ci    ///         } else {
829fad3a1d3Sopenharmony_ci    ///             Err(lookahead.error())
830fad3a1d3Sopenharmony_ci    ///         }
831fad3a1d3Sopenharmony_ci    ///     }
832fad3a1d3Sopenharmony_ci    /// }
833fad3a1d3Sopenharmony_ci    /// ```
834fad3a1d3Sopenharmony_ci    pub fn lookahead1(&self) -> Lookahead1<'a> {
835fad3a1d3Sopenharmony_ci        lookahead::new(self.scope, self.cursor())
836fad3a1d3Sopenharmony_ci    }
837fad3a1d3Sopenharmony_ci
838fad3a1d3Sopenharmony_ci    /// Forks a parse stream so that parsing tokens out of either the original
839fad3a1d3Sopenharmony_ci    /// or the fork does not advance the position of the other.
840fad3a1d3Sopenharmony_ci    ///
841fad3a1d3Sopenharmony_ci    /// # Performance
842fad3a1d3Sopenharmony_ci    ///
843fad3a1d3Sopenharmony_ci    /// Forking a parse stream is a cheap fixed amount of work and does not
844fad3a1d3Sopenharmony_ci    /// involve copying token buffers. Where you might hit performance problems
845fad3a1d3Sopenharmony_ci    /// is if your macro ends up parsing a large amount of content more than
846fad3a1d3Sopenharmony_ci    /// once.
847fad3a1d3Sopenharmony_ci    ///
848fad3a1d3Sopenharmony_ci    /// ```
849fad3a1d3Sopenharmony_ci    /// # use syn::{Expr, Result};
850fad3a1d3Sopenharmony_ci    /// # use syn::parse::ParseStream;
851fad3a1d3Sopenharmony_ci    /// #
852fad3a1d3Sopenharmony_ci    /// # fn bad(input: ParseStream) -> Result<Expr> {
853fad3a1d3Sopenharmony_ci    /// // Do not do this.
854fad3a1d3Sopenharmony_ci    /// if input.fork().parse::<Expr>().is_ok() {
855fad3a1d3Sopenharmony_ci    ///     return input.parse::<Expr>();
856fad3a1d3Sopenharmony_ci    /// }
857fad3a1d3Sopenharmony_ci    /// # unimplemented!()
858fad3a1d3Sopenharmony_ci    /// # }
859fad3a1d3Sopenharmony_ci    /// ```
860fad3a1d3Sopenharmony_ci    ///
861fad3a1d3Sopenharmony_ci    /// As a rule, avoid parsing an unbounded amount of tokens out of a forked
862fad3a1d3Sopenharmony_ci    /// parse stream. Only use a fork when the amount of work performed against
863fad3a1d3Sopenharmony_ci    /// the fork is small and bounded.
864fad3a1d3Sopenharmony_ci    ///
865fad3a1d3Sopenharmony_ci    /// When complex speculative parsing against the forked stream is
866fad3a1d3Sopenharmony_ci    /// unavoidable, use [`parse::discouraged::Speculative`] to advance the
867fad3a1d3Sopenharmony_ci    /// original stream once the fork's parse is determined to have been
868fad3a1d3Sopenharmony_ci    /// successful.
869fad3a1d3Sopenharmony_ci    ///
870fad3a1d3Sopenharmony_ci    /// For a lower level way to perform speculative parsing at the token level,
871fad3a1d3Sopenharmony_ci    /// consider using [`ParseStream::step`] instead.
872fad3a1d3Sopenharmony_ci    ///
873fad3a1d3Sopenharmony_ci    /// [`parse::discouraged::Speculative`]: discouraged::Speculative
874fad3a1d3Sopenharmony_ci    /// [`ParseStream::step`]: ParseBuffer::step
875fad3a1d3Sopenharmony_ci    ///
876fad3a1d3Sopenharmony_ci    /// # Example
877fad3a1d3Sopenharmony_ci    ///
878fad3a1d3Sopenharmony_ci    /// The parse implementation shown here parses possibly restricted `pub`
879fad3a1d3Sopenharmony_ci    /// visibilities.
880fad3a1d3Sopenharmony_ci    ///
881fad3a1d3Sopenharmony_ci    /// - `pub`
882fad3a1d3Sopenharmony_ci    /// - `pub(crate)`
883fad3a1d3Sopenharmony_ci    /// - `pub(self)`
884fad3a1d3Sopenharmony_ci    /// - `pub(super)`
885fad3a1d3Sopenharmony_ci    /// - `pub(in some::path)`
886fad3a1d3Sopenharmony_ci    ///
887fad3a1d3Sopenharmony_ci    /// To handle the case of visibilities inside of tuple structs, the parser
888fad3a1d3Sopenharmony_ci    /// needs to distinguish parentheses that specify visibility restrictions
889fad3a1d3Sopenharmony_ci    /// from parentheses that form part of a tuple type.
890fad3a1d3Sopenharmony_ci    ///
891fad3a1d3Sopenharmony_ci    /// ```
892fad3a1d3Sopenharmony_ci    /// # struct A;
893fad3a1d3Sopenharmony_ci    /// # struct B;
894fad3a1d3Sopenharmony_ci    /// # struct C;
895fad3a1d3Sopenharmony_ci    /// #
896fad3a1d3Sopenharmony_ci    /// struct S(pub(crate) A, pub (B, C));
897fad3a1d3Sopenharmony_ci    /// ```
898fad3a1d3Sopenharmony_ci    ///
899fad3a1d3Sopenharmony_ci    /// In this example input the first tuple struct element of `S` has
900fad3a1d3Sopenharmony_ci    /// `pub(crate)` visibility while the second tuple struct element has `pub`
901fad3a1d3Sopenharmony_ci    /// visibility; the parentheses around `(B, C)` are part of the type rather
902fad3a1d3Sopenharmony_ci    /// than part of a visibility restriction.
903fad3a1d3Sopenharmony_ci    ///
904fad3a1d3Sopenharmony_ci    /// The parser uses a forked parse stream to check the first token inside of
905fad3a1d3Sopenharmony_ci    /// parentheses after the `pub` keyword. This is a small bounded amount of
906fad3a1d3Sopenharmony_ci    /// work performed against the forked parse stream.
907fad3a1d3Sopenharmony_ci    ///
908fad3a1d3Sopenharmony_ci    /// ```
909fad3a1d3Sopenharmony_ci    /// use syn::{parenthesized, token, Ident, Path, Result, Token};
910fad3a1d3Sopenharmony_ci    /// use syn::ext::IdentExt;
911fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
912fad3a1d3Sopenharmony_ci    ///
913fad3a1d3Sopenharmony_ci    /// struct PubVisibility {
914fad3a1d3Sopenharmony_ci    ///     pub_token: Token![pub],
915fad3a1d3Sopenharmony_ci    ///     restricted: Option<Restricted>,
916fad3a1d3Sopenharmony_ci    /// }
917fad3a1d3Sopenharmony_ci    ///
918fad3a1d3Sopenharmony_ci    /// struct Restricted {
919fad3a1d3Sopenharmony_ci    ///     paren_token: token::Paren,
920fad3a1d3Sopenharmony_ci    ///     in_token: Option<Token![in]>,
921fad3a1d3Sopenharmony_ci    ///     path: Path,
922fad3a1d3Sopenharmony_ci    /// }
923fad3a1d3Sopenharmony_ci    ///
924fad3a1d3Sopenharmony_ci    /// impl Parse for PubVisibility {
925fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
926fad3a1d3Sopenharmony_ci    ///         let pub_token: Token![pub] = input.parse()?;
927fad3a1d3Sopenharmony_ci    ///
928fad3a1d3Sopenharmony_ci    ///         if input.peek(token::Paren) {
929fad3a1d3Sopenharmony_ci    ///             let ahead = input.fork();
930fad3a1d3Sopenharmony_ci    ///             let mut content;
931fad3a1d3Sopenharmony_ci    ///             parenthesized!(content in ahead);
932fad3a1d3Sopenharmony_ci    ///
933fad3a1d3Sopenharmony_ci    ///             if content.peek(Token![crate])
934fad3a1d3Sopenharmony_ci    ///                 || content.peek(Token![self])
935fad3a1d3Sopenharmony_ci    ///                 || content.peek(Token![super])
936fad3a1d3Sopenharmony_ci    ///             {
937fad3a1d3Sopenharmony_ci    ///                 return Ok(PubVisibility {
938fad3a1d3Sopenharmony_ci    ///                     pub_token,
939fad3a1d3Sopenharmony_ci    ///                     restricted: Some(Restricted {
940fad3a1d3Sopenharmony_ci    ///                         paren_token: parenthesized!(content in input),
941fad3a1d3Sopenharmony_ci    ///                         in_token: None,
942fad3a1d3Sopenharmony_ci    ///                         path: Path::from(content.call(Ident::parse_any)?),
943fad3a1d3Sopenharmony_ci    ///                     }),
944fad3a1d3Sopenharmony_ci    ///                 });
945fad3a1d3Sopenharmony_ci    ///             } else if content.peek(Token![in]) {
946fad3a1d3Sopenharmony_ci    ///                 return Ok(PubVisibility {
947fad3a1d3Sopenharmony_ci    ///                     pub_token,
948fad3a1d3Sopenharmony_ci    ///                     restricted: Some(Restricted {
949fad3a1d3Sopenharmony_ci    ///                         paren_token: parenthesized!(content in input),
950fad3a1d3Sopenharmony_ci    ///                         in_token: Some(content.parse()?),
951fad3a1d3Sopenharmony_ci    ///                         path: content.call(Path::parse_mod_style)?,
952fad3a1d3Sopenharmony_ci    ///                     }),
953fad3a1d3Sopenharmony_ci    ///                 });
954fad3a1d3Sopenharmony_ci    ///             }
955fad3a1d3Sopenharmony_ci    ///         }
956fad3a1d3Sopenharmony_ci    ///
957fad3a1d3Sopenharmony_ci    ///         Ok(PubVisibility {
958fad3a1d3Sopenharmony_ci    ///             pub_token,
959fad3a1d3Sopenharmony_ci    ///             restricted: None,
960fad3a1d3Sopenharmony_ci    ///         })
961fad3a1d3Sopenharmony_ci    ///     }
962fad3a1d3Sopenharmony_ci    /// }
963fad3a1d3Sopenharmony_ci    /// ```
964fad3a1d3Sopenharmony_ci    pub fn fork(&self) -> Self {
965fad3a1d3Sopenharmony_ci        ParseBuffer {
966fad3a1d3Sopenharmony_ci            scope: self.scope,
967fad3a1d3Sopenharmony_ci            cell: self.cell.clone(),
968fad3a1d3Sopenharmony_ci            marker: PhantomData,
969fad3a1d3Sopenharmony_ci            // Not the parent's unexpected. Nothing cares whether the clone
970fad3a1d3Sopenharmony_ci            // parses all the way unless we `advance_to`.
971fad3a1d3Sopenharmony_ci            unexpected: Cell::new(Some(Rc::new(Cell::new(Unexpected::None)))),
972fad3a1d3Sopenharmony_ci        }
973fad3a1d3Sopenharmony_ci    }
974fad3a1d3Sopenharmony_ci
975fad3a1d3Sopenharmony_ci    /// Triggers an error at the current position of the parse stream.
976fad3a1d3Sopenharmony_ci    ///
977fad3a1d3Sopenharmony_ci    /// # Example
978fad3a1d3Sopenharmony_ci    ///
979fad3a1d3Sopenharmony_ci    /// ```
980fad3a1d3Sopenharmony_ci    /// use syn::{Expr, Result, Token};
981fad3a1d3Sopenharmony_ci    /// use syn::parse::{Parse, ParseStream};
982fad3a1d3Sopenharmony_ci    ///
983fad3a1d3Sopenharmony_ci    /// // Some kind of loop: `while` or `for` or `loop`.
984fad3a1d3Sopenharmony_ci    /// struct Loop {
985fad3a1d3Sopenharmony_ci    ///     expr: Expr,
986fad3a1d3Sopenharmony_ci    /// }
987fad3a1d3Sopenharmony_ci    ///
988fad3a1d3Sopenharmony_ci    /// impl Parse for Loop {
989fad3a1d3Sopenharmony_ci    ///     fn parse(input: ParseStream) -> Result<Self> {
990fad3a1d3Sopenharmony_ci    ///         if input.peek(Token![while])
991fad3a1d3Sopenharmony_ci    ///             || input.peek(Token![for])
992fad3a1d3Sopenharmony_ci    ///             || input.peek(Token![loop])
993fad3a1d3Sopenharmony_ci    ///         {
994fad3a1d3Sopenharmony_ci    ///             Ok(Loop {
995fad3a1d3Sopenharmony_ci    ///                 expr: input.parse()?,
996fad3a1d3Sopenharmony_ci    ///             })
997fad3a1d3Sopenharmony_ci    ///         } else {
998fad3a1d3Sopenharmony_ci    ///             Err(input.error("expected some kind of loop"))
999fad3a1d3Sopenharmony_ci    ///         }
1000fad3a1d3Sopenharmony_ci    ///     }
1001fad3a1d3Sopenharmony_ci    /// }
1002fad3a1d3Sopenharmony_ci    /// ```
1003fad3a1d3Sopenharmony_ci    pub fn error<T: Display>(&self, message: T) -> Error {
1004fad3a1d3Sopenharmony_ci        error::new_at(self.scope, self.cursor(), message)
1005fad3a1d3Sopenharmony_ci    }
1006fad3a1d3Sopenharmony_ci
1007fad3a1d3Sopenharmony_ci    /// Speculatively parses tokens from this parse stream, advancing the
1008fad3a1d3Sopenharmony_ci    /// position of this stream only if parsing succeeds.
1009fad3a1d3Sopenharmony_ci    ///
1010fad3a1d3Sopenharmony_ci    /// This is a powerful low-level API used for defining the `Parse` impls of
1011fad3a1d3Sopenharmony_ci    /// the basic built-in token types. It is not something that will be used
1012fad3a1d3Sopenharmony_ci    /// widely outside of the Syn codebase.
1013fad3a1d3Sopenharmony_ci    ///
1014fad3a1d3Sopenharmony_ci    /// # Example
1015fad3a1d3Sopenharmony_ci    ///
1016fad3a1d3Sopenharmony_ci    /// ```
1017fad3a1d3Sopenharmony_ci    /// use proc_macro2::TokenTree;
1018fad3a1d3Sopenharmony_ci    /// use syn::Result;
1019fad3a1d3Sopenharmony_ci    /// use syn::parse::ParseStream;
1020fad3a1d3Sopenharmony_ci    ///
1021fad3a1d3Sopenharmony_ci    /// // This function advances the stream past the next occurrence of `@`. If
1022fad3a1d3Sopenharmony_ci    /// // no `@` is present in the stream, the stream position is unchanged and
1023fad3a1d3Sopenharmony_ci    /// // an error is returned.
1024fad3a1d3Sopenharmony_ci    /// fn skip_past_next_at(input: ParseStream) -> Result<()> {
1025fad3a1d3Sopenharmony_ci    ///     input.step(|cursor| {
1026fad3a1d3Sopenharmony_ci    ///         let mut rest = *cursor;
1027fad3a1d3Sopenharmony_ci    ///         while let Some((tt, next)) = rest.token_tree() {
1028fad3a1d3Sopenharmony_ci    ///             match &tt {
1029fad3a1d3Sopenharmony_ci    ///                 TokenTree::Punct(punct) if punct.as_char() == '@' => {
1030fad3a1d3Sopenharmony_ci    ///                     return Ok(((), next));
1031fad3a1d3Sopenharmony_ci    ///                 }
1032fad3a1d3Sopenharmony_ci    ///                 _ => rest = next,
1033fad3a1d3Sopenharmony_ci    ///             }
1034fad3a1d3Sopenharmony_ci    ///         }
1035fad3a1d3Sopenharmony_ci    ///         Err(cursor.error("no `@` was found after this point"))
1036fad3a1d3Sopenharmony_ci    ///     })
1037fad3a1d3Sopenharmony_ci    /// }
1038fad3a1d3Sopenharmony_ci    /// #
1039fad3a1d3Sopenharmony_ci    /// # fn remainder_after_skipping_past_next_at(
1040fad3a1d3Sopenharmony_ci    /// #     input: ParseStream,
1041fad3a1d3Sopenharmony_ci    /// # ) -> Result<proc_macro2::TokenStream> {
1042fad3a1d3Sopenharmony_ci    /// #     skip_past_next_at(input)?;
1043fad3a1d3Sopenharmony_ci    /// #     input.parse()
1044fad3a1d3Sopenharmony_ci    /// # }
1045fad3a1d3Sopenharmony_ci    /// #
1046fad3a1d3Sopenharmony_ci    /// # use syn::parse::Parser;
1047fad3a1d3Sopenharmony_ci    /// # let remainder = remainder_after_skipping_past_next_at
1048fad3a1d3Sopenharmony_ci    /// #     .parse_str("a @ b c")
1049fad3a1d3Sopenharmony_ci    /// #     .unwrap();
1050fad3a1d3Sopenharmony_ci    /// # assert_eq!(remainder.to_string(), "b c");
1051fad3a1d3Sopenharmony_ci    /// ```
1052fad3a1d3Sopenharmony_ci    pub fn step<F, R>(&self, function: F) -> Result<R>
1053fad3a1d3Sopenharmony_ci    where
1054fad3a1d3Sopenharmony_ci        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
1055fad3a1d3Sopenharmony_ci    {
1056fad3a1d3Sopenharmony_ci        // Since the user's function is required to work for any 'c, we know
1057fad3a1d3Sopenharmony_ci        // that the Cursor<'c> they return is either derived from the input
1058fad3a1d3Sopenharmony_ci        // StepCursor<'c, 'a> or from a Cursor<'static>.
1059fad3a1d3Sopenharmony_ci        //
1060fad3a1d3Sopenharmony_ci        // It would not be legal to write this function without the invariant
1061fad3a1d3Sopenharmony_ci        // lifetime 'c in StepCursor<'c, 'a>. If this function were written only
1062fad3a1d3Sopenharmony_ci        // in terms of 'a, the user could take our ParseBuffer<'a>, upcast it to
1063fad3a1d3Sopenharmony_ci        // a ParseBuffer<'short> which some shorter lifetime than 'a, invoke
1064fad3a1d3Sopenharmony_ci        // `step` on their ParseBuffer<'short> with a closure that returns
1065fad3a1d3Sopenharmony_ci        // Cursor<'short>, and we would wrongly write that Cursor<'short> into
1066fad3a1d3Sopenharmony_ci        // the Cell intended to hold Cursor<'a>.
1067fad3a1d3Sopenharmony_ci        //
1068fad3a1d3Sopenharmony_ci        // In some cases it may be necessary for R to contain a Cursor<'a>.
1069fad3a1d3Sopenharmony_ci        // Within Syn we solve this using `advance_step_cursor` which uses the
1070fad3a1d3Sopenharmony_ci        // existence of a StepCursor<'c, 'a> as proof that it is safe to cast
1071fad3a1d3Sopenharmony_ci        // from Cursor<'c> to Cursor<'a>. If needed outside of Syn, it would be
1072fad3a1d3Sopenharmony_ci        // safe to expose that API as a method on StepCursor.
1073fad3a1d3Sopenharmony_ci        let (node, rest) = function(StepCursor {
1074fad3a1d3Sopenharmony_ci            scope: self.scope,
1075fad3a1d3Sopenharmony_ci            cursor: self.cell.get(),
1076fad3a1d3Sopenharmony_ci            marker: PhantomData,
1077fad3a1d3Sopenharmony_ci        })?;
1078fad3a1d3Sopenharmony_ci        self.cell.set(rest);
1079fad3a1d3Sopenharmony_ci        Ok(node)
1080fad3a1d3Sopenharmony_ci    }
1081fad3a1d3Sopenharmony_ci
1082fad3a1d3Sopenharmony_ci    /// Returns the `Span` of the next token in the parse stream, or
1083fad3a1d3Sopenharmony_ci    /// `Span::call_site()` if this parse stream has completely exhausted its
1084fad3a1d3Sopenharmony_ci    /// input `TokenStream`.
1085fad3a1d3Sopenharmony_ci    pub fn span(&self) -> Span {
1086fad3a1d3Sopenharmony_ci        let cursor = self.cursor();
1087fad3a1d3Sopenharmony_ci        if cursor.eof() {
1088fad3a1d3Sopenharmony_ci            self.scope
1089fad3a1d3Sopenharmony_ci        } else {
1090fad3a1d3Sopenharmony_ci            crate::buffer::open_span_of_group(cursor)
1091fad3a1d3Sopenharmony_ci        }
1092fad3a1d3Sopenharmony_ci    }
1093fad3a1d3Sopenharmony_ci
1094fad3a1d3Sopenharmony_ci    /// Provides low-level access to the token representation underlying this
1095fad3a1d3Sopenharmony_ci    /// parse stream.
1096fad3a1d3Sopenharmony_ci    ///
1097fad3a1d3Sopenharmony_ci    /// Cursors are immutable so no operations you perform against the cursor
1098fad3a1d3Sopenharmony_ci    /// will affect the state of this parse stream.
1099fad3a1d3Sopenharmony_ci    ///
1100fad3a1d3Sopenharmony_ci    /// # Example
1101fad3a1d3Sopenharmony_ci    ///
1102fad3a1d3Sopenharmony_ci    /// ```
1103fad3a1d3Sopenharmony_ci    /// use proc_macro2::TokenStream;
1104fad3a1d3Sopenharmony_ci    /// use syn::buffer::Cursor;
1105fad3a1d3Sopenharmony_ci    /// use syn::parse::{ParseStream, Result};
1106fad3a1d3Sopenharmony_ci    ///
1107fad3a1d3Sopenharmony_ci    /// // Run a parser that returns T, but get its output as TokenStream instead of T.
1108fad3a1d3Sopenharmony_ci    /// // This works without T needing to implement ToTokens.
1109fad3a1d3Sopenharmony_ci    /// fn recognize_token_stream<T>(
1110fad3a1d3Sopenharmony_ci    ///     recognizer: fn(ParseStream) -> Result<T>,
1111fad3a1d3Sopenharmony_ci    /// ) -> impl Fn(ParseStream) -> Result<TokenStream> {
1112fad3a1d3Sopenharmony_ci    ///     move |input| {
1113fad3a1d3Sopenharmony_ci    ///         let begin = input.cursor();
1114fad3a1d3Sopenharmony_ci    ///         recognizer(input)?;
1115fad3a1d3Sopenharmony_ci    ///         let end = input.cursor();
1116fad3a1d3Sopenharmony_ci    ///         Ok(tokens_between(begin, end))
1117fad3a1d3Sopenharmony_ci    ///     }
1118fad3a1d3Sopenharmony_ci    /// }
1119fad3a1d3Sopenharmony_ci    ///
1120fad3a1d3Sopenharmony_ci    /// // Collect tokens between two cursors as a TokenStream.
1121fad3a1d3Sopenharmony_ci    /// fn tokens_between(begin: Cursor, end: Cursor) -> TokenStream {
1122fad3a1d3Sopenharmony_ci    ///     assert!(begin <= end);
1123fad3a1d3Sopenharmony_ci    ///
1124fad3a1d3Sopenharmony_ci    ///     let mut cursor = begin;
1125fad3a1d3Sopenharmony_ci    ///     let mut tokens = TokenStream::new();
1126fad3a1d3Sopenharmony_ci    ///     while cursor < end {
1127fad3a1d3Sopenharmony_ci    ///         let (token, next) = cursor.token_tree().unwrap();
1128fad3a1d3Sopenharmony_ci    ///         tokens.extend(std::iter::once(token));
1129fad3a1d3Sopenharmony_ci    ///         cursor = next;
1130fad3a1d3Sopenharmony_ci    ///     }
1131fad3a1d3Sopenharmony_ci    ///     tokens
1132fad3a1d3Sopenharmony_ci    /// }
1133fad3a1d3Sopenharmony_ci    ///
1134fad3a1d3Sopenharmony_ci    /// fn main() {
1135fad3a1d3Sopenharmony_ci    ///     use quote::quote;
1136fad3a1d3Sopenharmony_ci    ///     use syn::parse::{Parse, Parser};
1137fad3a1d3Sopenharmony_ci    ///     use syn::Token;
1138fad3a1d3Sopenharmony_ci    ///
1139fad3a1d3Sopenharmony_ci    ///     // Parse syn::Type as a TokenStream, surrounded by angle brackets.
1140fad3a1d3Sopenharmony_ci    ///     fn example(input: ParseStream) -> Result<TokenStream> {
1141fad3a1d3Sopenharmony_ci    ///         let _langle: Token![<] = input.parse()?;
1142fad3a1d3Sopenharmony_ci    ///         let ty = recognize_token_stream(syn::Type::parse)(input)?;
1143fad3a1d3Sopenharmony_ci    ///         let _rangle: Token![>] = input.parse()?;
1144fad3a1d3Sopenharmony_ci    ///         Ok(ty)
1145fad3a1d3Sopenharmony_ci    ///     }
1146fad3a1d3Sopenharmony_ci    ///
1147fad3a1d3Sopenharmony_ci    ///     let tokens = quote! { <fn() -> u8> };
1148fad3a1d3Sopenharmony_ci    ///     println!("{}", example.parse2(tokens).unwrap());
1149fad3a1d3Sopenharmony_ci    /// }
1150fad3a1d3Sopenharmony_ci    /// ```
1151fad3a1d3Sopenharmony_ci    pub fn cursor(&self) -> Cursor<'a> {
1152fad3a1d3Sopenharmony_ci        self.cell.get()
1153fad3a1d3Sopenharmony_ci    }
1154fad3a1d3Sopenharmony_ci
1155fad3a1d3Sopenharmony_ci    fn check_unexpected(&self) -> Result<()> {
1156fad3a1d3Sopenharmony_ci        match inner_unexpected(self).1 {
1157fad3a1d3Sopenharmony_ci            Some(span) => Err(Error::new(span, "unexpected token")),
1158fad3a1d3Sopenharmony_ci            None => Ok(()),
1159fad3a1d3Sopenharmony_ci        }
1160fad3a1d3Sopenharmony_ci    }
1161fad3a1d3Sopenharmony_ci}
1162fad3a1d3Sopenharmony_ci
1163fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1164fad3a1d3Sopenharmony_ciimpl<T: Parse> Parse for Box<T> {
1165fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1166fad3a1d3Sopenharmony_ci        input.parse().map(Box::new)
1167fad3a1d3Sopenharmony_ci    }
1168fad3a1d3Sopenharmony_ci}
1169fad3a1d3Sopenharmony_ci
1170fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1171fad3a1d3Sopenharmony_ciimpl<T: Parse + Token> Parse for Option<T> {
1172fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1173fad3a1d3Sopenharmony_ci        if T::peek(input.cursor()) {
1174fad3a1d3Sopenharmony_ci            Ok(Some(input.parse()?))
1175fad3a1d3Sopenharmony_ci        } else {
1176fad3a1d3Sopenharmony_ci            Ok(None)
1177fad3a1d3Sopenharmony_ci        }
1178fad3a1d3Sopenharmony_ci    }
1179fad3a1d3Sopenharmony_ci}
1180fad3a1d3Sopenharmony_ci
1181fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1182fad3a1d3Sopenharmony_ciimpl Parse for TokenStream {
1183fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1184fad3a1d3Sopenharmony_ci        input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
1185fad3a1d3Sopenharmony_ci    }
1186fad3a1d3Sopenharmony_ci}
1187fad3a1d3Sopenharmony_ci
1188fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1189fad3a1d3Sopenharmony_ciimpl Parse for TokenTree {
1190fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1191fad3a1d3Sopenharmony_ci        input.step(|cursor| match cursor.token_tree() {
1192fad3a1d3Sopenharmony_ci            Some((tt, rest)) => Ok((tt, rest)),
1193fad3a1d3Sopenharmony_ci            None => Err(cursor.error("expected token tree")),
1194fad3a1d3Sopenharmony_ci        })
1195fad3a1d3Sopenharmony_ci    }
1196fad3a1d3Sopenharmony_ci}
1197fad3a1d3Sopenharmony_ci
1198fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1199fad3a1d3Sopenharmony_ciimpl Parse for Group {
1200fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1201fad3a1d3Sopenharmony_ci        input.step(|cursor| {
1202fad3a1d3Sopenharmony_ci            if let Some((group, rest)) = cursor.any_group_token() {
1203fad3a1d3Sopenharmony_ci                if group.delimiter() != Delimiter::None {
1204fad3a1d3Sopenharmony_ci                    return Ok((group, rest));
1205fad3a1d3Sopenharmony_ci                }
1206fad3a1d3Sopenharmony_ci            }
1207fad3a1d3Sopenharmony_ci            Err(cursor.error("expected group token"))
1208fad3a1d3Sopenharmony_ci        })
1209fad3a1d3Sopenharmony_ci    }
1210fad3a1d3Sopenharmony_ci}
1211fad3a1d3Sopenharmony_ci
1212fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1213fad3a1d3Sopenharmony_ciimpl Parse for Punct {
1214fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1215fad3a1d3Sopenharmony_ci        input.step(|cursor| match cursor.punct() {
1216fad3a1d3Sopenharmony_ci            Some((punct, rest)) => Ok((punct, rest)),
1217fad3a1d3Sopenharmony_ci            None => Err(cursor.error("expected punctuation token")),
1218fad3a1d3Sopenharmony_ci        })
1219fad3a1d3Sopenharmony_ci    }
1220fad3a1d3Sopenharmony_ci}
1221fad3a1d3Sopenharmony_ci
1222fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1223fad3a1d3Sopenharmony_ciimpl Parse for Literal {
1224fad3a1d3Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1225fad3a1d3Sopenharmony_ci        input.step(|cursor| match cursor.literal() {
1226fad3a1d3Sopenharmony_ci            Some((literal, rest)) => Ok((literal, rest)),
1227fad3a1d3Sopenharmony_ci            None => Err(cursor.error("expected literal token")),
1228fad3a1d3Sopenharmony_ci        })
1229fad3a1d3Sopenharmony_ci    }
1230fad3a1d3Sopenharmony_ci}
1231fad3a1d3Sopenharmony_ci
1232fad3a1d3Sopenharmony_ci/// Parser that can parse Rust tokens into a particular syntax tree node.
1233fad3a1d3Sopenharmony_ci///
1234fad3a1d3Sopenharmony_ci/// Refer to the [module documentation] for details about parsing in Syn.
1235fad3a1d3Sopenharmony_ci///
1236fad3a1d3Sopenharmony_ci/// [module documentation]: self
1237fad3a1d3Sopenharmony_cipub trait Parser: Sized {
1238fad3a1d3Sopenharmony_ci    type Output;
1239fad3a1d3Sopenharmony_ci
1240fad3a1d3Sopenharmony_ci    /// Parse a proc-macro2 token stream into the chosen syntax tree node.
1241fad3a1d3Sopenharmony_ci    ///
1242fad3a1d3Sopenharmony_ci    /// This function will check that the input is fully parsed. If there are
1243fad3a1d3Sopenharmony_ci    /// any unparsed tokens at the end of the stream, an error is returned.
1244fad3a1d3Sopenharmony_ci    fn parse2(self, tokens: TokenStream) -> Result<Self::Output>;
1245fad3a1d3Sopenharmony_ci
1246fad3a1d3Sopenharmony_ci    /// Parse tokens of source code into the chosen syntax tree node.
1247fad3a1d3Sopenharmony_ci    ///
1248fad3a1d3Sopenharmony_ci    /// This function will check that the input is fully parsed. If there are
1249fad3a1d3Sopenharmony_ci    /// any unparsed tokens at the end of the stream, an error is returned.
1250fad3a1d3Sopenharmony_ci    #[cfg(feature = "proc-macro")]
1251fad3a1d3Sopenharmony_ci    #[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))]
1252fad3a1d3Sopenharmony_ci    fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> {
1253fad3a1d3Sopenharmony_ci        self.parse2(proc_macro2::TokenStream::from(tokens))
1254fad3a1d3Sopenharmony_ci    }
1255fad3a1d3Sopenharmony_ci
1256fad3a1d3Sopenharmony_ci    /// Parse a string of Rust code into the chosen syntax tree node.
1257fad3a1d3Sopenharmony_ci    ///
1258fad3a1d3Sopenharmony_ci    /// This function will check that the input is fully parsed. If there are
1259fad3a1d3Sopenharmony_ci    /// any unparsed tokens at the end of the string, an error is returned.
1260fad3a1d3Sopenharmony_ci    ///
1261fad3a1d3Sopenharmony_ci    /// # Hygiene
1262fad3a1d3Sopenharmony_ci    ///
1263fad3a1d3Sopenharmony_ci    /// Every span in the resulting syntax tree will be set to resolve at the
1264fad3a1d3Sopenharmony_ci    /// macro call site.
1265fad3a1d3Sopenharmony_ci    fn parse_str(self, s: &str) -> Result<Self::Output> {
1266fad3a1d3Sopenharmony_ci        self.parse2(proc_macro2::TokenStream::from_str(s)?)
1267fad3a1d3Sopenharmony_ci    }
1268fad3a1d3Sopenharmony_ci
1269fad3a1d3Sopenharmony_ci    // Not public API.
1270fad3a1d3Sopenharmony_ci    #[doc(hidden)]
1271fad3a1d3Sopenharmony_ci    #[cfg(any(feature = "full", feature = "derive"))]
1272fad3a1d3Sopenharmony_ci    fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
1273fad3a1d3Sopenharmony_ci        let _ = scope;
1274fad3a1d3Sopenharmony_ci        self.parse2(tokens)
1275fad3a1d3Sopenharmony_ci    }
1276fad3a1d3Sopenharmony_ci}
1277fad3a1d3Sopenharmony_ci
1278fad3a1d3Sopenharmony_cifn tokens_to_parse_buffer(tokens: &TokenBuffer) -> ParseBuffer {
1279fad3a1d3Sopenharmony_ci    let scope = Span::call_site();
1280fad3a1d3Sopenharmony_ci    let cursor = tokens.begin();
1281fad3a1d3Sopenharmony_ci    let unexpected = Rc::new(Cell::new(Unexpected::None));
1282fad3a1d3Sopenharmony_ci    new_parse_buffer(scope, cursor, unexpected)
1283fad3a1d3Sopenharmony_ci}
1284fad3a1d3Sopenharmony_ci
1285fad3a1d3Sopenharmony_ciimpl<F, T> Parser for F
1286fad3a1d3Sopenharmony_ciwhere
1287fad3a1d3Sopenharmony_ci    F: FnOnce(ParseStream) -> Result<T>,
1288fad3a1d3Sopenharmony_ci{
1289fad3a1d3Sopenharmony_ci    type Output = T;
1290fad3a1d3Sopenharmony_ci
1291fad3a1d3Sopenharmony_ci    fn parse2(self, tokens: TokenStream) -> Result<T> {
1292fad3a1d3Sopenharmony_ci        let buf = TokenBuffer::new2(tokens);
1293fad3a1d3Sopenharmony_ci        let state = tokens_to_parse_buffer(&buf);
1294fad3a1d3Sopenharmony_ci        let node = self(&state)?;
1295fad3a1d3Sopenharmony_ci        state.check_unexpected()?;
1296fad3a1d3Sopenharmony_ci        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
1297fad3a1d3Sopenharmony_ci            Err(Error::new(unexpected_span, "unexpected token"))
1298fad3a1d3Sopenharmony_ci        } else {
1299fad3a1d3Sopenharmony_ci            Ok(node)
1300fad3a1d3Sopenharmony_ci        }
1301fad3a1d3Sopenharmony_ci    }
1302fad3a1d3Sopenharmony_ci
1303fad3a1d3Sopenharmony_ci    #[cfg(any(feature = "full", feature = "derive"))]
1304fad3a1d3Sopenharmony_ci    fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
1305fad3a1d3Sopenharmony_ci        let buf = TokenBuffer::new2(tokens);
1306fad3a1d3Sopenharmony_ci        let cursor = buf.begin();
1307fad3a1d3Sopenharmony_ci        let unexpected = Rc::new(Cell::new(Unexpected::None));
1308fad3a1d3Sopenharmony_ci        let state = new_parse_buffer(scope, cursor, unexpected);
1309fad3a1d3Sopenharmony_ci        let node = self(&state)?;
1310fad3a1d3Sopenharmony_ci        state.check_unexpected()?;
1311fad3a1d3Sopenharmony_ci        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
1312fad3a1d3Sopenharmony_ci            Err(Error::new(unexpected_span, "unexpected token"))
1313fad3a1d3Sopenharmony_ci        } else {
1314fad3a1d3Sopenharmony_ci            Ok(node)
1315fad3a1d3Sopenharmony_ci        }
1316fad3a1d3Sopenharmony_ci    }
1317fad3a1d3Sopenharmony_ci}
1318fad3a1d3Sopenharmony_ci
1319fad3a1d3Sopenharmony_ci#[cfg(any(feature = "full", feature = "derive"))]
1320fad3a1d3Sopenharmony_cipub(crate) fn parse_scoped<F: Parser>(f: F, scope: Span, tokens: TokenStream) -> Result<F::Output> {
1321fad3a1d3Sopenharmony_ci    f.__parse_scoped(scope, tokens)
1322fad3a1d3Sopenharmony_ci}
1323fad3a1d3Sopenharmony_ci
1324fad3a1d3Sopenharmony_ci/// An empty syntax tree node that consumes no tokens when parsed.
1325fad3a1d3Sopenharmony_ci///
1326fad3a1d3Sopenharmony_ci/// This is useful for attribute macros that want to ensure they are not
1327fad3a1d3Sopenharmony_ci/// provided any attribute args.
1328fad3a1d3Sopenharmony_ci///
1329fad3a1d3Sopenharmony_ci/// ```
1330fad3a1d3Sopenharmony_ci/// # extern crate proc_macro;
1331fad3a1d3Sopenharmony_ci/// #
1332fad3a1d3Sopenharmony_ci/// use proc_macro::TokenStream;
1333fad3a1d3Sopenharmony_ci/// use syn::parse_macro_input;
1334fad3a1d3Sopenharmony_ci/// use syn::parse::Nothing;
1335fad3a1d3Sopenharmony_ci///
1336fad3a1d3Sopenharmony_ci/// # const IGNORE: &str = stringify! {
1337fad3a1d3Sopenharmony_ci/// #[proc_macro_attribute]
1338fad3a1d3Sopenharmony_ci/// # };
1339fad3a1d3Sopenharmony_ci/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream {
1340fad3a1d3Sopenharmony_ci///     parse_macro_input!(args as Nothing);
1341fad3a1d3Sopenharmony_ci///
1342fad3a1d3Sopenharmony_ci///     /* ... */
1343fad3a1d3Sopenharmony_ci/// #   TokenStream::new()
1344fad3a1d3Sopenharmony_ci/// }
1345fad3a1d3Sopenharmony_ci/// ```
1346fad3a1d3Sopenharmony_ci///
1347fad3a1d3Sopenharmony_ci/// ```text
1348fad3a1d3Sopenharmony_ci/// error: unexpected token
1349fad3a1d3Sopenharmony_ci///  --> src/main.rs:3:19
1350fad3a1d3Sopenharmony_ci///   |
1351fad3a1d3Sopenharmony_ci/// 3 | #[my_attr(asdf)]
1352fad3a1d3Sopenharmony_ci///   |           ^^^^
1353fad3a1d3Sopenharmony_ci/// ```
1354fad3a1d3Sopenharmony_cipub struct Nothing;
1355fad3a1d3Sopenharmony_ci
1356fad3a1d3Sopenharmony_ciimpl Parse for Nothing {
1357fad3a1d3Sopenharmony_ci    fn parse(_input: ParseStream) -> Result<Self> {
1358fad3a1d3Sopenharmony_ci        Ok(Nothing)
1359fad3a1d3Sopenharmony_ci    }
1360fad3a1d3Sopenharmony_ci}
1361fad3a1d3Sopenharmony_ci
1362fad3a1d3Sopenharmony_ci#[cfg(feature = "extra-traits")]
1363fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
1364fad3a1d3Sopenharmony_ciimpl Debug for Nothing {
1365fad3a1d3Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1366fad3a1d3Sopenharmony_ci        f.write_str("Nothing")
1367fad3a1d3Sopenharmony_ci    }
1368fad3a1d3Sopenharmony_ci}
1369fad3a1d3Sopenharmony_ci
1370fad3a1d3Sopenharmony_ci#[cfg(feature = "extra-traits")]
1371fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
1372fad3a1d3Sopenharmony_ciimpl Eq for Nothing {}
1373fad3a1d3Sopenharmony_ci
1374fad3a1d3Sopenharmony_ci#[cfg(feature = "extra-traits")]
1375fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
1376fad3a1d3Sopenharmony_ciimpl PartialEq for Nothing {
1377fad3a1d3Sopenharmony_ci    fn eq(&self, _other: &Self) -> bool {
1378fad3a1d3Sopenharmony_ci        true
1379fad3a1d3Sopenharmony_ci    }
1380fad3a1d3Sopenharmony_ci}
1381fad3a1d3Sopenharmony_ci
1382fad3a1d3Sopenharmony_ci#[cfg(feature = "extra-traits")]
1383fad3a1d3Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
1384fad3a1d3Sopenharmony_ciimpl Hash for Nothing {
1385fad3a1d3Sopenharmony_ci    fn hash<H: Hasher>(&self, _state: &mut H) {}
1386fad3a1d3Sopenharmony_ci}
1387