alloy_sol_macro_expander/expand/
var_def.rs
1use super::ExpCtxt;
4use ast::{ItemFunction, ParameterList, Spanned, Type, VariableDeclaration, VariableDefinition};
5use proc_macro2::TokenStream;
6use syn::{Error, Result};
7
8pub(super) fn expand(cx: &ExpCtxt<'_>, var_def: &VariableDefinition) -> Result<TokenStream> {
12 let Some(function) = var_as_function(cx, var_def)? else {
13 return Ok(TokenStream::new());
14 };
15 super::function::expand(cx, &function)
16}
17
18pub(super) fn var_as_function(
19 cx: &ExpCtxt<'_>,
20 var_def: &VariableDefinition,
21) -> Result<Option<ItemFunction>> {
22 if !var_def.attributes.visibility().is_some_and(|v| v.is_public() || v.is_external()) {
24 return Ok(None);
25 }
26
27 let mut function = ItemFunction::from_variable_definition(var_def.clone());
28 expand_returns(cx, &mut function)?;
29 Ok(Some(function))
30}
31
32fn expand_returns(cx: &ExpCtxt<'_>, f: &mut ItemFunction) -> Result<()> {
34 let returns = f.returns.as_mut().expect("generated getter function with no returns");
35 let ret = returns.returns.first_mut().unwrap();
36 if !ret.ty.has_custom_simple() {
37 return Ok(());
38 }
39
40 let mut ty = &ret.ty;
41
42 if let Type::Custom(name) = ty {
44 ty = cx.custom_type(name);
45 }
46 let Type::Tuple(tup) = ty else { return Ok(()) };
47
48 let mut new_returns = ParameterList::new();
51 for p in tup.types.pairs() {
52 let (ty, comma) = p.into_tuple();
53 if !type_is_complex(ty) {
54 new_returns.push_value(VariableDeclaration::new(ty.clone()));
55 if let Some(comma) = comma {
56 new_returns.push_punct(*comma);
57 }
58 }
59 }
60
61 if new_returns.is_empty() {
63 return Err(Error::new(f.name().span(), "invalid state variable type"));
64 }
65
66 returns.returns = new_returns;
67 Ok(())
68}
69
70fn type_is_complex(ty: &Type) -> bool {
104 matches!(ty, Type::Mapping(_) | Type::Array(_))
105}