//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
//! tokens in a token stream.
//!
-//! [`ParseStream`]: type.ParseStream.html
-//! [`Result<T>`]: type.Result.html
-//! [`Cursor`]: ../buffer/index.html
+//! [`Result<T>`]: Result
+//! [`Cursor`]: crate::buffer::Cursor
//!
//! # Example
//!
//! procedural macro, they will receive a helpful compiler error message
//! pointing out the exact token that triggered the failure to parse.
//!
-//! [`parse_macro_input!`]: ../macro.parse_macro_input.html
+//! [`parse_macro_input!`]: crate::parse_macro_input!
//!
//! ```
//! # extern crate proc_macro;
//! obvious default way. These functions can return any syntax tree node that
//! implements the [`Parse`] trait, which includes most types in Syn.
//!
-//! [`syn::parse`]: ../fn.parse.html
-//! [`syn::parse2`]: ../fn.parse2.html
-//! [`syn::parse_str`]: ../fn.parse_str.html
-//! [`Parse`]: trait.Parse.html
+//! [`syn::parse`]: crate::parse()
+//! [`syn::parse2`]: crate::parse2()
+//! [`syn::parse_str`]: crate::parse_str()
//!
//! ```
//! use syn::Type;
//!
//! The [`parse_quote!`] macro also uses this approach.
//!
-//! [`parse_quote!`]: ../macro.parse_quote.html
+//! [`parse_quote!`]: crate::parse_quote!
//!
//! # The `Parser` trait
//!
//! may or may not allow trailing punctuation, and parsing it the wrong way
//! would either reject valid input or accept invalid input.
//!
-//! [`Attribute`]: ../struct.Attribute.html
-//! [`Punctuated`]: ../punctuated/index.html
+//! [`Attribute`]: crate::Attribute
+//! [`Punctuated`]: crate::punctuated
//!
//! The `Parse` trait is not implemented in these cases because there is no good
//! behavior to consider the default.
//! single `Parse` implementation, and those parser functions can be invoked
//! through the [`Parser`] trait.
//!
-//! [`Parser`]: trait.Parser.html
//!
//! ```
//! # extern crate proc_macro;
/// - One of [the `syn::parse*` functions][syn-parse]; or
/// - A method of the [`Parser`] trait.
///
-/// [syn-parse]: index.html#the-synparse-functions
+/// [syn-parse]: self#the-synparse-functions
pub struct ParseBuffer<'a> {
scope: Span,
// Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.
/// }
/// ```
pub fn peek2<T: Peek>(&self, token: T) -> bool {
+ fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+ if let Some(group) = buffer.cursor().group(Delimiter::None) {
+ if group.0.skip().map_or(false, peek) {
+ return true;
+ }
+ }
+ buffer.cursor().skip().map_or(false, peek)
+ }
+
let _ = token;
- self.cursor().skip().map_or(false, T::Token::peek)
+ peek2(self, T::Token::peek)
}
/// Looks at the third-next token in the parse stream.
pub fn peek3<T: Peek>(&self, token: T) -> bool {
+ fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+ if let Some(group) = buffer.cursor().group(Delimiter::None) {
+ if group.0.skip().and_then(Cursor::skip).map_or(false, peek) {
+ return true;
+ }
+ }
+ buffer
+ .cursor()
+ .skip()
+ .and_then(Cursor::skip)
+ .map_or(false, peek)
+ }
+
let _ = token;
- self.cursor()
- .skip()
- .and_then(Cursor::skip)
- .map_or(false, T::Token::peek)
+ peek3(self, T::Token::peek)
}
/// Parses zero or more occurrences of `T` separated by punctuation of type
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl<T: Parse> Parse for Box<T> {
fn parse(input: ParseStream) -> Result<Self> {
input.parse().map(Box::new)
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl<T: Parse + Token> Parse for Option<T> {
fn parse(input: ParseStream) -> Result<Self> {
if T::peek(input.cursor()) {
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TokenStream {
fn parse(input: ParseStream) -> Result<Self> {
input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TokenTree {
fn parse(input: ParseStream) -> Result<Self> {
input.step(|cursor| match cursor.token_tree() {
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Group {
fn parse(input: ParseStream) -> Result<Self> {
input.step(|cursor| {
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Punct {
fn parse(input: ParseStream) -> Result<Self> {
input.step(|cursor| match cursor.punct() {
}
}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Literal {
fn parse(input: ParseStream) -> Result<Self> {
input.step(|cursor| match cursor.literal() {