about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-20 20:28:36 +0100
committerAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-31 11:38:49 +0100
commitaa3fe205223936e37c0accd91473fa3d666451ce (patch)
tree481c91362307cde7e4c3d39e1c8b0514e12dad84 /src/libsyntax/ext
parent01172eedfab32b24e38aa86ba0cba24453e842fb (diff)
downloadrust-aa3fe205223936e37c0accd91473fa3d666451ce.tar.gz
rust-aa3fe205223936e37c0accd91473fa3d666451ce.zip
Replace uses of Decorator and Modifier
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs15
-rw-r--r--src/libsyntax/ext/cfg_attr.rs61
-rw-r--r--src/libsyntax/ext/deriving/mod.rs25
-rw-r--r--src/libsyntax/ext/expand.rs19
4 files changed, 89 insertions, 31 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d3cedee6d21..cf0df37ede8 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -39,6 +39,8 @@ pub trait ItemDecorator {
               push: Box<FnMut(P<ast::Item>)>);
 }
 
+#[allow(deprecated)]
+#[deprecated="Replaced by MultiItemDecorator"]
 impl<F> ItemDecorator for F
     where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box<FnMut(P<ast::Item>)>)
 {
@@ -62,6 +64,7 @@ pub trait ItemModifier {
               -> P<ast::Item>;
 }
 
+#[allow(deprecated)]
 #[deprecated="Replaced by MultiItemModifier"]
 impl<F> ItemModifier for F
     where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item>
@@ -157,18 +160,18 @@ pub trait MultiItemDecorator {
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &Annotatable,
-              push: Box<FnMut(P<Annotatable>)>);
+              push: Box<FnMut(Annotatable)>);
 }
 
 impl<F> MultiItemDecorator for F
-    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box<FnMut(P<Annotatable>)>)
+    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, Box<FnMut(Annotatable)>)
 {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &Annotatable,
-              push: Box<FnMut(P<Annotatable>)>) {
+              push: Box<FnMut(Annotatable)>) {
         (*self)(ecx, sp, meta_item, item, push)
     }
 }
@@ -426,7 +429,7 @@ pub enum SyntaxExtension {
     /// A syntax extension that is attached to an item and creates new items
     /// based upon it.
     ///
-    /// `#[derive(...)]` is an `ItemDecorator`.
+    /// `#[derive(...)]` is a `MultiItemDecorator`.
     MultiDecorator(Box<MultiItemDecorator + 'static>),
 
     /// A syntax extension that is attached to an item and modifies it
@@ -499,7 +502,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
                             builtin_normal_expander(
                                     ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern("derive"),
-                            Decorator(box ext::deriving::expand_meta_derive));
+                            MultiDecorator(box ext::deriving::expand_meta_derive));
     syntax_expanders.insert(intern("deriving"),
                             Decorator(box ext::deriving::expand_deprecated_deriving));
 
@@ -562,7 +565,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
                             builtin_normal_expander(
                                     ext::cfg::expand_cfg));
     syntax_expanders.insert(intern("cfg_attr"),
-                            Modifier(box ext::cfg_attr::expand));
+                            MultiModifier(box ext::cfg_attr::expand));
     syntax_expanders.insert(intern("trace_macros"),
                             builtin_normal_expander(
                                     ext::trace_macros::expand_trace_macros));
diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs
index a85f12edb22..d282c3084de 100644
--- a/src/libsyntax/ext/cfg_attr.rs
+++ b/src/libsyntax/ext/cfg_attr.rs
@@ -8,27 +8,70 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast;
+use ast::{self, TraitItem, ImplItem};
 use attr;
 use codemap::Span;
-use ext::base::ExtCtxt;
+use ext::base::{Annotatable, ExtCtxt};
 use ext::build::AstBuilder;
 use ptr::P;
 
-pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> {
+macro_rules! fold_annotatable {
+    ($ann:expr, $item:ident => $oper:expr) => (
+        match $ann {
+            Annotatable::Item(it) => {
+                let mut $item = (*it).clone();
+                $oper;
+                Annotatable::Item(P($item))
+            }
+            Annotatable::TraitItem(it) => {
+                match it {
+                    TraitItem::RequiredMethod(mut $item) => {
+                        $oper;
+                        Annotatable::TraitItem(TraitItem::RequiredMethod($item))
+                    }
+                    TraitItem::ProvidedMethod(pm) => {
+                        let mut $item = (*pm).clone();
+                        $oper;
+                        Annotatable::TraitItem(TraitItem::ProvidedMethod(P($item)))
+                    }
+                    TraitItem::TypeTraitItem(at) => {
+                        let mut $item = (*at).clone();
+                        $oper;
+                        Annotatable::TraitItem(TraitItem::TypeTraitItem(P($item)))
+                    }
+                }
+            }
+            Annotatable::ImplItem(it) => {
+                match it {
+                    ImplItem::MethodImplItem(pm) => {
+                        let mut $item = (*pm).clone();
+                        $oper;
+                        Annotatable::ImplItem(ImplItem::MethodImplItem(P($item)))
+                    }
+                    ImplItem::TypeImplItem(at) => {
+                        let mut $item = (*at).clone();
+                        $oper;
+                        Annotatable::ImplItem(ImplItem::TypeImplItem(P($item)))
+                    }
+                }
+            }
+        }
+    );
+}
+
+pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, ann: Annotatable) -> Annotatable {
     let (cfg, attr) = match mi.node {
         ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]),
         _ => {
             cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
-            return it;
+            return ann;
         }
     };
 
