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