From 3c02749ad873af24c5865e105bd1e6ded1b71409 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 12 Feb 2014 23:53:52 -0800 Subject: [PATCH] Tweak ItemDecorator API The old method of building up a list of items and threading it through all of the decorators was unwieldy and not really scalable as non-deriving ItemDecorators become possible. The API is now that the decorator gets an immutable reference to the item it's attached to, and a callback that it can pass new items to. If we want to add syntax extensions that can modify the item they're attached to, we can add that later, but I think it'll have to be separate from ItemDecorator to avoid strange ordering issues. --- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/deriving/clone.rs | 12 ++++---- src/libsyntax/ext/deriving/cmp/eq.rs | 5 ++-- src/libsyntax/ext/deriving/cmp/ord.rs | 5 ++-- src/libsyntax/ext/deriving/cmp/totaleq.rs | 5 ++-- src/libsyntax/ext/deriving/cmp/totalord.rs | 5 ++-- src/libsyntax/ext/deriving/decodable.rs | 5 ++-- src/libsyntax/ext/deriving/default.rs | 6 ++-- src/libsyntax/ext/deriving/encodable.rs | 5 ++-- src/libsyntax/ext/deriving/generic.rs | 34 ++++++++++------------ src/libsyntax/ext/deriving/iter_bytes.rs | 5 ++-- src/libsyntax/ext/deriving/mod.rs | 16 +++++----- src/libsyntax/ext/deriving/primitive.rs | 5 ++-- src/libsyntax/ext/deriving/rand.rs | 6 ++-- src/libsyntax/ext/deriving/show.rs | 6 ++-- src/libsyntax/ext/deriving/to_str.rs | 6 ++-- src/libsyntax/ext/deriving/zero.rs | 6 ++-- src/libsyntax/ext/expand.rs | 16 +++++----- 18 files changed, 76 insertions(+), 74 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7ac66ecaa3713..bb5245c240f4f 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -35,7 +35,7 @@ pub struct MacroDef { } 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, diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 76cf5997aee75..bd961002f5311 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -17,8 +17,8 @@ use ext::deriving::generic::*; 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"]), @@ -38,14 +38,14 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt, ] }; - 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"]), @@ -67,7 +67,7 @@ pub fn expand_deriving_deep_clone(cx: &mut ExtCtxt, ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } fn cs_clone( diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 4672f1a8db689..6592dc97f348e 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -17,7 +17,8 @@ use ext::deriving::generic::*; 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 { @@ -54,5 +55,5 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt, md!("ne", cs_ne) ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 1a8ace69307a7..c41986fceef64 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -18,7 +18,8 @@ use ext::deriving::generic::*; 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 { @@ -46,7 +47,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt, md!("ge", false, true) ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } /// Strict inequality. diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index 7b7c1afa4d5cb..63e13b492020d 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -17,7 +17,8 @@ use ext::deriving::generic::*; 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) @@ -41,5 +42,5 @@ pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, } ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 157b6dc7521b7..3e58d2edb2960 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -19,7 +19,8 @@ use std::cmp::{Ordering, Equal, Less, Greater}; 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"]), @@ -39,7 +40,7 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt, ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index fdf1ef17d538b..c5c9a43fa5f58 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -24,7 +24,8 @@ use parse::token; 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, @@ -49,7 +50,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt, ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 7b87152b7115a..7ed27168bb606 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -17,8 +17,8 @@ use ext::deriving::generic::*; 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"]), @@ -37,7 +37,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt, }, ] }; - 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 { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 43edf6006b414..99c712caafef8 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -85,7 +85,8 @@ use parse::token; 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, @@ -110,7 +111,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt, ] }; - trait_def.expand(cx, mitem, in_items) + trait_def.expand(cx, mitem, item, push) } fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 9d290c93c6494..effcccdbaf831 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -322,27 +322,23 @@ impl<'a> TraitDef<'a> { 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 } /** diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 19e81b81df6a6..b1adf96b90af8 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -18,7 +18,8 @@ use ext::deriving::generic::*; 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"]), @@ -41,7 +42,7 @@ pub fn expand_deriving_iter_bytes(cx: &mut ExtCtxt, ] }; - 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 { diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 01e31fc5724d2..62408d79ee31e 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -48,25 +48,24 @@ pub mod generic; 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), @@ -94,12 +93,11 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt, ref tname => { cx.span_err(titem.span, format!("unknown \ `deriving` trait: `{}`", *tname)); - in_items } - } + }; } } - }) + } } } } diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index 1b356667b6b31..9391c9cd23c74 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -19,7 +19,8 @@ use parse::token::InternedString; 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"]), @@ -61,7 +62,7 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, ] }; - 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 { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index ef7bd7c2bcdec..351264fed72af 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -19,8 +19,8 @@ use opt_vec; 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"]), @@ -46,7 +46,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt, } ] }; - 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 { diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index e2d507f303510..984be122fe8a4 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -23,8 +23,8 @@ use std::hashmap::HashMap; 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)); @@ -47,7 +47,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt, } ] }; - 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 diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index e5145fb15f7a1..1efcf61013f6a 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -20,8 +20,8 @@ use parse::token; 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"]), @@ -40,7 +40,7 @@ pub fn expand_deriving_to_str(cx: &mut ExtCtxt, } ] }; - 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 diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index ca5c1543d88dc..924ab3c9e0020 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -17,8 +17,8 @@ use ext::deriving::generic::*; 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"]), @@ -53,7 +53,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt, } ] }; - 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 { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d96fc27f3ddfe..fc13207563c95 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -29,7 +29,6 @@ use visit::Visitor; use util::small_vector::SmallVector; use std::cast; -use std::vec; use std::unstable::dynamic_lib::DynamicLibrary; use std::os; @@ -220,8 +219,9 @@ pub fn expand_mod_items(module_: &ast::Mod, fld: &mut MacroExpander) -> ast::Mod // 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())) { @@ -234,14 +234,14 @@ pub fn expand_mod_items(module_: &ast::Mod, fld: &mut MacroExpander) -> ast::Mod 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,