syn_solidity/yul/type/
function.rs1use crate::{Spanned, YulBlock, YulIdent, kw, utils::DebugPunctuated};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5 Result, Token, parenthesized,
6 parse::{Parse, ParseStream},
7 punctuated::Punctuated,
8 token::Paren,
9};
10
11#[derive(Clone)]
16pub struct YulFunctionDef {
17 pub function_token: kw::function,
18 pub ident: YulIdent,
19 pub paren_token: Paren,
20 pub arguments: Punctuated<YulIdent, Token![,]>,
21 pub returns: Option<YulReturns>,
22 pub body: YulBlock,
23}
24
25impl Parse for YulFunctionDef {
26 fn parse(input: ParseStream<'_>) -> Result<Self> {
27 let content;
28 Ok(Self {
29 function_token: input.parse()?,
30 ident: input.parse()?,
31 paren_token: parenthesized!(content in input),
32 arguments: Punctuated::parse_terminated(&content)?,
33 returns: input.call(YulReturns::parse_opt)?,
34 body: input.parse()?,
35 })
36 }
37}
38
39impl Spanned for YulFunctionDef {
40 fn span(&self) -> Span {
41 let span = self.function_token.span();
42 span.join(self.body.span()).unwrap_or(span)
43 }
44
45 fn set_span(&mut self, span: Span) {
46 self.function_token.set_span(span);
47 self.ident.set_span(span);
48 self.paren_token = Paren(span);
49 self.arguments.set_span(span);
50 self.returns.set_span(span);
51 self.body.set_span(span);
52 }
53}
54
55impl fmt::Debug for YulFunctionDef {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.debug_struct("YulFunctionDef")
58 .field("ident", &self.ident)
59 .field("arguments", DebugPunctuated::new(&self.arguments))
60 .field("returns", &self.returns)
61 .field("body", &self.body)
62 .finish()
63 }
64}
65
66#[derive(Clone)]
68pub struct YulReturns {
69 pub arrow_token: Token![->],
70 pub returns: Punctuated<YulIdent, Token![,]>,
71}
72
73impl YulReturns {
74 pub fn parse_opt(input: ParseStream<'_>) -> Result<Option<Self>> {
75 if input.peek(Token![->]) {
76 Ok(Some(Self {
77 arrow_token: input.parse()?,
78 returns: Punctuated::parse_separated_nonempty(input)?,
79 }))
80 } else {
81 Ok(None)
82 }
83 }
84}
85
86impl Parse for YulReturns {
87 fn parse(input: ParseStream<'_>) -> Result<Self> {
88 Ok(Self {
89 arrow_token: input.parse()?,
90 returns: Punctuated::parse_separated_nonempty(input)?,
91 })
92 }
93}
94
95impl Spanned for YulReturns {
96 fn span(&self) -> Span {
97 let span = self.arrow_token.span();
98 span.join(self.returns.span()).unwrap_or(span)
99 }
100
101 fn set_span(&mut self, span: Span) {
102 self.arrow_token.set_span(span);
103 self.returns.set_span(span);
104 }
105}
106
107impl fmt::Debug for YulReturns {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 f.debug_struct("YulReturns").field("returns", DebugPunctuated::new(&self.returns)).finish()
110 }
111}