boa_ast/expression/
yield.rs1use boa_interner::{Interner, ToInternedString};
2use core::ops::ControlFlow;
3
4use crate::{
5 Span, Spanned,
6 visitor::{VisitWith, Visitor, VisitorMut},
7};
8
9use super::Expression;
10
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
21#[derive(Clone, Debug, PartialEq)]
22pub struct Yield {
23 target: Option<Box<Expression>>,
24 delegate: bool,
25 span: Span,
26}
27
28impl Yield {
29 #[inline]
31 #[must_use]
32 pub fn new(expr: Option<Expression>, delegate: bool, span: Span) -> Self {
33 Self {
34 target: expr.map(Box::new),
35 delegate,
36 span,
37 }
38 }
39
40 #[inline]
42 pub fn target(&self) -> Option<&Expression> {
43 self.target.as_ref().map(Box::as_ref)
44 }
45
46 #[inline]
48 #[must_use]
49 pub const fn delegate(&self) -> bool {
50 self.delegate
51 }
52}
53
54impl Spanned for Yield {
55 #[inline]
56 fn span(&self) -> Span {
57 self.span
58 }
59}
60
61impl From<Yield> for Expression {
62 #[inline]
63 fn from(r#yield: Yield) -> Self {
64 Self::Yield(r#yield)
65 }
66}
67
68impl ToInternedString for Yield {
69 #[inline]
70 fn to_interned_string(&self, interner: &Interner) -> String {
71 let y = if self.delegate { "yield*" } else { "yield" };
72 if let Some(ex) = self.target() {
73 format!("{y} {}", ex.to_interned_string(interner))
74 } else {
75 y.to_owned()
76 }
77 }
78}
79
80impl VisitWith for Yield {
81 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
82 where
83 V: Visitor<'a>,
84 {
85 if let Some(expr) = &self.target {
86 visitor.visit_expression(expr)
87 } else {
88 ControlFlow::Continue(())
89 }
90 }
91
92 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
93 where
94 V: VisitorMut<'a>,
95 {
96 if let Some(expr) = &mut self.target {
97 visitor.visit_expression_mut(expr)
98 } else {
99 ControlFlow::Continue(())
100 }
101 }
102}