Skip to content

Commit 01172ee

Browse files
committed
Add tests for MultiItemDecorator
1 parent 2e07b0d commit 01172ee

File tree

2 files changed

+134
-3
lines changed

2 files changed

+134
-3
lines changed

src/test/auxiliary/macro_crate_test.rs

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616
extern crate syntax;
1717
extern crate rustc;
1818

19-
use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
19+
use syntax::ast::{self, TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
2020
use syntax::codemap::Span;
2121
use syntax::ext::base::*;
22-
use syntax::parse::token;
23-
use syntax::parse;
22+
use syntax::parse::{self, token};
2423
use syntax::ptr::P;
2524
use rustc::plugin::Registry;
2625

@@ -40,6 +39,9 @@ pub fn plugin_registrar(reg: &mut Registry) {
4039
reg.register_syntax_extension(
4140
token::intern("into_multi_foo"),
4241
MultiModifier(box expand_into_foo_multi));
42+
reg.register_syntax_extension(
43+
token::intern("duplicate"),
44+
MultiDecorator(box expand_duplicate));
4345
}
4446

4547
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
@@ -92,6 +94,83 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
9294
}
9395
}
9496

97+
// Create a duplicate of the annotatable, based on the MetaItem
98+
fn expand_duplicate(cx: &mut ExtCtxt,
99+
sp: Span,
100+
mi: &MetaItem,
101+
it: &Annotatable,
102+
mut push: Box<FnMut(Annotatable)>)
103+
{
104+
let copy_name = match mi.node {
105+
ast::MetaItem_::MetaList(_, ref xs) => {
106+
if let ast::MetaItem_::MetaWord(ref w) = xs[0].node {
107+
token::str_to_ident(w.get())
108+
} else {
109+
cx.span_err(mi.span, "Expected word");
110+
return;
111+
}
112+
}
113+
_ => {
114+
cx.span_err(mi.span, "Expected list");
115+
return;
116+
}
117+
};
118+
119+
// Duplicate the item but replace its ident by the MetaItem
120+
match it.clone() {
121+
Annotatable::Item(it) => {
122+
let mut new_it = (*it).clone();
123+
new_it.attrs.clear();
124+
new_it.ident = copy_name;
125+
push(Annotatable::Item(P(new_it)));
126+
}
127+
Annotatable::ImplItem(it) => {
128+
match it {
129+
ImplItem::MethodImplItem(m) => {
130+
let mut new_m = (*m).clone();
131+
new_m.attrs.clear();
132+
replace_method_name(&mut new_m.node, copy_name);
133+
push(Annotatable::ImplItem(ImplItem::MethodImplItem(P(new_m))));
134+
}
135+
ImplItem::TypeImplItem(t) => {
136+
let mut new_t = (*t).clone();
137+
new_t.attrs.clear();
138+
new_t.ident = copy_name;
139+
push(Annotatable::ImplItem(ImplItem::TypeImplItem(P(new_t))));
140+
}
141+
}
142+
}
143+
Annotatable::TraitItem(it) => {
144+
match it {
145+
TraitItem::RequiredMethod(rm) => {
146+
let mut new_rm = rm.clone();
147+
new_rm.attrs.clear();
148+
new_rm.ident = copy_name;
149+
push(Annotatable::TraitItem(TraitItem::RequiredMethod(new_rm)));
150+
}
151+
TraitItem::ProvidedMethod(pm) => {
152+
let mut new_pm = (*pm).clone();
153+
new_pm.attrs.clear();
154+
replace_method_name(&mut new_pm.node, copy_name);
155+
push(Annotatable::TraitItem(TraitItem::ProvidedMethod(P(new_pm))));
156+
}
157+
TraitItem::TypeTraitItem(t) => {
158+
let mut new_t = (*t).clone();
159+
new_t.attrs.clear();
160+
new_t.ty_param.ident = copy_name;
161+
push(Annotatable::TraitItem(TraitItem::TypeTraitItem(P(new_t))));
162+
}
163+
}
164+
}
165+
}
166+
167+
fn replace_method_name(m: &mut ast::Method_, i: ast::Ident) {
168+
if let &mut ast::Method_::MethDecl(ref mut ident, _, _, _, _, _, _, _) = m {
169+
*ident = i
170+
}
171+
}
172+
}
173+
95174
fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult+'static> {
96175
use syntax::ext::quote::rt::*;
97176

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:macro_crate_test.rs
12+
// ignore-stage1
13+
14+
#![feature(plugin)]
15+
16+
#[plugin] #[no_link]
17+
extern crate macro_crate_test;
18+
19+
// The duplicate macro will create a copy of the item with the given identifier
20+
#[duplicate(MyCopy)]
21+
struct MyStruct {
22+
number: i32
23+
}
24+
25+
trait TestTrait {
26+
#[duplicate(TestType2)]
27+
type TestType;
28+
29+
#[duplicate(required_fn2)]
30+
fn required_fn(&self);
31+
32+
#[duplicate(provided_fn2)]
33+
fn provided_fn(&self) { }
34+
}
35+
36+
impl TestTrait for MyStruct {
37+
#[duplicate(TestType2)]
38+
type TestType = f64;
39+
40+
#[duplicate(required_fn2)]
41+
fn required_fn(&self) { }
42+
}
43+
44+
fn main() {
45+
let s = MyStruct { number: 42 };
46+
s.required_fn();
47+
s.required_fn2();
48+
s.provided_fn();
49+
s.provided_fn2();
50+
51+
let s = MyCopy { number: 42 };
52+
}

0 commit comments

Comments
 (0)