1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A support library for macro authors when defining new macros.
13 //! This library, provided by the standard distribution, provides the types
14 //! consumed in the interfaces of procedurally defined macro definitions.
15 //! Currently the primary use of this crate is to provide the ability to define
16 //! new custom derive modes through `#[proc_macro_derive]`.
18 //! Note that this crate is intentionally very bare-bones currently. The main
19 //! type, `TokenStream`, only supports `fmt::Display` and `FromStr`
20 //! implementations, indicating that it can only go to and come from a string.
21 //! This functionality is intended to be expanded over time as more surface
22 //! area for macro authors is stabilized.
24 //! See [the book](../../book/procedural-macros.html) for more.
26 #![crate_name = "proc_macro"]
27 #![stable(feature = "proc_macro_lib", since = "1.15.0")]
28 #![crate_type = "rlib"]
29 #![crate_type = "dylib"]
31 #![deny(missing_docs)]
33 #![feature(rustc_private)]
34 #![feature(staged_api)]
35 #![feature(lang_items)]
40 use std::str::FromStr;
42 use syntax::errors::DiagnosticBuilder;
44 use syntax::tokenstream::TokenStream as TokenStream_;
46 /// The main type provided by this crate, representing an abstract stream of
49 /// This is both the input and output of `#[proc_macro_derive]` definitions.
50 /// Currently it's required to be a list of valid Rust items, but this
51 /// restriction may be lifted in the future.
53 /// The API of this type is intentionally bare-bones, but it'll be expanded over
55 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
56 pub struct TokenStream {
60 /// Error returned from `TokenStream::from_str`.
62 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
67 /// Permanently unstable internal implementation details of this crate. This
68 /// should not be used.
70 /// These methods are used by the rest of the compiler to generate instances of
71 /// `TokenStream` to hand to macro definitions, as well as consume the output.
73 /// Note that this module is also intentionally separate from the rest of the
74 /// crate. This allows the `#[unstable]` directive below to naturally apply to
75 /// all of the contents.
76 #[unstable(feature = "proc_macro_internals", issue = "27812")]
84 use syntax::parse::{self, token, ParseSess};
85 use syntax::tokenstream::{TokenTree, TokenStream as TokenStream_};
87 use super::{TokenStream, LexError};
89 pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
91 inner: TokenTree::Token(item.span, token::Interpolated(Rc::new(token::NtItem(item))))
96 pub fn token_stream_wrap(inner: TokenStream_) -> TokenStream {
102 pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
103 with_parse_sess(move |sess| {
104 let mut parser = parse::new_parser_from_ts(sess, stream.inner);
105 let mut items = Vec::new();
107 while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
115 pub fn token_stream_inner(stream: TokenStream) -> TokenStream_ {
120 fn register_custom_derive(&mut self,
122 expand: fn(TokenStream) -> TokenStream,
123 attributes: &[&'static str]);
125 fn register_attr_proc_macro(&mut self,
127 expand: fn(TokenStream, TokenStream) -> TokenStream);
129 fn register_bang_proc_macro(&mut self,
131 expand: fn(TokenStream) -> TokenStream);
134 // Emulate scoped_thread_local!() here essentially
136 static CURRENT_SESS: Cell<*const ParseSess> = Cell::new(0 as *const _);
139 pub fn set_parse_sess<F, R>(sess: &ParseSess, f: F) -> R
140 where F: FnOnce() -> R
142 struct Reset { prev: *const ParseSess }
144 impl Drop for Reset {
146 CURRENT_SESS.with(|p| p.set(self.prev));
150 CURRENT_SESS.with(|p| {
151 let _reset = Reset { prev: p.get() };
157 pub fn with_parse_sess<F, R>(f: F) -> R
158 where F: FnOnce(&ParseSess) -> R
160 let p = CURRENT_SESS.with(|p| p.get());
161 assert!(!p.is_null(), "proc_macro::__internal::with_parse_sess() called \
162 before set_parse_sess()!");
167 fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
169 LexError { _inner: () }
172 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
173 impl FromStr for TokenStream {
176 fn from_str(src: &str) -> Result<TokenStream, LexError> {
177 __internal::with_parse_sess(|sess| {
178 let src = src.to_string();
179 let name = "<proc-macro source code>".to_string();
180 let tts = parse::parse_tts_from_source_str(name, src, sess);
182 Ok(__internal::token_stream_wrap(tts.into_iter().collect()))
187 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
188 impl fmt::Display for TokenStream {
189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {