proc_macro_api_test_base/
lib.rs

1#![no_implicit_prelude]
2#![no_std]
3
4extern crate proc_macro;
5
6/// ```no_run
7/// # macro_rules! a {
8/// #     ($vis:vis) => {
9/// $vis fn b(_) -> _ {}
10/// $vis fn c(_, _) -> _ {}
11/// $vis mod a {
12///     pub fn b(_) -> _ {}
13///     pub fn c(_, _) -> _ {}
14///     pub mod a { ... }
15/// }
16/// #     };
17/// # }
18/// ```
19/// Nesting the above `mod a`.
20/// The number of the `mod`s equals the number of the input `tt`s.
21/// The innermost `mod` is empty.
22///
23/// * When `b()` is called with a non-empty `TokenStream`,
24/// it always generates a `const D_NUM: usize`.
25/// * When `b()` is called with an empty `TokenStream`,
26/// it always returns a `usize`.
27/// * `c()` always replaces the input item with a `const NUM: usize`.
28///
29/// Those `usize` values are respectively equal to the
30/// nest-depths of the functions that output them.
31/// The nest-depth of the outermost function is 0.
32#[macro_export]
33macro_rules! dummy_api {
34    ($vis:vis mod $($count_down:tt)*) => {
35        $crate::dummy_api_inner! {
36            proc_macro [] $vis mod $($count_down)*
37        }
38    };
39
40    ($vis:vis pm2 mod $($count_down:tt)*) => {
41        $crate::dummy_api_inner! {
42            proc_macro2 [] $vis mod $($count_down)*
43        }
44    };
45}
46
47#[doc(hidden)]
48#[macro_export]
49macro_rules! dummy_api_inner {
50    ($pm:ident [ $($count:tt)* ] $vis:vis mod $tt:tt $($count_down:tt)*) => {
51        #[allow(dead_code)]
52        #[inline(always)]
53        $vis fn b(input: ::$pm::TokenStream) -> ::$pm::TokenStream {
54            use ::quote::quote;
55            use ::core::convert::Into as _;
56
57            const NUM: usize = const { 0usize $($count 1usize)* };
58
59            if input.is_empty() {
60                quote! { #NUM }.into()
61            } else {
62                quote! {
63                    const D_NUM: usize = #NUM;
64                }.into()
65            }
66        }
67
68        #[allow(dead_code)]
69        #[inline(always)]
70        $vis fn c(
71            _: ::$pm::TokenStream,
72            _: ::$pm::TokenStream,
73        ) -> ::$pm::TokenStream {
74            use ::quote::quote;
75            use ::core::convert::Into as _;
76
77            const NUM: usize = const { 0usize $($count 1usize)* };
78
79            quote! {
80                const NUM: usize = #NUM;
81            }.into()
82        }
83
84        #[allow(dead_code)]
85        $vis mod a {
86            $crate::dummy_api_inner! {
87                $pm [ $($count)* + ] pub mod $($count_down)*
88            }
89        }
90    };
91
92    ($($tt:tt)*) => {};
93}
94
95pub mod pm2 {
96    // 11 non-empty `mod`
97    dummy_api!(pub pm2 mod ,,,,,,,,,,,,);
98}
99
100// 11 non-empty `mod`
101dummy_api!(pub mod ,,,,,,,,,,,,);