1 | // We need to support Rust 1.34 to stable |
2 | #![allow (deprecated)] |
3 | |
4 | #![allow (renamed_and_removed_lints)] // support for multiple Clippy versions |
5 | #![allow (clippy::unknown_clippy_lints)] // because of other #![allow]s |
6 | #![allow (clippy::mem_replace_with_default)] // needs rustc 1.40 |
7 | #![allow (clippy::option_as_ref_deref)] // needs rustc 1.40 |
8 | #![allow (clippy::cyclomatic_complexity)] // old name of cognitive_complexity |
9 | #![allow (clippy::cognitive_complexity)] // in code generated by macros |
10 | #![allow (clippy::redundant_closure)] |
11 | |
12 | extern crate proc_macro; |
13 | extern crate proc_macro2; |
14 | #[macro_use ] |
15 | extern crate syn; |
16 | |
17 | #[macro_use ] |
18 | extern crate quote; |
19 | |
20 | mod ast; |
21 | mod attr; |
22 | mod bound; |
23 | mod clone; |
24 | mod cmp; |
25 | mod debug; |
26 | mod default; |
27 | mod hash; |
28 | mod matcher; |
29 | mod paths; |
30 | mod utils; |
31 | |
32 | use proc_macro::TokenStream; |
33 | |
34 | fn derive_impls( |
35 | input: &mut ast::Input, |
36 | errors: &mut proc_macro2::TokenStream, |
37 | ) -> proc_macro2::TokenStream { |
38 | let mut tokens = proc_macro2::TokenStream::new(); |
39 | |
40 | if input.attrs.clone.is_some() { |
41 | tokens.extend(clone::derive_clone(input)); |
42 | } |
43 | if input.attrs.copy.is_some() { |
44 | tokens.extend(clone::derive_copy(input)); |
45 | } |
46 | if input.attrs.debug.is_some() { |
47 | tokens.extend(debug::derive(input)); |
48 | } |
49 | if let Some(ref default) = input.attrs.default { |
50 | tokens.extend(default::derive(input, default)); |
51 | } |
52 | if input.attrs.eq.is_some() { |
53 | tokens.extend(cmp::derive_eq(input)); |
54 | } |
55 | if input.attrs.hash.is_some() { |
56 | tokens.extend(hash::derive(input)); |
57 | } |
58 | if input.attrs.partial_eq.is_some() { |
59 | tokens.extend(cmp::derive_partial_eq(input)); |
60 | } |
61 | if input.attrs.partial_ord.is_some() { |
62 | tokens.extend(cmp::derive_partial_ord(input, errors)); |
63 | } |
64 | if input.attrs.ord.is_some() { |
65 | tokens.extend(cmp::derive_ord(input, errors)); |
66 | } |
67 | |
68 | tokens.extend(std::mem::replace( |
69 | errors, |
70 | Default::default(), |
71 | )); |
72 | |
73 | tokens |
74 | } |
75 | |
76 | #[cfg_attr (not(test), proc_macro_derive(Derivative, attributes(derivative)))] |
77 | pub fn derivative(input: TokenStream) -> TokenStream { |
78 | let mut errors: TokenStream = proc_macro2::TokenStream::new(); |
79 | |
80 | let mut output: TokenStream = match syn::parse::<syn::DeriveInput>(tokens:input) { |
81 | Ok(parsed: DeriveInput) => { |
82 | astResult::Input::from_ast(&parsed, &mut errors) |
83 | .map(|mut input: Input<'_>| derive_impls(&mut input, &mut errors)) |
84 | .unwrap_or_default() |
85 | }, |
86 | Err(error: Error) => { |
87 | errors.extend(iter:error.to_compile_error()); |
88 | Default::default() |
89 | } |
90 | }; |
91 | |
92 | output.extend(iter:errors); |
93 | output.into() |
94 | } |