aboutsummaryrefslogtreecommitdiff
path: root/macros/src/lib.rs
blob: 86fa509d39766aa0be6dcb96c95c6c3f01cd1635 (plain)
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
mod explain;
mod metadata;

use explain::generate_explain_impl;
use metadata::{generate_meta_impl, RawLintMeta};
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{parse_macro_input, Ident, ItemStruct};

fn generate_self_impl(struct_name: &Ident) -> TokenStream2 {
    quote! {
        impl #struct_name {
            pub fn new() -> Box<Self> {
                Box::new(Self)
            }
        }
    }
}

#[proc_macro_attribute]
pub fn lint(attr: TokenStream, item: TokenStream) -> TokenStream {
    let struct_item = parse_macro_input!(item as ItemStruct);
    let meta = parse_macro_input!(attr as RawLintMeta);

    let struct_name = &struct_item.ident;
    let self_impl = generate_self_impl(struct_name);
    let meta_impl = generate_meta_impl(struct_name, &meta);
    let explain_impl = generate_explain_impl(&struct_item);

    (quote! {
        #struct_item

        ::lazy_static::lazy_static! {
            pub static ref LINT: Box<dyn crate::Lint> = #struct_name::new();
        }

        #self_impl
        #meta_impl
        #explain_impl

        impl crate::Lint for #struct_name {}
    })
    .into()
}