diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-03-16 01:09:22 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-11-30 06:15:19 +0200 |
| commit | e305994beb1347e2fcadf5c84acec60fb6902551 (patch) | |
| tree | fa3cc47ac732137a158714c65f2e758667ef7e8f /src/libsyntax_ext | |
| parent | 3e90a12a8a95933604a8b609197fce61bb24a38c (diff) | |
| download | rust-e305994beb1347e2fcadf5c84acec60fb6902551.tar.gz rust-e305994beb1347e2fcadf5c84acec60fb6902551.zip | |
proc_macro: introduce a "bridge" between clients (proc macros) and servers (compiler front-ends).
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/deriving/custom.rs | 65 | ||||
| -rw-r--r-- | src/libsyntax_ext/lib.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax_ext/proc_macro_decls.rs (renamed from src/libsyntax_ext/proc_macro_registrar.rs) | 142 | ||||
| -rw-r--r-- | src/libsyntax_ext/proc_macro_impl.rs | 42 |
4 files changed, 124 insertions, 129 deletions
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 55b3928d68e..76826dd93e7 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -8,15 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::panic; - use errors::FatalError; -use proc_macro::{TokenStream, __internal}; use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; use syntax::source_map::Span; use syntax::ext::base::*; +use syntax::parse; +use syntax::parse::token::{self, Token}; +use syntax::tokenstream; use syntax::visit::Visitor; +use syntax_pos::DUMMY_SP; + +use proc_macro_impl::EXEC_STRATEGY; struct MarkAttrs<'a>(&'a [ast::Name]); @@ -32,14 +35,10 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> { } pub struct ProcMacroDerive { - inner: fn(TokenStream) -> TokenStream, - attrs: Vec<ast::Name>, -} - -impl ProcMacroDerive { - pub fn new(inner: fn(TokenStream) -> TokenStream, attrs: Vec<ast::Name>) -> ProcMacroDerive { - ProcMacroDerive { inner: inner, attrs: attrs } - } + pub client: ::proc_macro::bridge::client::Client< + fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + >, + pub attrs: Vec<ast::Name>, } impl MultiItemModifier for ProcMacroDerive { @@ -75,10 +74,12 @@ impl MultiItemModifier for ProcMacroDerive { // Mark attributes as known, and used. MarkAttrs(&self.attrs).visit_item(&item); - let input = __internal::new_token_stream(ecx.resolver.eliminate_crate_var(item)); - let res = __internal::set_sess(ecx, || { - let inner = self.inner; - panic::catch_unwind(panic::AssertUnwindSafe(|| inner(input))) + let item = ecx.resolver.eliminate_crate_var(item); + let token = Token::interpolated(token::NtItem(item)); + let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); + let server = ::proc_macro::rustc::Rustc; + let res = ::proc_macro::__internal::set_sess(ecx, || { + self.client.run(&EXEC_STRATEGY, server, input) }); let stream = match res { @@ -86,10 +87,7 @@ impl MultiItemModifier for ProcMacroDerive { Err(e) => { let msg = "proc-macro derive panicked"; let mut err = ecx.struct_span_fatal(span, msg); - if let Some(s) = e.downcast_ref::<String>() { - err.help(&format!("message: {}", s)); - } - if let Some(s) = e.downcast_ref::<&'static str>() { + if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } @@ -99,21 +97,32 @@ impl MultiItemModifier for ProcMacroDerive { }; let error_count_before = ecx.parse_sess.span_diagnostic.err_count(); - __internal::set_sess(ecx, || { - let msg = "proc-macro derive produced unparseable tokens"; - match __internal::token_stream_parse_items(stream) { - // fail if there have been errors emitted - Ok(_) if ecx.parse_sess.span_diagnostic.err_count() > error_count_before => { - ecx.struct_span_fatal(span, msg).emit(); - FatalError.raise(); + let msg = "proc-macro derive produced unparseable tokens"; + + let mut parser = parse::stream_to_parser(ecx.parse_sess, stream); + let mut items = vec![]; + + loop { + match parser.parse_item().map_err(::proc_macro::__internal::parse_to_lex_err) { + Ok(None) => break, + Ok(Some(item)) => { + items.push(Annotatable::Item(item)) } - Ok(new_items) => new_items.into_iter().map(Annotatable::Item).collect(), Err(_) => { // FIXME: handle this better ecx.struct_span_fatal(span, msg).emit(); FatalError.raise(); } } - }) + } + + + // fail if there have been errors emitted + if ecx.parse_sess.span_diagnostic.err_count() > error_count_before { + ecx.struct_span_fatal(span, msg).emit(); + FatalError.raise(); + } + + items } } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 7c023fc5c9c..c5bceff4733 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -55,9 +55,7 @@ mod trace_macros; mod test; mod test_case; -pub mod proc_macro_registrar; - - +pub mod proc_macro_decls; pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_decls.rs index 65e175f95df..c859275ed02 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -91,7 +91,7 @@ pub fn modify(sess: &ParseSess, return krate; } - krate.module.items.push(mk_registrar(&mut cx, &derives, &attr_macros, &bang_macros)); + krate.module.items.push(mk_decls(&mut cx, &derives, &attr_macros, &bang_macros)); krate } @@ -339,19 +339,21 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // mod $gensym { // extern crate proc_macro; // -// use proc_macro::__internal::Registry; +// use proc_macro::bridge::client::ProcMacro; // -// #[plugin_registrar] -// fn registrar(registrar: &mut Registry) { -// registrar.register_custom_derive($name_trait1, ::$name1, &[]); -// registrar.register_custom_derive($name_trait2, ::$name2, &["attribute_name"]); +// #[rustc_proc_macro_decls] +// static DECLS: &[ProcMacro] = &[ +// ProcMacro::custom_derive($name_trait1, &[], ::$name1); +// ProcMacro::custom_derive($name_trait2, &["attribute_name"], ::$name2); // // ... -// } +// ]; // } -fn mk_registrar(cx: &mut ExtCtxt, - custom_derives: &[ProcMacroDerive], - custom_attrs: &[ProcMacroDef], - custom_macros: &[ProcMacroDef]) -> P<ast::Item> { +fn mk_decls( + cx: &mut ExtCtxt, + custom_derives: &[ProcMacroDerive], + custom_attrs: &[ProcMacroDef], + custom_macros: &[ProcMacroDef], +) -> P<ast::Item> { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo { call_site: DUMMY_SP, @@ -370,75 +372,67 @@ fn mk_registrar(cx: &mut ExtCtxt, Vec::new(), ast::ItemKind::ExternCrate(None)); - let __internal = Ident::from_str("__internal"); - let registry = Ident::from_str("Registry"); - let registrar = Ident::from_str("_registrar"); - let register_custom_derive = Ident::from_str("register_custom_derive"); - let register_attr_proc_macro = Ident::from_str("register_attr_proc_macro"); - let register_bang_proc_macro = Ident::from_str("register_bang_proc_macro"); + let bridge = Ident::from_str("bridge"); + let client = Ident::from_str("client"); + let proc_macro_ty = Ident::from_str("ProcMacro"); + let custom_derive = Ident::from_str("custom_derive"); + let attr = Ident::from_str("attr"); + let bang = Ident::from_str("bang"); let crate_kw = Ident::with_empty_ctxt(keywords::Crate.name()); - let local_path = |cx: &mut ExtCtxt, sp: Span, name: Ident| { - cx.path(sp.with_ctxt(span.ctxt()), vec![crate_kw, name]) + + let decls = { + let local_path = |sp: Span, name| { + cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![crate_kw, name])) + }; + let proc_macro_ty_method_path = |method| cx.expr_path(cx.path(span, vec![ + proc_macro, bridge, client, proc_macro_ty, method, + ])); + custom_derives.iter().map(|cd| { + cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![ + cx.expr_str(cd.span, cd.trait_name), + cx.expr_vec_slice( + span, + cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>() + ), + local_path(cd.span, cd.function_name), + ]) + }).chain(custom_attrs.iter().map(|ca| { + cx.expr_call(span, proc_macro_ty_method_path(attr), vec![ + cx.expr_str(ca.span, ca.function_name.name), + local_path(ca.span, ca.function_name), + ]) + })).chain(custom_macros.iter().map(|cm| { + cx.expr_call(span, proc_macro_ty_method_path(bang), vec![ + cx.expr_str(cm.span, cm.function_name.name), + local_path(cm.span, cm.function_name), + ]) + })).collect() }; - let mut stmts = custom_derives.iter().map(|cd| { - let path = local_path(cx, cd.span, cd.function_name); - let trait_name = cx.expr_str(cd.span, cd.trait_name); - let attrs = cx.expr_vec_slice( - span, - cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>() - ); - let registrar = cx.expr_ident(span, registrar); - let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, - register_custom_derive]); - - cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, trait_name, cx.expr_path(path), attrs])) - - }).collect::<Vec<_>>(); - - stmts.extend(custom_attrs.iter().map(|ca| { - let name = cx.expr_str(ca.span, ca.function_name.name); - let path = local_path(cx, ca.span, ca.function_name); - let registrar = cx.expr_ident(ca.span, registrar); - - let ufcs_path = cx.path(span, - vec![proc_macro, __internal, registry, register_attr_proc_macro]); - - cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, name, cx.expr_path(path)])) - })); - - stmts.extend(custom_macros.iter().map(|cm| { - let name = cx.expr_str(cm.span, cm.function_name.name); - let path = local_path(cx, cm.span, cm.function_name); - let registrar = cx.expr_ident(cm.span, registrar); - - let ufcs_path = cx.path(span, - vec![proc_macro, __internal, registry, register_bang_proc_macro]); - - cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, name, cx.expr_path(path)])) - })); - - let path = cx.path(span, vec![proc_macro, __internal, registry]); - let registrar_path = cx.ty_path(path); - let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable); - let func = cx.item_fn(span, - registrar, - vec![cx.arg(span, registrar, arg_ty)], - cx.ty(span, ast::TyKind::Tup(Vec::new())), - cx.block(span, stmts)); - - let derive_registrar = cx.meta_word(span, Symbol::intern("rustc_derive_registrar")); - let derive_registrar = cx.attribute(span, derive_registrar); - let func = func.map(|mut i| { - i.attrs.push(derive_registrar); + let decls_static = cx.item_static( + span, + Ident::from_str("_DECLS"), + cx.ty_rptr(span, + cx.ty(span, ast::TyKind::Slice( + cx.ty_path(cx.path(span, + vec![proc_macro, bridge, client, proc_macro_ty])))), + None, ast::Mutability::Immutable), + ast::Mutability::Immutable, + cx.expr_vec_slice(span, decls), + ).map(|mut i| { + let attr = cx.meta_word(span, Symbol::intern("rustc_proc_macro_decls")); + i.attrs.push(cx.attribute(span, attr)); i.vis = respan(span, ast::VisibilityKind::Public); i }); - let ident = ast::Ident::with_empty_ctxt(Symbol::gensym("registrar")); - let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| { + + let module = cx.item_mod( + span, + span, + ast::Ident::with_empty_ctxt(Symbol::gensym("decls")), + vec![], + vec![krate, decls_static], + ).map(|mut i| { i.vis = respan(span, ast::VisibilityKind::Public); i }); diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index ff60262055b..1f111dfcaf9 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::panic; use errors::FatalError; @@ -17,11 +16,13 @@ use syntax::ext::base::*; use syntax::tokenstream::TokenStream; use syntax::ext::base; -use proc_macro::TokenStream as TsShim; -use proc_macro::__internal; +pub const EXEC_STRATEGY: ::proc_macro::bridge::server::SameThread = + ::proc_macro::bridge::server::SameThread; pub struct AttrProcMacro { - pub inner: fn(TsShim, TsShim) -> TsShim, + pub client: ::proc_macro::bridge::client::Client< + fn(::proc_macro::TokenStream, ::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + >, } impl base::AttrProcMacro for AttrProcMacro { @@ -31,22 +32,17 @@ impl base::AttrProcMacro for AttrProcMacro { annotation: TokenStream, annotated: TokenStream) -> TokenStream { - let annotation = __internal::token_stream_wrap(annotation); - let annotated = __internal::token_stream_wrap(annotated); - - let res = __internal::set_sess(ecx, || { - panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(annotation, annotated))) + let server = ::proc_macro::rustc::Rustc; + let res = ::proc_macro::__internal::set_sess(ecx, || { + self.client.run(&EXEC_STRATEGY, server, annotation, annotated) }); match res { - Ok(stream) => __internal::token_stream_inner(stream), + Ok(stream) => stream, Err(e) => { let msg = "custom attribute panicked"; let mut err = ecx.struct_span_fatal(span, msg); - if let Some(s) = e.downcast_ref::<String>() { - err.help(&format!("message: {}", s)); - } - if let Some(s) = e.downcast_ref::<&'static str>() { + if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } @@ -58,7 +54,9 @@ impl base::AttrProcMacro for AttrProcMacro { } pub struct BangProcMacro { - pub inner: fn(TsShim) -> TsShim, + pub client: ::proc_macro::bridge::client::Client< + fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream, + >, } impl base::ProcMacro for BangProcMacro { @@ -67,21 +65,17 @@ impl base::ProcMacro for BangProcMacro { span: Span, input: TokenStream) -> TokenStream { - let input = __internal::token_stream_wrap(input); - - let res = __internal::set_sess(ecx, || { - panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input))) + let server = ::proc_macro::rustc::Rustc; + let res = ::proc_macro::__internal::set_sess(ecx, || { + self.client.run(&EXEC_STRATEGY, server, input) }); match res { - Ok(stream) => __internal::token_stream_inner(stream), + Ok(stream) => stream, Err(e) => { let msg = "proc macro panicked"; let mut err = ecx.struct_span_fatal(span, msg); - if let Some(s) = e.downcast_ref::<String>() { - err.help(&format!("message: {}", s)); - } - if let Some(s) = e.downcast_ref::<&'static str>() { + if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } |
