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
use class_deriviation_generator::generate_class_initializer;
use method_generator::AbstractMethodGenerator;
use proc_macro::{self, TokenStream};
use quote::quote;
use syn::parse_macro_input;

mod class_deriviation_generator;
mod funcall_generator;
mod method_generator;
mod name_generator;
mod tuple;

#[proc_macro]
pub fn define_tuples(_item: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let definitions: Vec<_> = (1..=32).map(|i| tuple::define_tuple(i)).collect();

    let q = quote::quote! {
        #(
            #definitions
        )*
    };
    q.into()
}

#[proc_macro_attribute]
pub fn wrap(attrs: TokenStream, input: TokenStream) -> TokenStream {
    let class_initializer =
        proc_macro2::TokenStream::from(generate_class_initializer(attrs, input.clone()));

    let input = proc_macro2::TokenStream::from(input);

    let tokens = quote! {
        #[derive(minutus::MrbData)]
        #input

        #class_initializer
    };
    tokens.into()
}

#[proc_macro_derive(MrbData)]
pub fn derive_data(input: TokenStream) -> TokenStream {
    class_deriviation_generator::derive_data(input)
}

#[proc_macro_attribute]
pub fn class_method(_attr: TokenStream, input: TokenStream) -> TokenStream {
    let original_function_definition = proc_macro2::TokenStream::from(input.clone());
    let signature = parse_macro_input!(input as syn::ItemFn).sig;
    let method_generator = method_generator::ClassMethodGenerator { sig: signature };
    let externed_function = method_generator.generate_externed_function();
    let method_define_function = method_generator.generate_method_define_function();

    let output = quote! {
        #original_function_definition
        #externed_function
        #method_define_function
    };
    output.into()
}

#[proc_macro_attribute]
pub fn method(_attr: TokenStream, input: TokenStream) -> TokenStream {
    let original_function_definition = proc_macro2::TokenStream::from(input.clone());
    let signature = parse_macro_input!(input as syn::ItemFn).sig;
    let method_generator = method_generator::InstanceMethodGenerator { sig: signature };
    let externed_function = method_generator.generate_externed_function();
    let method_define_function = method_generator.generate_method_define_function();

    let output = quote! {
        #original_function_definition
        #externed_function
        #method_define_function
    };
    output.into()
}

#[proc_macro]
pub fn extern_methods(input: TokenStream) -> TokenStream {
    funcall_generator::generate_methods(input)
}

#[proc_macro]
pub fn define_funcall(input: TokenStream) -> TokenStream {
    funcall_generator::define_funcall(input)
}