about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-20 20:10:55 +0100
committerAdolfo OchagavĂ­a <aochagavia92@gmail.com>2015-01-31 11:38:48 +0100
commit01172eedfab32b24e38aa86ba0cba24453e842fb (patch)
tree0273c0505e836f136856021009762a2ddc5d671a
parent2e07b0d6be3d2ffcfb154b5cbbe02bc166014172 (diff)
downloadrust-01172eedfab32b24e38aa86ba0cba24453e842fb.tar.gz
rust-01172eedfab32b24e38aa86ba0cba24453e842fb.zip
Add tests for MultiItemDecorator
-rw-r--r--src/test/auxiliary/macro_crate_test.rs85
-rw-r--r--src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs52
2 files changed, 134 insertions, 3 deletions
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index d545a42ae19..d3c9659a1f1 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -16,11 +16,10 @@
 extern crate syntax;
 extern crate rustc;
 
-use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
+use syntax::ast::{self, TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
-use syntax::parse::token;
-use syntax::parse;
+use syntax::parse::{self, token};
 use syntax::ptr::P;
 use rustc::plugin::Registry;
 
@@ -40,6 +39,9 @@ pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_syntax_extension(
         token::intern("into_multi_foo"),
         MultiModifier(box expand_into_foo_multi));
+    reg.register_syntax_extension(
+        token::intern("duplicate"),
+        MultiDecorator(box expand_duplicate));
 }
 
 fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
@@ -92,6 +94,83 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
     }
 }
 
+// Create a duplicate of the annotatable, based on the MetaItem
+fn expand_duplicate(cx: &mut ExtCtxt,
+                    sp: Span,
+                    mi: &MetaItem,
+                    it: &Annotatable,
+                    mut push: Box<FnMut(Annotatable)>)
+{
+    let copy_name = match mi.node {
+        ast::MetaItem_::MetaList(_, ref xs) => {
+            if let ast::MetaItem_::MetaWord(ref w) = xs[0].node {
+                token::str_to_ident(w.get())
+            } else {
+                cx.span_err(mi.span, "Expected word");
+                return;
+            }
+        }
+        _ => {
+            cx.span_err(mi.span, "Expected list");
+            return;
+        }
+    };
+
+    // Duplicate the item but replace its ident by the MetaItem
+    match it.clone() {
+        Annotatable::Item(it) => {
+            let mut new_it = (*it).clone();
+            new_it.attrs.clear();
+            new_it.ident = copy_name;
+            push(Annotatable::Item(P(new_it)));
+        }
+        Annotatable::ImplItem(it) => {
+            match it {
+                ImplItem::MethodImplItem(m) => {
+                    let mut new_m = (*m).clone();
+                    new_m.attrs.clear();
+                    replace_method_name(&mut new_m.node, copy_name);
+                    push(Annotatable::ImplItem(ImplItem::MethodImplItem(P(new_m))));
+                }
+                ImplItem::TypeImplItem(t) => {
+                    let mut new_t = (*t).clone();
+                    new_t.attrs.clear();
+                    new_t.ident = copy_name;
+                    push(Annotatable::ImplItem(ImplItem::TypeImplItem(P(new_t))));
+                }
+            }
+        }
+        Annotatable::TraitItem(it) => {
+            match it {
+                TraitItem::RequiredMethod(rm) => {
+                    let mut new_rm = rm.clone();
+                    new_rm.attrs.clear();
+                    new_rm.ident = copy_name;
+                    push(Annotatable::TraitItem(TraitItem::RequiredMethod(new_rm)));
+                }
+                TraitItem::ProvidedMethod(pm) => {
+                    let mut new_pm = (*pm).clone();
+                    new_pm.attrs.clear();
+                    replace_method_name(&mut new_pm.node, copy_name);
+                    push(Annotatable::TraitItem(TraitItem::ProvidedMethod(P(new_pm))));
+                }
+                TraitItem::TypeTraitItem(t) => {
+                    let mut new_t = (*t).clone();
+                    new_t.attrs.clear();
+                    new_t.ty_param.ident = copy_name;
+                    push(Annotatable::TraitItem(TraitItem::TypeTraitItem(P(new_t))));
+                }
+            }
+        }
+    }
+
+    fn replace_method_name(m: &mut ast::Method_, i: ast::Ident) {
+        if let &mut ast::Method_::MethDecl(ref mut ident, _, _, _, _, _, _, _) = m {
+            *ident = i
+        }
+    }
+}
+
 fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult+'static> {
     use syntax::ext::quote::rt::*;
 
diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
new file mode 100644
index 00000000000..45341d12d07
--- /dev/null
+++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
@@ -0,0 +1,52 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[plugin] #[no_link]
+extern crate macro_crate_test;
+
+// The duplicate macro will create a copy of the item with the given identifier
+#[duplicate(MyCopy)]
+struct MyStruct {
+    number: i32
+}
+
+trait TestTrait {
+    #[duplicate(TestType2)]
+    type TestType;
+
+    #[duplicate(required_fn2)]
+    fn required_fn(&self);
+
+    #[duplicate(provided_fn2)]
+    fn provided_fn(&self) { }
+}
+
+impl TestTrait for MyStruct {
+    #[duplicate(TestType2)]
+    type TestType = f64;
+
+    #[duplicate(required_fn2)]
+    fn required_fn(&self) { }
+}
+
+fn main() {
+    let s = MyStruct { number: 42 };
+    s.required_fn();
+    s.required_fn2();
+    s.provided_fn();
+    s.provided_fn2();
+
+    let s = MyCopy { number: 42 };
+}