Skip to main content

mago_syntax/ast/ast/class_like/
trait_use.rs

1use 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}