Skip to main content

mago_syntax/cst/cst/class_like/
trait_use.rs

1use strum::Display;
2
3use mago_span::HasSpan;
4use mago_span::Span;
5
6use crate::cst::cst::identifier::Identifier;
7use crate::cst::cst::identifier::LocalIdentifier;
8use crate::cst::cst::keyword::Keyword;
9use crate::cst::cst::modifier::Modifier;
10use crate::cst::cst::terminator::Terminator;
11use crate::cst::sequence::Sequence;
12use crate::cst::sequence::TokenSeparatedSequence;
13
14#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize))]
16pub struct TraitUse<'arena> {
17    pub r#use: Keyword<'arena>,
18    pub trait_names: TokenSeparatedSequence<'arena, Identifier<'arena>>,
19    pub specification: TraitUseSpecification<'arena>,
20}
21
22#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize))]
24#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
25pub enum TraitUseSpecification<'arena> {
26    Abstract(TraitUseAbstractSpecification<'arena>),
27    Concrete(TraitUseConcreteSpecification<'arena>),
28}
29
30#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize))]
32pub struct TraitUseAbstractSpecification<'arena>(pub Terminator<'arena>);
33
34#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize))]
36pub struct TraitUseConcreteSpecification<'arena> {
37    pub left_brace: Span,
38    pub adaptations: Sequence<'arena, TraitUseAdaptation<'arena>>,
39    pub right_brace: Span,
40}
41
42#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize))]
44#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
45pub enum TraitUseAdaptation<'arena> {
46    Precedence(TraitUsePrecedenceAdaptation<'arena>),
47    Alias(TraitUseAliasAdaptation<'arena>),
48}
49
50#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize))]
52pub struct TraitUsePrecedenceAdaptation<'arena> {
53    pub method_reference: TraitUseAbsoluteMethodReference<'arena>,
54    pub insteadof: Keyword<'arena>,
55    pub trait_names: TokenSeparatedSequence<'arena, Identifier<'arena>>,
56    pub terminator: Terminator<'arena>,
57}
58
59#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
60#[cfg_attr(feature = "serde", derive(serde::Serialize))]
61pub struct TraitUseAliasAdaptation<'arena> {
62    pub method_reference: TraitUseMethodReference<'arena>,
63    pub r#as: Keyword<'arena>,
64    pub modifier: Option<Modifier<'arena>>,
65    pub alias: Option<LocalIdentifier<'arena>>,
66    pub terminator: Terminator<'arena>,
67}
68
69#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
70#[cfg_attr(feature = "serde", derive(serde::Serialize))]
71#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
72pub enum TraitUseMethodReference<'arena> {
73    Identifier(LocalIdentifier<'arena>),
74    Absolute(TraitUseAbsoluteMethodReference<'arena>),
75}
76
77#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
78#[cfg_attr(feature = "serde", derive(serde::Serialize))]
79pub struct TraitUseAbsoluteMethodReference<'arena> {
80    pub trait_name: Identifier<'arena>,
81    pub double_colon: Span,
82    pub method_name: LocalIdentifier<'arena>,
83}
84
85impl HasSpan for TraitUse<'_> {
86    fn span(&self) -> Span {
87        Span::between(self.r#use.span(), self.specification.span())
88    }
89}
90
91impl HasSpan for TraitUseSpecification<'_> {
92    fn span(&self) -> Span {
93        match self {
94            TraitUseSpecification::Abstract(specification) => specification.span(),
95            TraitUseSpecification::Concrete(specification) => specification.span(),
96        }
97    }
98}
99
100impl HasSpan for TraitUseAbstractSpecification<'_> {
101    fn span(&self) -> Span {
102        self.0.span()
103    }
104}
105
106impl HasSpan for TraitUseConcreteSpecification<'_> {
107    fn span(&self) -> Span {
108        Span::between(self.left_brace, self.right_brace)
109    }
110}
111
112impl HasSpan for TraitUseAdaptation<'_> {
113    fn span(&self) -> Span {
114        match self {
115            TraitUseAdaptation::Precedence(adaptation) => adaptation.span(),
116            TraitUseAdaptation::Alias(adaptation) => adaptation.span(),
117        }
118    }
119}
120
121impl HasSpan for TraitUsePrecedenceAdaptation<'_> {
122    fn span(&self) -> Span {
123        Span::between(self.method_reference.span(), self.terminator.span())
124    }
125}
126
127impl HasSpan for TraitUseAliasAdaptation<'_> {
128    fn span(&self) -> Span {
129        self.method_reference.span().join(self.terminator.span())
130    }
131}
132
133impl HasSpan for TraitUseMethodReference<'_> {
134    fn span(&self) -> Span {
135        match self {
136            TraitUseMethodReference::Identifier(identifier) => identifier.span(),
137            TraitUseMethodReference::Absolute(absolute) => absolute.span(),
138        }
139    }
140}
141
142impl HasSpan for TraitUseAbsoluteMethodReference<'_> {
143    fn span(&self) -> Span {
144        Span::between(self.trait_name.span(), self.method_name.span())
145    }
146}