syn_solidity/attribute/
mod.rsuse crate::{kw, utils::DebugPunctuated, Expr, SolPath, Spanned};
use proc_macro2::Span;
use std::{
fmt,
hash::{Hash, Hasher},
};
use syn::{
parenthesized,
parse::{Parse, ParseStream},
punctuated::Punctuated,
token::Paren,
Result, Token,
};
mod function;
pub use function::{FunctionAttribute, FunctionAttributes};
mod variable;
pub use variable::{VariableAttribute, VariableAttributes};
kw_enum! {
pub enum Storage {
Memory(kw::memory),
Storage(kw::storage),
Calldata(kw::calldata),
}
}
kw_enum! {
pub enum Visibility {
External(kw::external),
Public(kw::public),
Internal(kw::internal),
Private(kw::private),
}
}
kw_enum! {
pub enum Mutability {
Pure(kw::pure),
View(kw::view),
Constant(kw::constant),
Payable(kw::payable),
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Override {
pub override_token: Token![override],
pub paren_token: Option<Paren>,
pub paths: Punctuated<SolPath, Token![,]>,
}
impl fmt::Display for Override {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("override")?;
if self.paren_token.is_some() {
f.write_str("(")?;
for (i, path) in self.paths.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
path.fmt(f)?;
}
f.write_str(")")?;
}
Ok(())
}
}
impl fmt::Debug for Override {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Override").field(DebugPunctuated::new(&self.paths)).finish()
}
}
impl Parse for Override {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let override_token = input.parse()?;
let this = if input.peek(Paren) {
let content;
Self {
override_token,
paren_token: Some(parenthesized!(content in input)),
paths: content.parse_terminated(SolPath::parse, Token![,])?,
}
} else {
Self { override_token, paren_token: None, paths: Default::default() }
};
Ok(this)
}
}
impl Spanned for Override {
fn span(&self) -> Span {
let span = self.override_token.span;
self.paren_token.and_then(|paren_token| span.join(paren_token.span.join())).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.override_token.span = span;
if let Some(paren_token) = &mut self.paren_token {
*paren_token = Paren(span);
}
}
}
#[derive(Clone)]
pub struct Modifier {
pub name: SolPath,
pub paren_token: Option<Paren>,
pub arguments: Punctuated<Expr, Token![,]>,
}
impl PartialEq for Modifier {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl Eq for Modifier {}
impl Hash for Modifier {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl fmt::Display for Modifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.fmt(f)?;
if self.paren_token.is_some() {
f.write_str("(")?;
for (i, _arg) in self.arguments.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
f.write_str("<expr>")?;
}
f.write_str(")")?;
}
Ok(())
}
}
impl fmt::Debug for Modifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Modifier")
.field("name", &self.name)
.field("arguments", DebugPunctuated::new(&self.arguments))
.finish()
}
}
impl Parse for Modifier {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let name = input.parse()?;
let this = if input.peek(Paren) {
let content;
let paren_token = parenthesized!(content in input);
let arguments = content.parse_terminated(Expr::parse, Token![,])?;
Self { name, paren_token: Some(paren_token), arguments }
} else {
Self { name, paren_token: None, arguments: Punctuated::new() }
};
Ok(this)
}
}
impl Spanned for Modifier {
fn span(&self) -> Span {
let span = self.name.span();
self.paren_token.and_then(|paren_token| span.join(paren_token.span.join())).unwrap_or(span)
}
fn set_span(&mut self, span: Span) {
self.name.set_span(span);
if let Some(paren_token) = &mut self.paren_token {
*paren_token = Paren(span);
}
}
}