sway_ast/item/
item_trait.rs

1use sway_error::handler::ErrorEmitted;
2
3use crate::priv_prelude::*;
4
5#[derive(Clone, Debug, Serialize)]
6pub enum ItemTraitItem {
7    Fn(FnSignature, Option<SemicolonToken>),
8    Const(ItemConst, Option<SemicolonToken>),
9    Type(TraitType, Option<SemicolonToken>),
10    // to handle parser recovery: Error represents an incomplete trait item
11    Error(Box<[Span]>, #[serde(skip_serializing)] ErrorEmitted),
12}
13
14impl ItemTraitItem {
15    /// [ItemTraitItem]'s friendly name string used for various reportings.
16    pub fn friendly_name(&self) -> &'static str {
17        use ItemTraitItem::*;
18        match self {
19            Fn(..) => "function signature",
20            Const(..) => "associated constant",
21            Type(..) => "associated type",
22            Error(..) => "error",
23        }
24    }
25}
26
27#[derive(Clone, Debug, Serialize)]
28pub struct ItemTrait {
29    pub visibility: Option<PubToken>,
30    pub trait_token: TraitToken,
31    pub name: Ident,
32    pub generics: Option<GenericParams>,
33    pub where_clause_opt: Option<WhereClause>,
34    pub super_traits: Option<(ColonToken, Traits)>,
35    pub trait_items: Braces<Vec<Annotated<ItemTraitItem>>>,
36    pub trait_defs_opt: Option<Braces<Vec<Annotated<ItemFn>>>>,
37}
38
39impl Spanned for ItemTrait {
40    fn span(&self) -> Span {
41        let start = match &self.visibility {
42            Some(pub_token) => pub_token.span(),
43            None => self.trait_token.span(),
44        };
45        let end = match &self.trait_defs_opt {
46            Some(trait_defs) => trait_defs.span(),
47            None => self.trait_items.span(),
48        };
49        Span::join(start, &end)
50    }
51}
52
53impl Spanned for ItemTraitItem {
54    fn span(&self) -> Span {
55        match self {
56            ItemTraitItem::Fn(fn_decl, semicolon) => match semicolon.as_ref().map(|x| x.span()) {
57                Some(semicolon) => Span::join(fn_decl.span(), &semicolon),
58                None => fn_decl.span(),
59            },
60            ItemTraitItem::Const(const_decl, semicolon) => {
61                match semicolon.as_ref().map(|x| x.span()) {
62                    Some(semicolon) => Span::join(const_decl.span(), &semicolon),
63                    None => const_decl.span(),
64                }
65            }
66            ItemTraitItem::Type(type_decl, semicolon) => {
67                match semicolon.as_ref().map(|x| x.span()) {
68                    Some(semicolon) => Span::join(type_decl.span(), &semicolon),
69                    None => type_decl.span(),
70                }
71            }
72            ItemTraitItem::Error(spans, _) => Span::join_all(spans.iter().cloned()),
73        }
74    }
75}
76
77#[derive(Clone, Debug, Serialize)]
78pub struct Traits {
79    pub prefix: PathType,
80    pub suffixes: Vec<(AddToken, PathType)>,
81}
82
83impl Traits {
84    pub fn iter(&self) -> impl Iterator<Item = &PathType> {
85        vec![&self.prefix]
86            .into_iter()
87            .chain(self.suffixes.iter().map(|(_add_token, path)| path))
88    }
89
90    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PathType> {
91        vec![&mut self.prefix]
92            .into_iter()
93            .chain(self.suffixes.iter_mut().map(|(_add_token, path)| path))
94    }
95}
96
97impl Spanned for Traits {
98    fn span(&self) -> Span {
99        match self.suffixes.last() {
100            Some((_add_token, path_type)) => Span::join(self.prefix.span(), &path_type.span()),
101            None => self.prefix.span(),
102        }
103    }
104}