mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Add tests for MultiItemDecorator
This commit is contained in:
parent
2e07b0d6be
commit
01172eedfa
@ -16,11 +16,10 @@
|
|||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
extern crate rustc;
|
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::codemap::Span;
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::parse::token;
|
use syntax::parse::{self, token};
|
||||||
use syntax::parse;
|
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use rustc::plugin::Registry;
|
use rustc::plugin::Registry;
|
||||||
|
|
||||||
@ -40,6 +39,9 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||||||
reg.register_syntax_extension(
|
reg.register_syntax_extension(
|
||||||
token::intern("into_multi_foo"),
|
token::intern("into_multi_foo"),
|
||||||
MultiModifier(box expand_into_foo_multi));
|
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])
|
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> {
|
fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult+'static> {
|
||||||
use syntax::ext::quote::rt::*;
|
use syntax::ext::quote::rt::*;
|
||||||
|
|
||||||
|
52
src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
Normal file
52
src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs
Normal file
@ -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 };
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user