diff options
Diffstat (limited to 'rtic-macros/src/codegen/init.rs')
-rw-r--r-- | rtic-macros/src/codegen/init.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/rtic-macros/src/codegen/init.rs b/rtic-macros/src/codegen/init.rs new file mode 100644 index 00000000..6e1059f7 --- /dev/null +++ b/rtic-macros/src/codegen/init.rs @@ -0,0 +1,95 @@ +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +use crate::{ + analyze::Analysis, + codegen::{local_resources_struct, module}, + syntax::{ast::App, Context}, +}; + +/// Generates support code for `#[init]` functions +pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { + let init = &app.init; + let name = &init.name; + + let mut root_init = vec![]; + + let context = &init.context; + let attrs = &init.attrs; + let stmts = &init.stmts; + let shared = &init.user_shared_struct; + let local = &init.user_local_struct; + + let shared_resources: Vec<_> = app + .shared_resources + .iter() + .map(|(k, v)| { + let ty = &v.ty; + let cfgs = &v.cfgs; + let docs = &v.docs; + quote!( + #(#cfgs)* + #(#docs)* + #k: #ty, + ) + }) + .collect(); + let local_resources: Vec<_> = app + .local_resources + .iter() + .map(|(k, v)| { + let ty = &v.ty; + let cfgs = &v.cfgs; + let docs = &v.docs; + quote!( + #(#cfgs)* + #(#docs)* + #k: #ty, + ) + }) + .collect(); + + root_init.push(quote! { + struct #shared { + #(#shared_resources)* + } + + struct #local { + #(#local_resources)* + } + }); + + // let locals_pat = locals_pat.iter(); + + let user_init_return = quote! {#shared, #local}; + + let user_init = quote!( + #(#attrs)* + #[inline(always)] + #[allow(non_snake_case)] + fn #name(#context: #name::Context) -> (#user_init_return) { + #(#stmts)* + } + ); + + let mut mod_app = None; + + // `${task}Locals` + if !init.args.local_resources.is_empty() { + let (item, constructor) = local_resources_struct::codegen(Context::Init, app); + + root_init.push(item); + + mod_app = Some(constructor); + } + + root_init.push(module::codegen(Context::Init, app, analysis)); + + quote!( + #mod_app + + #(#root_init)* + + #user_init + ) +} |