1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#![forbid(unsafe_code)]
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::{abort_call_site, proc_macro_error};
use quote::quote;
use syn::{parse_macro_input, visit_mut::VisitMut, File};
use crate::pre_attr::PreAttrVisitor;
mod call;
mod call_handling;
mod documentation;
mod extern_crate;
mod helpers;
mod pre_attr;
mod precondition;
cfg_if::cfg_if! {
if #[cfg(nightly)] {
mod const_generics_impl;
pub(crate) use crate::const_generics_impl::{render_assure, render_pre};
} else {
mod struct_impl;
pub(crate) use crate::struct_impl::{render_assure, render_pre};
}
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn pre(attr: TokenStream, file: TokenStream) -> TokenStream {
let dummy_file: TokenStream2 = file.clone().into();
proc_macro_error::set_dummy(quote! {
#dummy_file
});
let mut file = parse_macro_input!(file as File);
PreAttrVisitor::new(attr.into()).visit_file_mut(&mut file);
let output = quote! {
#file
};
proc_macro_error::set_dummy(quote! {
#output
});
output.into()
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn assure(_: TokenStream, _: TokenStream) -> TokenStream {
abort_call_site!(
"this attribute by itself is currently non-functional";
help = "use it on an expression in an item wrapped by a `pre` attribute"
)
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn forward(_: TokenStream, _: TokenStream) -> TokenStream {
abort_call_site!(
"this attribute by itself is currently non-functional";
help = "use it on an expression in an item wrapped by a `pre` attribute"
)
}
#[proc_macro_attribute]
#[proc_macro_error]
pub fn extern_crate(attr: TokenStream, module: TokenStream) -> TokenStream {
let attr = parse_macro_input!(attr as extern_crate::ExternCrateAttr);
let module = parse_macro_input!(module as extern_crate::Module);
let output = module.render(attr);
proc_macro_error::set_dummy(quote! {
#output
});
output.into()
}