blob: c9d40889f817b5af06192c89e3ac1f5e8cead3c5 [file] [log] [blame]
David Tolnay544a90f2018-08-24 20:34:03 -04001#[macro_use]
2pub mod token;
3
4#[macro_use]
5pub mod parse;
6
7#[macro_use]
8mod group;
9
10mod error;
11mod lookahead;
12mod span;
13
14pub use proc_macro2::Ident;
15
16// Not public API.
17#[doc(hidden)]
18pub mod export;
19
20use std::str::FromStr;
21
David Tolnay6d67c742018-08-24 20:42:39 -040022use buffer::TokenBuffer;
David Tolnay544a90f2018-08-24 20:34:03 -040023#[cfg(feature = "proc-macro")]
24use proc_macro;
25use proc_macro2::{self, Span};
David Tolnay544a90f2018-08-24 20:34:03 -040026
27use self::parse::{Parse, ParseBuffer, Result};
28
29/// Parse tokens of source code into the chosen syntax tree node.
30#[cfg(feature = "proc-macro")]
31pub fn parse<T: Parse>(input: proc_macro::TokenStream) -> Result<T> {
32 parse2(proc_macro2::TokenStream::from(input))
33}
34
35/// Parse a proc-macro2 token stream into the chosen syntax tree node.
36pub fn parse2<T: Parse>(input: proc_macro2::TokenStream) -> Result<T> {
37 let buf = TokenBuffer::new2(input);
38 let state = ParseBuffer::new(Span::call_site(), buf.begin());
39 T::parse(&state)
40}
41
42/// Parse a string of Rust code into the chosen syntax tree node.
43pub fn parse_str<T: Parse>(input: &str) -> Result<T> {
44 let tokens = proc_macro2::TokenStream::from_str(input)?;
45 parse2(tokens)
46}
47
48/// Parse the input TokenStream of a macro, triggering a compile error if the
49/// tokens fail to parse.
50///
51/// # Intended usage
52///
53/// ```rust
54/// # extern crate proc_macro;
David Tolnay6d67c742018-08-24 20:42:39 -040055/// # extern crate syn;
David Tolnay544a90f2018-08-24 20:34:03 -040056/// #
57/// use proc_macro::TokenStream;
David Tolnay6d67c742018-08-24 20:42:39 -040058/// use syn::parse_macro_input;
59/// use syn::next::parse::{Parse, ParseStream, Result};
David Tolnay544a90f2018-08-24 20:34:03 -040060///
61/// struct MyMacroInput {
62/// /* ... */
63/// }
64///
65/// impl Parse for MyMacroInput {
66/// fn parse(input: ParseStream) -> Result<Self> {
67/// /* ... */
68/// # Ok(MyMacroInput {})
69/// }
70/// }
71///
72/// # const IGNORE: &str = stringify! {
73/// #[proc_macro]
74/// # };
75/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
76/// let input = parse_macro_input!(tokens as MyMacroInput);
77///
78/// /* ... */
79/// # "".parse().unwrap()
80/// }
81/// #
82/// # fn main() {}
83/// ```
84#[cfg(feature = "proc-macro")]
85#[macro_export]
86macro_rules! parse_macro_input {
87 ($tokenstream:ident as $ty:ty) => {
88 match $crate::next::parse::<$ty>($tokenstream) {
89 $crate::next::export::Ok(data) => data,
90 $crate::next::export::Err(err) => {
91 return $crate::next::export::TokenStream::from(err.into_compile_error());
92 }
93 };
94 };
95}