Change ItemModifier and ItemDecorator to traits

For convenience, the traits are implemented for the respective bare
functions. Change code from this:

```rust
ItemDecorator(some_function)
// or
ItemModifier(some_other_function)
```
to
```rust
ItemDecorator(box some_function)
// or
ItemModifier(box some_other_function)
```

[breaking-change]
This commit is contained in:
Steven Fackler 2014-09-09 23:57:14 -07:00
parent 6ceb9b4157
commit 313cb8acae
3 changed files with 46 additions and 13 deletions

View file

@ -39,11 +39,45 @@ 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 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)
}
}
pub struct BasicMacroExpander {
pub expander: MacroExpanderFn,
@ -281,11 +315,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.
///
@ -371,7 +405,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"),

View file

@ -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 {
@ -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()));
@ -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,
@ -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!()