syn_solidity/yul/stmt/
var_decl.rs1use crate::{utils::DebugPunctuated, Spanned, WalrusToken, YulExpr, YulIdent};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5 parse::{Parse, ParseStream},
6 punctuated::Punctuated,
7 Result, Token,
8};
9
10#[derive(Clone)]
21pub struct YulVarDecl {
22 pub let_token: Token![let],
23 pub vars: Punctuated<YulIdent, Token![,]>,
24 pub init_value: Option<(WalrusToken, YulExpr)>,
25}
26
27impl Parse for YulVarDecl {
28 fn parse(input: ParseStream<'_>) -> Result<Self> {
29 let let_token = input.parse()?;
30 let vars = Punctuated::parse_separated_nonempty(input)?;
31 let init_value = if input.peek(Token![:]) && input.peek2(Token![=]) {
32 Some((input.parse()?, input.parse()?))
33 } else {
34 None
35 };
36
37 if vars.len() > 1
38 && init_value.as_ref().is_some_and(|(_, expr)| !matches!(expr, YulExpr::Call(_)))
39 {
40 return Err(
41 input.error("Multiple variables can only be initialized by a function call")
42 );
43 }
44
45 Ok(Self { let_token, vars, init_value })
46 }
47}
48
49impl Spanned for YulVarDecl {
50 fn span(&self) -> Span {
51 let span = self.let_token.span();
52 if let Some((_, expr)) = &self.init_value {
53 span.join(expr.span()).unwrap_or(span)
54 } else {
55 span.join(self.vars.span()).unwrap_or(span)
56 }
57 }
58
59 fn set_span(&mut self, span: Span) {
60 self.let_token.set_span(span);
61 self.vars.set_span(span);
62 if let Some((walrus_token, init_value)) = &mut self.init_value {
63 walrus_token.set_span(span);
64 init_value.set_span(span);
65 }
66 }
67}
68
69impl fmt::Debug for YulVarDecl {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.debug_struct("YulVarDecl")
72 .field("vars", DebugPunctuated::new(&self.vars))
73 .field("init_value", &self.init_value.as_ref().map(|(_, expr)| expr))
74 .finish()
75 }
76}