Skip to main content

mago_syntax/ast/ast/
yield.rs

1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::expression::Expression;
8use crate::ast::ast::keyword::Keyword;
9
10/// Represents a PHP `yield` expression.
11///
12/// # Examples
13///
14/// ```php
15/// <?php
16///
17/// function gen(): Generator {
18///     yield 1;
19///     yield 2 => 3;
20///     yield from [4, 5];
21/// }
22/// ```
23#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
24#[serde(tag = "type", content = "value")]
25pub enum Yield<'arena> {
26    Value(YieldValue<'arena>),
27    Pair(YieldPair<'arena>),
28    From(YieldFrom<'arena>),
29}
30
31/// Represents a PHP `yield` expression with a value.
32///
33/// # Examples
34///
35/// ```php
36/// <?php
37///
38/// function gen(): Generator {
39///    yield 1;
40/// }
41/// ```
42#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
43pub struct YieldValue<'arena> {
44    pub r#yield: Keyword<'arena>,
45    pub value: Option<&'arena Expression<'arena>>,
46}
47
48/// Represents a PHP `yield` expression with a key-value pair.
49///
50/// # Examples
51///
52/// ```php
53/// <?php
54///
55/// function gen(): Generator {
56///   yield 2 => 3;
57/// }
58/// ```
59#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
60pub struct YieldPair<'arena> {
61    pub r#yield: Keyword<'arena>,
62    pub key: &'arena Expression<'arena>,
63    pub arrow: Span,
64    pub value: &'arena Expression<'arena>,
65}
66
67/// Represents a PHP `yield from` expression.
68///
69/// # Examples
70///
71/// ```php
72/// <?php
73///
74/// function gen(): Generator {
75///  yield from [4, 5];
76/// }
77/// ```
78#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
79pub struct YieldFrom<'arena> {
80    pub r#yield: Keyword<'arena>,
81    pub from: Keyword<'arena>,
82    pub iterator: &'arena Expression<'arena>,
83}
84
85impl HasSpan for Yield<'_> {
86    fn span(&self) -> Span {
87        match self {
88            Yield::Value(y) => y.span(),
89            Yield::Pair(y) => y.span(),
90            Yield::From(y) => y.span(),
91        }
92    }
93}
94
95impl HasSpan for YieldValue<'_> {
96    fn span(&self) -> Span {
97        if let Some(value) = &self.value { self.r#yield.span().join(value.span()) } else { self.r#yield.span() }
98    }
99}
100
101impl HasSpan for YieldPair<'_> {
102    fn span(&self) -> Span {
103        self.r#yield.span().join(self.value.span())
104    }
105}
106
107impl HasSpan for YieldFrom<'_> {
108    fn span(&self) -> Span {
109        self.r#yield.span().join(self.iterator.span())
110    }
111}