-    let mut out = (*it).clone();
     if attr::cfg_matches(&cx.parse_sess.span_diagnostic, cx.cfg.as_slice(), &**cfg) {
-        out.attrs.push(cx.attribute(attr.span, attr.clone()));
+        let attr = cx.attribute(attr.span, attr.clone());
+        fold_annotatable!(ann, item => item.attrs.push(attr))
+    } else {
+        ann
     }
-
-    P(out)
 }
-
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index d3d7fee3a18..a06ed638fe1 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -13,10 +13,9 @@
 //! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is
 //! the standard library, and "std" is the core library.
 
-use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
-use ext::base::ExtCtxt;
+use ast::{MetaItem, MetaList, MetaNameValue, MetaWord};
+use ext::base::{Annotatable, ExtCtxt};
 use codemap::Span;
-use ptr::P;
 
 pub mod bounds;
 pub mod clone;
@@ -49,10 +48,20 @@ pub fn expand_deprecated_deriving(cx: &mut ExtCtxt,
 }
 
 pub fn expand_meta_derive(cx: &mut ExtCtxt,
-                          _span: Span,
+                          span: Span,
                           mitem: &MetaItem,
-                          item: &Item,
-                          mut push: Box<FnMut(P<Item>)>) {
+                          annotatable: &Annotatable,
+                          mut push: Box<FnMut(Annotatable)>)
+{
+    // Derive can only be applied to items
+    let item = match annotatable {
+        &Annotatable::Item(ref it) => it.clone(),
+        _ => {
+            cx.span_err(span, "`derive` can only be applied to items");
+            return;
+        }
+    };
+
     match mitem.node {
         MetaNameValue(_, ref l) => {
             cx.span_err(l.span, "unexpected value in `derive`");
@@ -70,8 +79,8 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt,
                     MetaList(ref tname, _) |
                     MetaWord(ref tname) => {
                         macro_rules! expand {
-                            ($func:path) => ($func(cx, titem.span, &**titem, item,
-                                                   |i| push(i)))
+                            ($func:path) => ($func(cx, titem.span, &**titem,
+                                                   &*item, |i| push(Annotatable::Item(i))))
                         }
 
                         match tname.get() {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index dbbcee0d9d8..672acfbff65 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -488,6 +488,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
         .into_iter().map(|i| i.expect_item()).collect()
 }
 
+#[allow(deprecated)] // This is needed because the `ItemModifier` trait is used
 fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
                          -> P<ast::Item> {
     // partition the attributes into ItemModifiers and others
@@ -1056,6 +1057,7 @@ impl<'a> Folder for PatIdentRenamer<'a> {
     }
 }
 
+#[allow(deprecated)] // This is needed because the `Decorator` variant is used
 fn expand_annotatable(a: Annotatable,
                       fld: &mut MacroExpander)
                       -> SmallVector<Annotatable> {
@@ -1092,7 +1094,8 @@ fn expand_annotatable(a: Annotatable,
                     dec.expand(fld.cx, attr.span, &*attr.node.value, &**it,
                                box |&mut: item| items.push(item));
                     decorator_items.extend(items.into_iter()
-                        .flat_map(|item| expand_item(item, fld).into_iter()));
+                        .flat_map(|item| expand_item(item, fld).into_iter()
+                                                               .map(|i| Annotatable::Item(i))));
 
                     fld.cx.bt_pop();
                 }
@@ -1108,13 +1111,13 @@ fn expand_annotatable(a: Annotatable,
                         }
                     });
 
-                    // we'd ideally decorator_items.push_all(expand_item(item, fld)),
+                    // we'd ideally decorator_items.push_all(expand_annotatable(ann, fld)),
                     // but that double-mut-borrows fld
-                    let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
-                    dec.expand(fld.cx, attr.span, &*attr.node.value, a,
-                               box |&mut: item| items.push(item));
-                    decorator_items.extend(items.into_iter()
-                        .flat_map(|item| expand_item(item, fld).into_iter()));
+                    let mut anns: SmallVector<Annotatable> = SmallVector::zero();
+                    dec.expand(fld.cx, attr.span, &*attr.node.value, &a,
+                               box |&mut: ann| anns.push(ann));
+                    decorator_items.extend(anns.into_iter()
+                        .flat_map(|ann| expand_annotatable(ann, fld).into_iter()));
 
                     fld.cx.bt_pop();
                 }
@@ -1179,7 +1182,7 @@ fn expand_annotatable(a: Annotatable,
         }
     };
 
-    new_items.push_all(decorator_items.into_iter().map(|i| Annotatable::Item(i)).collect());
+    new_items.push_all(decorator_items);
     new_items
 }