syn_solidity/attribute/
function.rs1use crate::{kw, Modifier, Mutability, Override, SolPath, Spanned, VariableAttribute, Visibility};
2use proc_macro2::Span;
3use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6};
7use syn::{
8 ext::IdentExt,
9 parse::{Parse, ParseStream},
10 token::Brace,
11 Error, Ident, Result, Token,
12};
13
14#[derive(Clone, Default, PartialEq, Eq)]
17pub struct FunctionAttributes(pub Vec<FunctionAttribute>);
18
19impl fmt::Display for FunctionAttributes {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 for (i, attr) in self.0.iter().enumerate() {
22 if i > 0 {
23 f.write_str(" ")?;
24 }
25 write!(f, "{attr}")?;
26 }
27 Ok(())
28 }
29}
30
31impl fmt::Debug for FunctionAttributes {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 self.0.fmt(f)
34 }
35}
36
37impl Deref for FunctionAttributes {
38 type Target = Vec<FunctionAttribute>;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl DerefMut for FunctionAttributes {
46 fn deref_mut(&mut self) -> &mut Self::Target {
47 &mut self.0
48 }
49}
50
51impl Parse for FunctionAttributes {
52 fn parse(input: ParseStream<'_>) -> Result<Self> {
53 let mut attributes = Vec::<FunctionAttribute>::new();
54 while !input.is_empty() && !input.peek(kw::returns) && input.peek(Ident::peek_any) {
55 let attr: FunctionAttribute = input.parse()?;
56 if matches!(
57 attr,
58 FunctionAttribute::Visibility(_)
59 | FunctionAttribute::Mutability(_)
60 | FunctionAttribute::Virtual(_)
61 ) {
62 if let Some(prev) = attributes.iter().find(|a| **a == attr) {
63 let mut e = Error::new(attr.span(), "duplicate attribute");
64 e.combine(Error::new(prev.span(), "previous declaration is here"));
65 return Err(e);
66 }
67 }
68 attributes.push(attr);
69 }
70 Ok(Self(attributes))
71 }
72}
73
74impl Spanned for FunctionAttributes {
75 fn span(&self) -> Span {
76 self.0.span()
77 }
78
79 fn set_span(&mut self, span: Span) {
80 self.0.set_span(span);
81 }
82}
83
84impl FunctionAttributes {
85 #[inline]
86 pub fn new() -> Self {
87 Self(Vec::new())
88 }
89
90 pub fn visibility(&self) -> Option<Visibility> {
91 self.0.iter().find_map(FunctionAttribute::visibility)
92 }
93
94 pub fn mutability(&self) -> Option<Mutability> {
95 self.0.iter().find_map(FunctionAttribute::mutability)
96 }
97
98 pub fn r#override(&self) -> Option<&Override> {
99 self.0.iter().find_map(FunctionAttribute::r#override)
100 }
101
102 pub fn modifier(&self) -> Option<&Modifier> {
103 self.0.iter().find_map(FunctionAttribute::modifier)
104 }
105
106 pub fn has_external(&self) -> bool {
107 self.0.iter().any(FunctionAttribute::is_external)
108 }
109
110 pub fn has_internal(&self) -> bool {
111 self.0.iter().any(FunctionAttribute::is_internal)
112 }
113
114 pub fn has_private(&self) -> bool {
115 self.0.iter().any(FunctionAttribute::is_private)
116 }
117
118 pub fn has_public(&self) -> bool {
119 self.0.iter().any(FunctionAttribute::is_public)
120 }
121
122 pub fn has_virtual(&self) -> bool {
123 self.0.iter().any(FunctionAttribute::is_virtual)
124 }
125
126 pub fn has_override(&self, path: Option<&SolPath>) -> bool {
127 self.0.iter().any(|attr| attr.is_override(path))
128 }
129
130 pub fn has_modifier(&self, path: Option<&SolPath>) -> bool {
131 self.0.iter().any(|attr| attr.is_modifier(path))
132 }
133}
134
135#[derive(Clone, PartialEq, Eq, Hash)]
137pub enum FunctionAttribute {
138 Visibility(Visibility),
140 Mutability(Mutability),
142 Modifier(Modifier),
144 Virtual(Token![virtual]),
146 Override(Override),
148}
149
150impl fmt::Display for FunctionAttribute {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 match self {
153 Self::Visibility(visibility) => visibility.fmt(f),
154 Self::Mutability(mutability) => mutability.fmt(f),
155 Self::Virtual(_) => f.write_str("virtual"),
156 Self::Override(o) => o.fmt(f),
157 Self::Modifier(modifier) => modifier.fmt(f),
158 }
159 }
160}
161
162impl fmt::Debug for FunctionAttribute {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 match self {
165 Self::Visibility(visibility) => f.debug_tuple("Visibility").field(visibility).finish(),
166 Self::Mutability(mutability) => f.debug_tuple("Mutability").field(mutability).finish(),
167 Self::Virtual(_) => f.write_str("Virtual"),
168 Self::Override(o) => o.fmt(f),
169 Self::Modifier(modifier) => modifier.fmt(f),
170 }
171 }
172}
173
174impl Parse for FunctionAttribute {
175 fn parse(input: ParseStream<'_>) -> Result<Self> {
176 let lookahead = input.lookahead1();
177 if Visibility::peek(&lookahead) {
178 input.parse().map(Self::Visibility)
179 } else if Mutability::peek(&lookahead) {
180 input.parse().map(Self::Mutability)
181 } else if lookahead.peek(Token![virtual]) {
182 input.parse().map(Self::Virtual)
183 } else if lookahead.peek(Token![override]) {
184 input.parse().map(Self::Override)
185 } else if !input.peek(kw::returns) && lookahead.peek(Ident::peek_any) {
186 input.parse().map(Self::Modifier)
187 } else if input.peek(Brace) {
188 Err(input.error("functions cannot have an implementation"))
190 } else {
191 Err(lookahead.error())
192 }
193 }
194}
195
196impl From<VariableAttribute> for FunctionAttribute {
197 fn from(value: VariableAttribute) -> Self {
202 match value {
203 VariableAttribute::Visibility(v) => Self::Visibility(v),
204 VariableAttribute::Constant(c) => Self::Mutability(Mutability::new_pure(c.span)),
205 VariableAttribute::Immutable(i) => Self::Mutability(Mutability::new_view(i.span)),
206 VariableAttribute::Override(o) => Self::Override(o),
207 }
208 }
209}
210
211impl Spanned for FunctionAttribute {
212 fn span(&self) -> Span {
213 match self {
214 Self::Visibility(v) => v.span(),
215 Self::Mutability(m) => m.span(),
216 Self::Virtual(v) => v.span,
217 Self::Override(o) => o.span(),
218 Self::Modifier(m) => m.span(),
219 }
220 }
221
222 fn set_span(&mut self, span: Span) {
223 match self {
224 Self::Visibility(v) => v.set_span(span),
225 Self::Mutability(m) => m.set_span(span),
226 Self::Virtual(v) => v.span = span,
227 Self::Override(o) => o.set_span(span),
228 Self::Modifier(m) => m.set_span(span),
229 }
230 }
231}
232
233impl FunctionAttribute {
234 #[inline]
235 pub const fn visibility(&self) -> Option<Visibility> {
236 match self {
237 Self::Visibility(v) => Some(*v),
238 _ => None,
239 }
240 }
241
242 #[inline]
243 pub const fn mutability(&self) -> Option<Mutability> {
244 match self {
245 Self::Mutability(m) => Some(*m),
246 _ => None,
247 }
248 }
249
250 #[inline]
251 pub const fn r#override(&self) -> Option<&Override> {
252 match self {
253 Self::Override(o) => Some(o),
254 _ => None,
255 }
256 }
257
258 #[inline]
259 pub const fn modifier(&self) -> Option<&Modifier> {
260 match self {
261 Self::Modifier(m) => Some(m),
262 _ => None,
263 }
264 }
265
266 #[inline]
267 pub const fn is_external(&self) -> bool {
268 matches!(self, Self::Visibility(Visibility::External(_)))
269 }
270
271 #[inline]
272 pub const fn is_public(&self) -> bool {
273 matches!(self, Self::Visibility(Visibility::Public(_)))
274 }
275
276 #[inline]
277 pub const fn is_internal(&self) -> bool {
278 matches!(self, Self::Visibility(Visibility::Internal(_)))
279 }
280
281 #[inline]
282 pub const fn is_private(&self) -> bool {
283 matches!(self, Self::Visibility(Visibility::Private(_)))
284 }
285
286 #[inline]
287 pub const fn is_virtual(&self) -> bool {
288 matches!(self, Self::Virtual(_))
289 }
290
291 #[inline]
292 pub fn is_override(&self, path: Option<&SolPath>) -> bool {
293 self.r#override().is_some_and(|o| match path {
294 Some(path) => o.paths.iter().any(|p| p == path),
295 None => true,
296 })
297 }
298
299 #[inline]
300 pub fn is_modifier(&self, path: Option<&SolPath>) -> bool {
301 self.modifier().is_some_and(|m| match path {
302 Some(path) => m.name == *path,
303 None => true,
304 })
305 }
306}