syn_solidity/attribute/
mod.rs1use crate::{kw, utils::DebugPunctuated, Expr, SolPath, Spanned};
2use proc_macro2::Span;
3use std::{
4 fmt,
5 hash::{Hash, Hasher},
6};
7use syn::{
8 parenthesized,
9 parse::{Parse, ParseStream},
10 punctuated::Punctuated,
11 token::Paren,
12 Result, Token,
13};
14
15mod function;
16pub use function::{FunctionAttribute, FunctionAttributes};
17
18mod variable;
19pub use variable::{VariableAttribute, VariableAttributes};
20
21kw_enum! {
22 pub enum Storage {
24 Memory(kw::memory),
25 Storage(kw::storage),
26 Calldata(kw::calldata),
27 }
28}
29
30kw_enum! {
31 pub enum Visibility {
33 External(kw::external),
34 Public(kw::public),
35 Internal(kw::internal),
36 Private(kw::private),
37 }
38}
39
40kw_enum! {
41 pub enum Mutability {
43 Pure(kw::pure),
44 View(kw::view),
45 Constant(kw::constant),
46 Payable(kw::payable),
47 }
48}
49
50#[derive(Clone, PartialEq, Eq, Hash)]
52pub struct Override {
53 pub override_token: Token![override],
54 pub paren_token: Option<Paren>,
55 pub paths: Punctuated<SolPath, Token![,]>,
56}
57
58impl fmt::Display for Override {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.write_str("override")?;
61 if self.paren_token.is_some() {
62 f.write_str("(")?;
63 for (i, path) in self.paths.iter().enumerate() {
64 if i > 0 {
65 f.write_str(", ")?;
66 }
67 path.fmt(f)?;
68 }
69 f.write_str(")")?;
70 }
71 Ok(())
72 }
73}
74
75impl fmt::Debug for Override {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 f.debug_tuple("Override").field(DebugPunctuated::new(&self.paths)).finish()
78 }
79}
80
81impl Parse for Override {
82 fn parse(input: ParseStream<'_>) -> Result<Self> {
83 let override_token = input.parse()?;
84 let this = if input.peek(Paren) {
85 let content;
86 Self {
87 override_token,
88 paren_token: Some(parenthesized!(content in input)),
89 paths: content.parse_terminated(SolPath::parse, Token![,])?,
90 }
91 } else {
92 Self { override_token, paren_token: None, paths: Default::default() }
93 };
94 Ok(this)
95 }
96}
97
98impl Spanned for Override {
99 fn span(&self) -> Span {
100 let span = self.override_token.span;
101 self.paren_token.and_then(|paren_token| span.join(paren_token.span.join())).unwrap_or(span)
102 }
103
104 fn set_span(&mut self, span: Span) {
105 self.override_token.span = span;
106 if let Some(paren_token) = &mut self.paren_token {
107 *paren_token = Paren(span);
108 }
109 }
110}
111
112#[derive(Clone)]
114pub struct Modifier {
115 pub name: SolPath,
116 pub paren_token: Option<Paren>,
117 pub arguments: Punctuated<Expr, Token![,]>,
118}
119
120impl PartialEq for Modifier {
121 fn eq(&self, other: &Self) -> bool {
122 self.name == other.name
123 }
124}
125
126impl Eq for Modifier {}
127
128impl Hash for Modifier {
129 fn hash<H: Hasher>(&self, state: &mut H) {
130 self.name.hash(state);
131 }
132}
133
134impl fmt::Display for Modifier {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 self.name.fmt(f)?;
137 if self.paren_token.is_some() {
138 f.write_str("(")?;
139 for (i, _arg) in self.arguments.iter().enumerate() {
140 if i > 0 {
141 f.write_str(", ")?;
142 }
143 f.write_str("<expr>")?;
145 }
146 f.write_str(")")?;
147 }
148 Ok(())
149 }
150}
151
152impl fmt::Debug for Modifier {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 f.debug_struct("Modifier")
155 .field("name", &self.name)
156 .field("arguments", DebugPunctuated::new(&self.arguments))
157 .finish()
158 }
159}
160
161impl Parse for Modifier {
162 fn parse(input: ParseStream<'_>) -> Result<Self> {
163 let name = input.parse()?;
164 let this = if input.peek(Paren) {
165 let content;
166 let paren_token = parenthesized!(content in input);
167 let arguments = content.parse_terminated(Expr::parse, Token![,])?;
168 Self { name, paren_token: Some(paren_token), arguments }
169 } else {
170 Self { name, paren_token: None, arguments: Punctuated::new() }
171 };
172 Ok(this)
173 }
174}
175
176impl Spanned for Modifier {
177 fn span(&self) -> Span {
178 let span = self.name.span();
179 self.paren_token.and_then(|paren_token| span.join(paren_token.span.join())).unwrap_or(span)
180 }
181
182 fn set_span(&mut self, span: Span) {
183 self.name.set_span(span);
184 if let Some(paren_token) = &mut self.paren_token {
185 *paren_token = Paren(span);
186 }
187 }
188}