rtic_macros/codegen/
util.rs
1use crate::syntax::{ast::App, Context};
2use core::sync::atomic::{AtomicUsize, Ordering};
3use proc_macro2::{Span, TokenStream as TokenStream2};
4use quote::quote;
5use syn::{Ident, PatType};
6
7const RTIC_INTERNAL: &str = "__rtic_internal";
8
9pub fn mark_internal_name(name: &str) -> Ident {
11 Ident::new(&format!("{RTIC_INTERNAL}_{name}"), Span::call_site())
12}
13
14pub fn internal_task_ident(task: &Ident, ident_name: &str) -> Ident {
16 mark_internal_name(&format!("{task}_{ident_name}"))
17}
18
19fn link_section_index() -> usize {
20 static INDEX: AtomicUsize = AtomicUsize::new(0);
21
22 INDEX.fetch_add(1, Ordering::Relaxed)
23}
24
25pub fn link_section_uninit() -> TokenStream2 {
27 let section = format!(".uninit.rtic{}", link_section_index());
28
29 quote!(#[link_section = #section])
30}
31
32pub fn regroup_inputs(
36 inputs: &[PatType],
37) -> (
38 Vec<TokenStream2>,
40 TokenStream2,
42 Vec<TokenStream2>,
44 TokenStream2,
46) {
47 if inputs.len() == 1 {
48 let ty = &inputs[0].ty;
49
50 (
51 vec![quote!(_0: #ty)],
52 quote!(_0),
53 vec![quote!(_0)],
54 quote!(#ty),
55 )
56 } else {
57 let mut args = vec![];
58 let mut pats = vec![];
59 let mut tys = vec![];
60
61 for (i, input) in inputs.iter().enumerate() {
62 let i = Ident::new(&format!("_{i}"), Span::call_site());
63 let ty = &input.ty;
64
65 args.push(quote!(#i: #ty));
66
67 pats.push(quote!(#i));
68
69 tys.push(quote!(#ty));
70 }
71
72 let tupled = {
73 let pats = pats.clone();
74 quote!((#(#pats,)*))
75 };
76 let ty = quote!((#(#tys,)*));
77 (args, tupled, pats, ty)
78 }
79}
80
81pub fn get_task_name(ctxt: Context, app: &App) -> Ident {
83 let s = match ctxt {
84 Context::Init => app.init.name.to_string(),
85 Context::Idle => app
86 .idle
87 .as_ref()
88 .expect("RTIC-ICE: unable to find idle name")
89 .name
90 .to_string(),
91 Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
92 };
93
94 Ident::new(&s, Span::call_site())
95}
96
97pub fn shared_resources_ident(ctxt: Context, app: &App) -> Ident {
99 let mut s = match ctxt {
100 Context::Init => app.init.name.to_string(),
101 Context::Idle => app
102 .idle
103 .as_ref()
104 .expect("RTIC-ICE: unable to find idle name")
105 .name
106 .to_string(),
107 Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
108 };
109
110 s.push_str("SharedResources");
111
112 mark_internal_name(&s)
113}
114
115pub fn local_resources_ident(ctxt: Context, app: &App) -> Ident {
117 let mut s = match ctxt {
118 Context::Init => app.init.name.to_string(),
119 Context::Idle => app
120 .idle
121 .as_ref()
122 .expect("RTIC-ICE: unable to find idle name")
123 .name
124 .to_string(),
125 Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
126 };
127
128 s.push_str("LocalResources");
129
130 mark_internal_name(&s)
131}
132
133pub fn suffixed(name: &str) -> Ident {
135 let span = Span::call_site();
136 Ident::new(name, span)
137}
138
139pub fn static_shared_resource_ident(name: &Ident) -> Ident {
140 mark_internal_name(&format!("shared_resource_{name}"))
141}
142
143pub fn static_local_resource_ident(name: &Ident) -> Ident {
144 mark_internal_name(&format!("local_resource_{name}"))
145}
146
147pub fn declared_static_local_resource_ident(name: &Ident, task_name: &Ident) -> Ident {
148 mark_internal_name(&format!("local_{task_name}_{name}"))
149}
150
151pub fn need_to_lock_ident(name: &Ident) -> Ident {
152 Ident::new(&format!("{name}_that_needs_to_be_locked"), name.span())
153}
154
155pub fn zero_prio_dispatcher_ident() -> Ident {
156 Ident::new("__rtic_internal_async_0_prio_dispatcher", Span::call_site())
157}
158
159pub fn rt_err_ident() -> Ident {
161 Ident::new(
162 "you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml",
163 Span::call_site(),
164 )
165}
166
167pub fn from_ptr_n_args_ident(n: usize) -> Ident {
168 Ident::new(&format!("from_ptr_{}_args", n + 1), Span::call_site())
169}
170
171pub fn new_n_args_ident(n: usize) -> Ident {
172 Ident::new(&format!("new_{}_args", n + 1), Span::call_site())
173}