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

https://gitlab.com/jianglu/rust · Rust · 161 lines · 135 code · 15 blank · 11 comment · 19 complexity · ac01fb6a7d8b84c7e24b4c3a13b94a12 MD5 · raw file

  1. // Copyright 2017 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. // force-host
  11. // no-prefer-dynamic
  12. #![feature(proc_macro)]
  13. #![crate_type = "proc-macro"]
  14. extern crate proc_macro;
  15. use proc_macro::{TokenStream, TokenTree, Delimiter, Literal, Spacing, Group};
  16. #[proc_macro_attribute]
  17. pub fn foo(attr: TokenStream, input: TokenStream) -> TokenStream {
  18. assert!(attr.is_empty());
  19. let input = input.into_iter().collect::<Vec<_>>();
  20. {
  21. let mut cursor = &input[..];
  22. assert_inline(&mut cursor);
  23. assert_doc(&mut cursor);
  24. assert_inline(&mut cursor);
  25. assert_doc(&mut cursor);
  26. assert_foo(&mut cursor);
  27. assert!(cursor.is_empty());
  28. }
  29. fold_stream(input.into_iter().collect())
  30. }
  31. #[proc_macro_attribute]
  32. pub fn bar(attr: TokenStream, input: TokenStream) -> TokenStream {
  33. assert!(attr.is_empty());
  34. let input = input.into_iter().collect::<Vec<_>>();
  35. {
  36. let mut cursor = &input[..];
  37. assert_inline(&mut cursor);
  38. assert_doc(&mut cursor);
  39. assert_invoc(&mut cursor);
  40. assert_inline(&mut cursor);
  41. assert_doc(&mut cursor);
  42. assert_foo(&mut cursor);
  43. assert!(cursor.is_empty());
  44. }
  45. input.into_iter().collect()
  46. }
  47. fn assert_inline(slice: &mut &[TokenTree]) {
  48. match &slice[0] {
  49. TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'),
  50. _ => panic!("expected '#' char"),
  51. }
  52. match &slice[1] {
  53. TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Bracket),
  54. _ => panic!("expected brackets"),
  55. }
  56. *slice = &slice[2..];
  57. }
  58. fn assert_doc(slice: &mut &[TokenTree]) {
  59. match &slice[0] {
  60. TokenTree::Punct(tt) => {
  61. assert_eq!(tt.as_char(), '#');
  62. assert_eq!(tt.spacing(), Spacing::Alone);
  63. }
  64. _ => panic!("expected #"),
  65. }
  66. let inner = match &slice[1] {
  67. TokenTree::Group(tt) => {
  68. assert_eq!(tt.delimiter(), Delimiter::Bracket);
  69. tt.stream()
  70. }
  71. _ => panic!("expected brackets"),
  72. };
  73. let tokens = inner.into_iter().collect::<Vec<_>>();
  74. let tokens = &tokens[..];
  75. if tokens.len() != 3 {
  76. panic!("expected three tokens in doc")
  77. }
  78. match &tokens[0] {
  79. TokenTree::Ident(tt) => assert_eq!("doc", &*tt.to_string()),
  80. _ => panic!("expected `doc`"),
  81. }
  82. match &tokens[1] {
  83. TokenTree::Punct(tt) => {
  84. assert_eq!(tt.as_char(), '=');
  85. assert_eq!(tt.spacing(), Spacing::Alone);
  86. }
  87. _ => panic!("expected equals"),
  88. }
  89. match tokens[2] {
  90. TokenTree::Literal(_) => {}
  91. _ => panic!("expected literal"),
  92. }
  93. *slice = &slice[2..];
  94. }
  95. fn assert_invoc(slice: &mut &[TokenTree]) {
  96. match &slice[0] {
  97. TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'),
  98. _ => panic!("expected '#' char"),
  99. }
  100. match &slice[1] {
  101. TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Bracket),
  102. _ => panic!("expected brackets"),
  103. }
  104. *slice = &slice[2..];
  105. }
  106. fn assert_foo(slice: &mut &[TokenTree]) {
  107. match &slice[0] {
  108. TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "fn"),
  109. _ => panic!("expected fn"),
  110. }
  111. match &slice[1] {
  112. TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "foo"),
  113. _ => panic!("expected foo"),
  114. }
  115. match &slice[2] {
  116. TokenTree::Group(tt) => {
  117. assert_eq!(tt.delimiter(), Delimiter::Parenthesis);
  118. assert!(tt.stream().is_empty());
  119. }
  120. _ => panic!("expected parens"),
  121. }
  122. match &slice[3] {
  123. TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Brace),
  124. _ => panic!("expected braces"),
  125. }
  126. *slice = &slice[4..];
  127. }
  128. fn fold_stream(input: TokenStream) -> TokenStream {
  129. input.into_iter().map(fold_tree).collect()
  130. }
  131. fn fold_tree(input: TokenTree) -> TokenTree {
  132. match input {
  133. TokenTree::Group(b) => {
  134. TokenTree::Group(Group::new(b.delimiter(), fold_stream(b.stream())))
  135. }
  136. TokenTree::Punct(b) => TokenTree::Punct(b),
  137. TokenTree::Ident(a) => TokenTree::Ident(a),
  138. TokenTree::Literal(a) => {
  139. if a.to_string() != "\"foo\"" {
  140. TokenTree::Literal(a)
  141. } else {
  142. TokenTree::Literal(Literal::i32_unsuffixed(3))
  143. }
  144. }
  145. }
  146. }