Skip to main content

boa_ast/statement/iteration/
do_while_loop.rs

1use crate::{
2    expression::Expression,
3    statement::Statement,
4    visitor::{VisitWith, Visitor, VisitorMut},
5};
6use boa_interner::{Interner, ToIndentedString, ToInternedString};
7use core::ops::ControlFlow;
8
9/// The `do...while` statement creates a loop that executes a specified statement until the
10/// test condition evaluates to false.
11///
12/// The condition is evaluated after executing the statement, resulting in the specified
13/// statement executing at least once.
14///
15/// More information:
16///  - [ECMAScript reference][spec]
17///  - [MDN documentation][mdn]
18///
19/// [spec]: https://tc39.es/ecma262/#sec-do-while-statement
20/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23#[derive(Clone, Debug, PartialEq)]
24pub struct DoWhileLoop {
25    body: Box<Statement>,
26    condition: Expression,
27}
28
29impl DoWhileLoop {
30    /// Gets the body of the do-while loop.
31    #[inline]
32    #[must_use]
33    pub const fn body(&self) -> &Statement {
34        &self.body
35    }
36
37    /// Gets the condition of the do-while loop.
38    #[inline]
39    #[must_use]
40    pub const fn cond(&self) -> &Expression {
41        &self.condition
42    }
43    /// Creates a `DoWhileLoop` AST node.
44    #[inline]
45    #[must_use]
46    pub fn new(body: Statement, condition: Expression) -> Self {
47        Self {
48            body: body.into(),
49            condition,
50        }
51    }
52}
53
54impl ToIndentedString for DoWhileLoop {
55    fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
56        format!(
57            "do {} while ({})",
58            self.body().to_indented_string(interner, indentation),
59            self.cond().to_interned_string(interner)
60        )
61    }
62}
63
64impl From<DoWhileLoop> for Statement {
65    fn from(do_while: DoWhileLoop) -> Self {
66        Self::DoWhileLoop(do_while)
67    }
68}
69
70impl VisitWith for DoWhileLoop {
71    fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
72    where
73        V: Visitor<'a>,
74    {
75        visitor.visit_statement(&self.body)?;
76        visitor.visit_expression(&self.condition)
77    }
78
79    fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
80    where
81        V: VisitorMut<'a>,
82    {
83        visitor.visit_statement_mut(&mut self.body)?;
84        visitor.visit_expression_mut(&mut self.condition)
85    }
86}