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