Skip to content

Commit

Permalink
fix(macros): integration test passes
Browse files Browse the repository at this point in the history
  • Loading branch information
tbraun96 committed Dec 7, 2024
1 parent 581fbbe commit 35026ac
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 25 deletions.
55 changes: 41 additions & 14 deletions macros/blueprint-proc-macro/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,21 +230,21 @@ pub(crate) fn generate_event_workflow_tokenstream(
// convert the listener var, which is just a struct name, to an ident
let listener = listener_meta.listener.to_token_stream();

// Raw events have no pre-processor, therefore their inputs are passed directly into the job function
// and NOT as job params
let is_raw = listener_meta.is_raw();

// Generate the variable that we are passing as the context into EventListener::create(&mut ctx)
// We assume the first supplied event handler arg is the context we are injecting into the event listener
// Then, pass that into the EventFlowWrapper
let fn_name_ident = &input.sig.ident;
let static_ctx_get_override = quote! { CTX.get().unwrap() };
let mut ordered_inputs =
get_fn_call_ordered(param_types, params, Some(static_ctx_get_override))?;
let (ctx_pos_in_ordered_inputs, mut ordered_inputs) =
get_fn_call_ordered(param_types, params, Some(static_ctx_get_override), is_raw)?;

let asyncness = get_asyncness(input);
let call_id_static_name = get_current_call_id_field_name(input);

// Raw events have no pre-processor, therefore their inputs are passed directly into the job function
// and NOT as job params
let is_raw = listener_meta.is_raw();

// TODO: task 001: find better way to identify which ident is the raw event
// for now, we assume the raw event is always listed first
if is_raw {
Expand All @@ -257,7 +257,12 @@ pub(crate) fn generate_event_workflow_tokenstream(
// If is_raw, assume the actual context is the second param
quote! { ctx. #field_in_self .clone() }
})
.ok_or_else(|| syn::Error::new(Span::call_site(), "Must specify a context"))?;
.ok_or_else(|| {
syn::Error::new(
Span::call_site(),
"Must specify a context (field_in_self_getter)",
)
})?;

let autogen_struct_name = quote! { #struct_name };

Expand Down Expand Up @@ -295,6 +300,7 @@ pub(crate) fn generate_event_workflow_tokenstream(
&call_id_static_name,
&asyncness,
&return_type,
ctx_pos_in_ordered_inputs,
)?,

ListenerType::Evm => get_evm_job_processor_wrapper(
Expand All @@ -312,7 +318,7 @@ pub(crate) fn generate_event_workflow_tokenstream(

quote! {
move |param0| async move {
let res = #fn_name_ident (#(#ordered_inputs)*) #asyncness;
let res = #fn_name_ident (#(#ordered_inputs),*) #asyncness;
#job_processor_call_return
}
}
Expand Down Expand Up @@ -568,7 +574,8 @@ pub fn get_fn_call_ordered(
param_types: &IndexMap<Ident, Type>,
params_from_job_args: &[Ident],
replacement_for_self: Option<proc_macro2::TokenStream>,
) -> syn::Result<Vec<proc_macro2::TokenStream>> {
is_raw: bool,
) -> syn::Result<(usize, Vec<proc_macro2::TokenStream>)> {
let (event_handler_args, _) = get_event_handler_args(param_types, params_from_job_args)?;

let additional_var_indexes: Vec<usize> =
Expand All @@ -583,6 +590,8 @@ pub fn get_fn_call_ordered(

// This has all params
let mut job_var_idx = 0;
let mut non_job_var_count = 0;
let mut ctx_pos = None;
let this = replacement_for_self.unwrap_or_else(|| quote! { self });
let ret = param_types
.iter()
Expand All @@ -595,25 +604,43 @@ pub fn get_fn_call_ordered(
if is_job_var {
let ident = format_ident!("param{job_var_idx}");
job_var_idx += 1;
return quote! { #ident, };
return quote! { #ident };
}

let (is_ref, is_ref_mut) = match ty {
Type::Reference(r) => (true, r.mutability.is_some()),
_ => (false, false),
};

if non_job_var_count == 0 {
// Assume first non-job var is the context
ctx_pos = Some(pos_in_all_args);
}

non_job_var_count += 1;

if is_ref && is_ref_mut {
quote! { &mut #this .#ident, }
quote! { &mut #this .#ident }
} else if is_ref {
quote! { &#this .#ident, }
quote! { &#this .#ident }
} else {
quote! { #this .#ident.clone(), }
quote! { #this .#ident.clone() }
}
})
.collect::<Vec<_>>();

Ok(ret)
if is_raw {
ctx_pos = Some(1); // Raw events have only two events: 0 = the raw event, 1 = the context
}

let ctx_pos = ctx_pos.ok_or_else(|| {
syn::Error::new(
Span::call_site(),
"Could not find the context in the function signature",
)
})?;

Ok((ctx_pos, ret))
}

fn get_asyncness(input: &ItemFn) -> proc_macro2::TokenStream {
Expand Down
2 changes: 1 addition & 1 deletion macros/blueprint-proc-macro/src/special_impls/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub(crate) fn get_evm_job_processor_wrapper(
quote! {
let inputs = param0;
#(#params_tokens)*
let res = #fn_name_ident (#(#ordered_inputs)*) #asyncness;
let res = #fn_name_ident (#(#ordered_inputs),*) #asyncness;
}
};

Expand Down
34 changes: 24 additions & 10 deletions macros/blueprint-proc-macro/src/special_impls/tangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ pub(crate) fn get_tangle_job_processor_wrapper(
event_listeners: &EventListenerArgs,
ordered_inputs: &mut Vec<TokenStream>,
fn_name_ident: &Ident,
call_id_static_name: &Ident,
_call_id_static_name: &Ident,
asyncness: &TokenStream,
return_type: &Type,
ctx_post_in_ordered_inputs: usize,
) -> syn::Result<TokenStream> {
let params = declared_params_to_field_types(job_params, param_map)?;
let params_tokens = event_listeners.get_param_name_tokenstream(&params);
Expand All @@ -91,37 +92,50 @@ pub(crate) fn get_tangle_job_processor_wrapper(
const PARAMETER_COUNT: usize = #parameter_count;
};

// let non_job_param_map = get_non_job_arguments(param_map, job_params);

let injected_context = ordered_inputs[ctx_post_in_ordered_inputs].clone();
let call_id_injector = quote! {
let mut injected_context = #injected_context;
if let Some(call_id) = tangle_event.call_id {
injected_context.set_call_id(call_id);
}
};

ordered_inputs[ctx_post_in_ordered_inputs] = quote! { injected_context };

let job_processor_call = if params_tokens.is_empty() {
let second_param = ordered_inputs
.pop()
.ok_or_else(|| syn::Error::new(Span::call_site(), "Context type required"))?;
quote! {
#call_id_injector
// If no args are specified, assume this job has no parameters and thus takes in the raw event
let res = #fn_name_ident (param0, #second_param) #asyncness;
let res = #fn_name_ident (tangle_event, #second_param) #asyncness;
}
} else {
quote! {
#parameter_count_const

if param0.args.len() != PARAMETER_COUNT {
if tangle_event.args.len() != PARAMETER_COUNT {
return Err(
::gadget_sdk::Error::BadArgumentDecoding(format!("Parameter count mismatch, got `{}`, expected `{PARAMETER_COUNT}`", param0.args.len()))
::gadget_sdk::Error::BadArgumentDecoding(format!("Parameter count mismatch, got `{}`, expected `{PARAMETER_COUNT}`", tangle_event.args.len()))
);
}

let mut args = param0.args.into_iter();
let mut args = tangle_event.args.clone().into_iter();
#(#params_tokens)*
let res = #fn_name_ident (#(#ordered_inputs)*) #asyncness;

#call_id_injector

let res = #fn_name_ident (#(#ordered_inputs),*) #asyncness;
}
};

let job_processor_call_return = get_return_type_wrapper(return_type);

Ok(quote! {
move |param0: gadget_sdk::event_listener::tangle::TangleEvent<_, _>| async move {
if let Some(call_id) = param0.call_id {
#call_id_static_name.store(call_id, std::sync::atomic::Ordering::Relaxed);
}
move |tangle_event: gadget_sdk::event_listener::tangle::TangleEvent<_, _>| async move {

#job_processor_call
#job_processor_call_return
Expand Down

0 comments on commit 35026ac

Please sign in to comment.