mago_syntax/ast/ast/
partial_application.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::argument::PartialArgumentList;
8use crate::ast::ast::class_like::member::ClassLikeMemberSelector;
9use crate::ast::ast::expression::Expression;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
12#[serde(tag = "type", content = "value")]
13pub enum PartialApplication<'arena> {
14 Function(FunctionPartialApplication<'arena>),
15 Method(MethodPartialApplication<'arena>),
16 StaticMethod(StaticMethodPartialApplication<'arena>),
17}
18
19#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
20pub struct FunctionPartialApplication<'arena> {
21 pub function: &'arena Expression<'arena>,
22 pub argument_list: PartialArgumentList<'arena>,
23}
24
25#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
26pub struct MethodPartialApplication<'arena> {
27 pub object: &'arena Expression<'arena>,
28 pub arrow: Span,
29 pub method: ClassLikeMemberSelector<'arena>,
30 pub argument_list: PartialArgumentList<'arena>,
31}
32
33#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
34pub struct StaticMethodPartialApplication<'arena> {
35 pub class: &'arena Expression<'arena>,
36 pub double_colon: Span,
37 pub method: ClassLikeMemberSelector<'arena>,
38 pub argument_list: PartialArgumentList<'arena>,
39}
40
41impl<'arena> PartialApplication<'arena> {
42 #[inline]
43 #[must_use]
44 pub fn is_first_class_callable(&self) -> bool {
45 self.get_argument_list().is_first_class_callable()
46 }
47
48 #[inline]
49 #[must_use]
50 pub fn get_argument_list(&self) -> &PartialArgumentList<'arena> {
51 match self {
52 PartialApplication::Function(f) => &f.argument_list,
53 PartialApplication::Method(m) => &m.argument_list,
54 PartialApplication::StaticMethod(s) => &s.argument_list,
55 }
56 }
57}
58
59impl HasSpan for PartialApplication<'_> {
60 fn span(&self) -> Span {
61 match self {
62 PartialApplication::Function(f) => f.span(),
63 PartialApplication::Method(m) => m.span(),
64 PartialApplication::StaticMethod(s) => s.span(),
65 }
66 }
67}
68
69impl HasSpan for FunctionPartialApplication<'_> {
70 fn span(&self) -> Span {
71 self.function.span().join(self.argument_list.span())
72 }
73}
74
75impl HasSpan for MethodPartialApplication<'_> {
76 fn span(&self) -> Span {
77 self.object.span().join(self.argument_list.span())
78 }
79}
80
81impl HasSpan for StaticMethodPartialApplication<'_> {
82 fn span(&self) -> Span {
83 self.class.span().join(self.argument_list.span())
84 }
85}