Skip to content

Make ItemModifier and ItemDecorator take trait objects #17162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions src/librustc/plugin/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use lint::{LintPassObject, LintId, Lint};

use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier, BasicMacroExpander};
use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier};
use syntax::ext::base::{MacroExpanderFn};
use syntax::codemap::Span;
use syntax::parse::token;
Expand Down Expand Up @@ -71,15 +71,10 @@ impl Registry {
/// Register a macro of the usual kind.
///
/// This is a convenience wrapper for `register_syntax_extension`.
/// It builds for you a `NormalTT` with a `BasicMacroExpander`,
/// It builds for you a `NormalTT` that calls `expander`,
/// and also takes care of interning the macro's name.
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
self.register_syntax_extension(
token::intern(name),
NormalTT(box BasicMacroExpander {
expander: expander,
span: None,
}, None));
self.register_syntax_extension(token::intern(name), NormalTT(box expander, None));
}

/// Register a compiler lint pass.
Expand Down
83 changes: 49 additions & 34 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,44 @@ pub struct MacroDef {
pub ext: SyntaxExtension
}

pub type ItemDecorator =
fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>, |Gc<ast::Item>|);
pub trait ItemDecorator {
fn expand(&self,
ecx: &mut ExtCtxt,
sp: Span,
meta_item: Gc<ast::MetaItem>,
item: Gc<ast::Item>,
push: |Gc<ast::Item>|);
}

pub type ItemModifier =
fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>) -> Gc<ast::Item>;
impl ItemDecorator for fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>, |Gc<ast::Item>|) {
fn expand(&self,
ecx: &mut ExtCtxt,
sp: Span,
meta_item: Gc<ast::MetaItem>,
item: Gc<ast::Item>,
push: |Gc<ast::Item>|) {
(*self)(ecx, sp, meta_item, item, push)
}
}

pub struct BasicMacroExpander {
pub expander: MacroExpanderFn,
pub span: Option<Span>
pub trait ItemModifier {
fn expand(&self,
ecx: &mut ExtCtxt,
span: Span,
meta_item: Gc<ast::MetaItem>,
item: Gc<ast::Item>)
-> Gc<ast::Item>;
}

impl ItemModifier for fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>) -> Gc<ast::Item> {
fn expand(&self,
ecx: &mut ExtCtxt,
span: Span,
meta_item: Gc<ast::MetaItem>,
item: Gc<ast::Item>)
-> Gc<ast::Item> {
(*self)(ecx, span, meta_item, item)
}
}

/// Represents a thing that maps token trees to Macro Results
Expand All @@ -60,24 +89,18 @@ pub trait TTMacroExpander {
}

pub type MacroExpanderFn =
fn<'cx>(ecx: &'cx mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree])
-> Box<MacResult+'cx>;
fn<'cx>(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box<MacResult+'cx>;

impl TTMacroExpander for BasicMacroExpander {
impl TTMacroExpander for MacroExpanderFn {
fn expand<'cx>(&self,
ecx: &'cx mut ExtCtxt,
span: Span,
token_tree: &[ast::TokenTree])
-> Box<MacResult+'cx> {
(self.expander)(ecx, span, token_tree)
(*self)(ecx, span, token_tree)
}
}

pub struct BasicIdentMacroExpander {
pub expander: IdentMacroExpanderFn,
pub span: Option<Span>
}

pub trait IdentMacroExpander {
fn expand<'cx>(&self,
cx: &'cx mut ExtCtxt,
Expand All @@ -87,20 +110,20 @@ pub trait IdentMacroExpander {
-> Box<MacResult+'cx>;
}

impl IdentMacroExpander for BasicIdentMacroExpander {
pub type IdentMacroExpanderFn =
fn<'cx>(&'cx mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult+'cx>;

impl IdentMacroExpander for IdentMacroExpanderFn {
fn expand<'cx>(&self,
cx: &'cx mut ExtCtxt,
sp: Span,
ident: ast::Ident,
token_tree: Vec<ast::TokenTree> )
-> Box<MacResult+'cx> {
(self.expander)(cx, sp, ident, token_tree)
(*self)(cx, sp, ident, token_tree)
}
}

pub type IdentMacroExpanderFn =
fn<'cx>(&'cx mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult+'cx>;

/// The result of a macro expansion. The return values of the various
/// methods are spliced into the AST at the callsite of the macro (or
/// just into the compiler's internal macro table, for `make_def`).
Expand Down Expand Up @@ -281,11 +304,11 @@ pub enum SyntaxExtension {
/// based upon it.
///
/// `#[deriving(...)]` is an `ItemDecorator`.
ItemDecorator(ItemDecorator),
ItemDecorator(Box<ItemDecorator + 'static>),

/// A syntax extension that is attached to an item and modifies it
/// in-place.
ItemModifier(ItemModifier),
ItemModifier(Box<ItemModifier + 'static>),

/// A normal, function-like syntax extension.
///
Expand Down Expand Up @@ -329,20 +352,12 @@ impl BlockInfo {
fn initial_syntax_expander_table() -> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
NormalTT(box BasicMacroExpander {
expander: f,
span: None,
},
None)
NormalTT(box f, None)
}

let mut syntax_expanders = SyntaxEnv::new();
syntax_expanders.insert(intern("macro_rules"),
LetSyntaxTT(box BasicIdentMacroExpander {
expander: ext::tt::macro_rules::add_new_extension,
span: None,
},
None));
LetSyntaxTT(box ext::tt::macro_rules::add_new_extension, None));
syntax_expanders.insert(intern("fmt"),
builtin_normal_expander(
ext::fmt::expand_syntax_ext));
Expand Down Expand Up @@ -371,7 +386,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
builtin_normal_expander(
ext::log_syntax::expand_syntax_ext));
syntax_expanders.insert(intern("deriving"),
ItemDecorator(ext::deriving::expand_meta_deriving));
ItemDecorator(box ext::deriving::expand_meta_deriving));

// Quasi-quoting expanders
syntax_expanders.insert(intern("quote_tokens"),
Expand Down
9 changes: 4 additions & 5 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)

match fld.cx.syntax_env.find(&intern(mname.get())) {
Some(rc) => match *rc {
ItemDecorator(dec_fn) => {
ItemDecorator(ref dec) => {
attr::mark_used(attr);

fld.cx.bt_push(ExpnInfo {
Expand All @@ -266,8 +266,7 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
// we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld
let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| items.push(item));
dec.expand(fld.cx, attr.span, attr.node.value, it, |item| items.push(item));
decorator_items.extend(items.move_iter()
.flat_map(|item| expand_item(item, fld).move_iter()));

Expand Down Expand Up @@ -328,7 +327,7 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)

match fld.cx.syntax_env.find(&intern(mname.get())) {
Some(rc) => match *rc {
ItemModifier(dec_fn) => {
ItemModifier(ref mac) => {
attr::mark_used(attr);
fld.cx.bt_push(ExpnInfo {
call_site: attr.span,
Expand All @@ -338,7 +337,7 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
span: None,
}
});
it = dec_fn(fld.cx, attr.span, attr.node.value, it);
it = mac.expand(fld.cx, attr.span, attr.node.value, it);
fld.cx.bt_pop();
}
_ => unreachable!()
Expand Down
2 changes: 1 addition & 1 deletion src/test/auxiliary/macro_crate_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("identity", expand_identity);
reg.register_syntax_extension(
token::intern("into_foo"),
ItemModifier(expand_into_foo));
ItemModifier(box expand_into_foo));
}

fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
Expand Down