sway_ast/
attribute.rs

1use crate::priv_prelude::*;
2
3#[derive(Clone, Debug, Serialize)]
4pub struct Annotated<T> {
5    pub attribute_list: Vec<AttributeDecl>,
6    pub value: T,
7}
8
9// Attributes can have any number of arguments:
10//
11//    #[attribute]
12//    #[attribute()]
13//    #[attribute(value)]
14//    #[attribute(value0, value1, value2)]
15
16#[derive(Clone, Debug, Serialize)]
17pub struct AttributeDecl {
18    pub hash_kind: AttributeHashKind,
19    pub attribute: SquareBrackets<Punctuated<Attribute, CommaToken>>,
20}
21
22impl Spanned for AttributeDecl {
23    fn span(&self) -> Span {
24        let hash_span = match &self.hash_kind {
25            AttributeHashKind::Inner(hash_bang_token) => hash_bang_token.span(),
26            AttributeHashKind::Outer(hash_token) => hash_token.span(),
27        };
28        Span::join(hash_span, &self.attribute.span())
29    }
30}
31
32/// Denotes the target direction of an [AttributeDecl] and
33/// the hash token kind associated.
34///
35/// Example:
36/// ```sway
37/// // outer (after), written as `///`
38/// #[doc("a Sway struct")]
39/// struct Foo {}
40///
41/// // inner (before), written as `//!`
42/// enum Bar {}
43/// #![doc("a Sway enum")]
44/// ```
45#[derive(Clone, Debug, Serialize)]
46pub enum AttributeHashKind {
47    /// Inner specifies that the attribute belongs to
48    /// the item before it.
49    Inner(HashBangToken),
50    /// Outer specifies that the attribute belongs to
51    /// the item after it.
52    Outer(HashToken),
53}
54
55#[derive(Clone, Debug, Serialize)]
56pub struct AttributeArg {
57    pub name: Ident,
58    pub value: Option<Literal>,
59}
60
61impl Spanned for AttributeArg {
62    fn span(&self) -> Span {
63        if let Some(value) = &self.value {
64            Span::join(self.name.span(), &value.span())
65        } else {
66            self.name.span()
67        }
68    }
69}
70
71#[derive(Clone, Debug, Serialize)]
72pub struct Attribute {
73    pub name: Ident,
74    pub args: Option<Parens<Punctuated<AttributeArg, CommaToken>>>,
75}
76
77impl Spanned for Attribute {
78    fn span(&self) -> Span {
79        self.args
80            .as_ref()
81            .map(|args| Span::join(self.name.span(), &args.span()))
82            .unwrap_or_else(|| self.name.span())
83    }
84}