sway_ast/item/
item_trait.rs

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