From 01172eedfab32b24e38aa86ba0cba24453e842fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Tue, 20 Jan 2015 20:10:55 +0100 Subject: [PATCH] Add tests for MultiItemDecorator --- src/test/auxiliary/macro_crate_test.rs | 85 ++++++++++++++++++- .../macro-crate-multi-decorator.rs | 52 ++++++++++++ 2 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs 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) +{ + 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 { 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 or the MIT license +// , 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 }; +}