mago_syntax/cst/cst/class_like/
trait_use.rs1use 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}