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")]
13#[repr(u8)]
14pub enum PartialApplication<'arena> {
15 Function(FunctionPartialApplication<'arena>),
16 Method(MethodPartialApplication<'arena>),
17 StaticMethod(StaticMethodPartialApplication<'arena>),
18}
19
20#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
21pub struct FunctionPartialApplication<'arena> {
22 pub function: &'arena Expression<'arena>,
23 pub argument_list: PartialArgumentList<'arena>,
24}
25
26#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
27pub struct MethodPartialApplication<'arena> {
28 pub object: &'arena Expression<'arena>,
29 pub arrow: Span,
30 pub method: ClassLikeMemberSelector<'arena>,
31 pub argument_list: PartialArgumentList<'arena>,
32}
33
34#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
35pub struct StaticMethodPartialApplication<'arena> {
36 pub class: &'arena Expression<'arena>,
37 pub double_colon: Span,
38 pub method: ClassLikeMemberSelector<'arena>,
39 pub argument_list: PartialArgumentList<'arena>,
40}
41
42impl<'arena> PartialApplication<'arena> {
43 #[inline]
44 #[must_use]
45 pub fn is_first_class_callable(&self) -> bool {
46 self.get_argument_list().is_first_class_callable()
47 }
48
49 #[inline]
50 #[must_use]
51 pub fn get_argument_list(&self) -> &PartialArgumentList<'arena> {
52 match self {
53 PartialApplication::Function(f) => &f.argument_list,
54 PartialApplication::Method(m) => &m.argument_list,
55 PartialApplication::StaticMethod(s) => &s.argument_list,
56 }
57 }
58}
59
60impl HasSpan for PartialApplication<'_> {
61 fn span(&self) -> Span {
62 match self {
63 PartialApplication::Function(f) => f.span(),
64 PartialApplication::Method(m) => m.span(),
65 PartialApplication::StaticMethod(s) => s.span(),
66 }
67 }
68}
69
70impl HasSpan for FunctionPartialApplication<'_> {
71 fn span(&self) -> Span {
72 self.function.span().join(self.argument_list.span())
73 }
74}
75
76impl HasSpan for MethodPartialApplication<'_> {
77 fn span(&self) -> Span {
78 self.object.span().join(self.argument_list.span())
79 }
80}
81
82impl HasSpan for StaticMethodPartialApplication<'_> {
83 fn span(&self) -> Span {
84 self.class.span().join(self.argument_list.span())
85 }
86}