syn_solidity/stmt/
assembly.rs

1use crate::{kw, utils::DebugPunctuated, LitStr, Spanned, YulBlock};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5    parse::{Parse, ParseStream},
6    punctuated::Punctuated,
7    token::Paren,
8    Result, Token,
9};
10
11/// An assembly block, with optional flags: `assembly "evmasm" { ... }`.
12#[derive(Clone)]
13pub struct StmtAssembly {
14    pub assembly_token: kw::assembly,
15    pub literal: Option<LitStr>,
16    pub flags: Option<AssemblyFlags>,
17    pub block: YulBlock,
18}
19
20impl fmt::Debug for StmtAssembly {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        f.debug_struct("StmtAssembly")
23            .field("literal", &self.literal)
24            .field("flags", &self.flags)
25            .field("block", &self.block)
26            .finish()
27    }
28}
29
30impl Parse for StmtAssembly {
31    fn parse(input: ParseStream<'_>) -> Result<Self> {
32        Ok(Self {
33            assembly_token: input.parse()?,
34            literal: input.call(LitStr::parse_opt)?,
35            flags: input.call(AssemblyFlags::parse_opt)?,
36            block: input.parse()?,
37        })
38    }
39}
40
41impl Spanned for StmtAssembly {
42    fn span(&self) -> Span {
43        let span = self.assembly_token.span;
44        span.join(self.block.span()).unwrap_or(span)
45    }
46
47    fn set_span(&mut self, span: Span) {
48        self.assembly_token.span = span;
49        self.block.set_span(span);
50    }
51}
52
53/// A list of flags of an assembly statement.
54#[derive(Clone)]
55pub struct AssemblyFlags {
56    pub paren_token: Paren,
57    pub strings: Punctuated<LitStr, Token![,]>,
58}
59
60impl fmt::Debug for AssemblyFlags {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.debug_struct("AssemblyFlags")
63            .field("strings", DebugPunctuated::new(&self.strings))
64            .finish()
65    }
66}
67
68impl Parse for AssemblyFlags {
69    fn parse(input: ParseStream<'_>) -> Result<Self> {
70        let content;
71        Ok(Self {
72            paren_token: syn::parenthesized!(content in input),
73            strings: content.parse_terminated(LitStr::parse, Token![,])?,
74        })
75    }
76}
77
78impl Spanned for AssemblyFlags {
79    fn span(&self) -> Span {
80        self.paren_token.span.join()
81    }
82
83    fn set_span(&mut self, span: Span) {
84        self.paren_token = Paren(span);
85    }
86}
87
88impl AssemblyFlags {
89    pub fn parse_opt(input: ParseStream<'_>) -> Result<Option<Self>> {
90        if input.peek(Paren) {
91            input.parse().map(Some)
92        } else {
93            Ok(None)
94        }
95    }
96}