syn_solidity/yul/stmt/
assignment.rs

1use crate::{utils::DebugPunctuated, Spanned, WalrusToken, YulExpr, YulPath};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5    parse::{Parse, ParseStream},
6    punctuated::Punctuated,
7    Result, Token,
8};
9
10/// Yul variable assignment. `x := 0` or `x, y := foo()`.
11/// Assigning values to multiple variables requires a function call.
12///
13/// Solidity Reference:
14/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.yulAssignment>
15#[derive(Clone)]
16pub struct YulVarAssign {
17    pub vars: Punctuated<YulPath, Token![,]>,
18    pub walrus_token: WalrusToken,
19    pub assigned_value: YulExpr,
20}
21
22impl Parse for YulVarAssign {
23    fn parse(input: ParseStream<'_>) -> Result<Self> {
24        let vars = Punctuated::parse_separated_nonempty(input)?;
25        let walrus_token = input.parse()?;
26        let assigned_value = input.parse()?;
27
28        if vars.len() > 1 && !matches!(assigned_value, YulExpr::Call(_)) {
29            return Err(input.error("Multiple variables require a function call for assignment"));
30        }
31
32        Ok(Self { vars, walrus_token, assigned_value })
33    }
34}
35
36impl Spanned for YulVarAssign {
37    fn span(&self) -> Span {
38        let span = self.vars.span();
39        span.join(self.assigned_value.span()).unwrap_or(span)
40    }
41
42    fn set_span(&mut self, span: Span) {
43        self.vars.set_span(span);
44        self.walrus_token.set_span(span);
45        self.assigned_value.set_span(span);
46    }
47}
48
49impl fmt::Debug for YulVarAssign {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        f.debug_struct("YulVarAssign")
52            .field("vars", DebugPunctuated::new(&self.vars))
53            .field("assigned_value", &self.assigned_value)
54            .finish()
55    }
56}