rust/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs

131 lines
3.7 KiB
Rust
Raw Normal View History

// Copyright 2017 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.
// force-host
// no-prefer-dynamic
#![feature(proc_macro)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::{TokenStream, TokenTree, TokenNode, Delimiter, Literal};
#[proc_macro_attribute]
pub fn foo(attr: TokenStream, input: TokenStream) -> TokenStream {
assert!(attr.is_empty());
let input = input.into_iter().collect::<Vec<_>>();
{
let mut cursor = &input[..];
assert_inline(&mut cursor);
assert_doc(&mut cursor);
assert_inline(&mut cursor);
assert_doc(&mut cursor);
assert_foo(&mut cursor);
assert!(cursor.is_empty());
}
fold_stream(input.into_iter().collect())
}
#[proc_macro_attribute]
pub fn bar(attr: TokenStream, input: TokenStream) -> TokenStream {
assert!(attr.is_empty());
let input = input.into_iter().collect::<Vec<_>>();
{
let mut cursor = &input[..];
assert_inline(&mut cursor);
assert_doc(&mut cursor);
assert_invoc(&mut cursor);
assert_inline(&mut cursor);
assert_doc(&mut cursor);
assert_foo(&mut cursor);
assert!(cursor.is_empty());
}
input.into_iter().collect()
}
fn assert_inline(slice: &mut &[TokenTree]) {
match slice[0].kind {
TokenNode::Op('#', _) => {}
_ => panic!("expected '#' char"),
}
match slice[1].kind {
TokenNode::Group(Delimiter::Bracket, _) => {}
_ => panic!("expected brackets"),
}
*slice = &slice[2..];
}
fn assert_doc(slice: &mut &[TokenTree]) {
match slice[0].kind {
TokenNode::Literal(_) => {}
_ => panic!("expected literal doc comment got other"),
}
*slice = &slice[1..];
}
fn assert_invoc(slice: &mut &[TokenTree]) {
match slice[0].kind {
TokenNode::Op('#', _) => {}
_ => panic!("expected '#' char"),
}
match slice[1].kind {
TokenNode::Group(Delimiter::Bracket, _) => {}
_ => panic!("expected brackets"),
}
*slice = &slice[2..];
}
fn assert_foo(slice: &mut &[TokenTree]) {
match slice[0].kind {
TokenNode::Term(ref name) => assert_eq!(name.as_str(), "fn"),
_ => panic!("expected fn"),
}
match slice[1].kind {
TokenNode::Term(ref name) => assert_eq!(name.as_str(), "foo"),
_ => panic!("expected foo"),
}
match slice[2].kind {
TokenNode::Group(Delimiter::Parenthesis, ref s) => assert!(s.is_empty()),
_ => panic!("expected parens"),
}
match slice[3].kind {
TokenNode::Group(Delimiter::Brace, _) => {}
_ => panic!("expected braces"),
}
*slice = &slice[4..];
}
fn fold_stream(input: TokenStream) -> TokenStream {
input.into_iter().map(fold_tree).collect()
}
fn fold_tree(input: TokenTree) -> TokenTree {
TokenTree {
span: input.span,
kind: fold_node(input.kind),
}
}
fn fold_node(input: TokenNode) -> TokenNode {
match input {
TokenNode::Group(a, b) => TokenNode::Group(a, fold_stream(b)),
TokenNode::Op(a, b) => TokenNode::Op(a, b),
TokenNode::Term(a) => TokenNode::Term(a),
TokenNode::Literal(a) => {
if a.to_string() != "\"foo\"" {
TokenNode::Literal(a)
} else {
TokenNode::Literal(Literal::integer(3))
}
}
}
}