}
pub type ItemDecorator =
- fn(&mut ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item];
+ fn(&mut ExtCtxt, Span, @ast::MetaItem, @ast::Item, |@ast::Item|);
pub struct BasicMacroExpander {
expander: MacroExpanderFn,
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "clone", "Clone"]),
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
pub fn expand_deriving_deep_clone(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "clone", "DeepClone"]),
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn cs_clone(
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
// structures are equal if all fields are equal, and non equal, if
// any fields are not equal or if the enum variants are different
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
md!("ne", cs_ne)
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
pub fn expand_deriving_ord(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
macro_rules! md (
($name:expr, $op:expr, $equal:expr) => {
MethodDef {
md!("ge", false, true)
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
/// Strict inequality.
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
fn cs_equals(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
cs_and(|cx, span, _, _| cx.expr_bool(span, false),
cx, span, substr)
}
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "cmp", "TotalOrd"]),
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new_(~["serialize", "Decodable"], None,
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
pub fn expand_deriving_default(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "default", "Default"]),
},
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new_(~["serialize", "Encodable"], None,
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
pub fn expand(&self,
cx: &mut ExtCtxt,
_mitem: @ast::MetaItem,
- in_items: ~[@ast::Item]) -> ~[@ast::Item] {
- let mut result = ~[];
- for item in in_items.iter() {
- result.push(*item);
- match item.node {
- ast::ItemStruct(struct_def, ref generics) => {
- result.push(self.expand_struct_def(cx,
- struct_def,
- item.ident,
- generics));
- }
- ast::ItemEnum(ref enum_def, ref generics) => {
- result.push(self.expand_enum_def(cx,
- enum_def,
- item.ident,
- generics));
- }
- _ => ()
+ item: @ast::Item,
+ push: |@ast::Item|) {
+ match item.node {
+ ast::ItemStruct(struct_def, ref generics) => {
+ push(self.expand_struct_def(cx,
+ struct_def,
+ item.ident,
+ generics));
+ }
+ ast::ItemEnum(ref enum_def, ref generics) => {
+ push(self.expand_enum_def(cx,
+ enum_def,
+ item.ident,
+ generics));
}
+ _ => ()
}
- result
}
/**
pub fn expand_deriving_iter_bytes(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "to_bytes", "IterBytes"]),
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn iter_bytes_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
match mitem.node {
MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`");
- in_items
}
MetaWord(_) | MetaList(_, []) => {
cx.span_warn(mitem.span, "empty trait list in `deriving`");
- in_items
}
MetaList(_, ref titems) => {
- titems.rev_iter().fold(in_items, |in_items, &titem| {
+ for &titem in titems.rev_iter() {
match titem.node {
MetaNameValue(ref tname, _) |
MetaList(ref tname, _) |
MetaWord(ref tname) => {
macro_rules! expand(($func:path) => ($func(cx, titem.span,
- titem, in_items)));
+ titem, item,
+ |i| push(i))));
match tname.get() {
"Clone" => expand!(clone::expand_deriving_clone),
"DeepClone" => expand!(clone::expand_deriving_deep_clone),
ref tname => {
cx.span_err(titem.span, format!("unknown \
`deriving` trait: `{}`", *tname));
- in_items
}
- }
+ };
}
}
- })
+ }
}
}
}
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item]) -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "num", "FromPrimitive"]),
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
pub fn expand_deriving_rand(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "rand", "Rand"]),
}
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
pub fn expand_deriving_show(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
// &mut ::std::fmt::Formatter
let fmtr = Ptr(~Literal(Path::new(~["std", "fmt", "Formatter"])),
Borrowed(None, ast::MutMutable));
}
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
// we construct a format string and then defer to std::fmt, since that
pub fn expand_deriving_to_str(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "to_str", "ToStr"]),
}
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
// It used to be the case that this deriving implementation invoked
pub fn expand_deriving_zero(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
- in_items: ~[@Item])
- -> ~[@Item] {
+ item: @Item,
+ push: |@Item|) {
let trait_def = TraitDef {
span: span,
path: Path::new(~["std", "num", "Zero"]),
}
]
};
- trait_def.expand(cx, mitem, in_items)
+ trait_def.expand(cx, mitem, item, push)
}
fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
use util::small_vector::SmallVector;
use std::cast;
-use std::vec;
use std::unstable::dynamic_lib::DynamicLibrary;
use std::os;
// For each item, look through the attributes. If any of them are
// decorated with "item decorators", then use that function to transform
// the item into a new set of items.
- let new_items = vec::flat_map(module_.items, |item| {
- item.attrs.rev_iter().fold(~[*item], |items, attr| {
+ let mut new_items = module_.items.clone();
+ for item in module_.items.iter() {
+ for attr in item.attrs.rev_iter() {
let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) {
span: None
}
});
- let r = dec_fn(fld.cx, attr.span, attr.node.value, items);
+ dec_fn(fld.cx, attr.span, attr.node.value, *item,
+ |item| new_items.push(item));
fld.cx.bt_pop();
- r
},
- _ => items,
+ _ => {},
}
- })
- });
+ }
+ }
ast::Mod {
items: new_items,