boa/syntax/ast/node/declaration/async_function_expr/
mod.rs

1//! Async Function Expression.
2
3use crate::{
4    exec::Executable,
5    syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList},
6    Context, JsResult, JsValue,
7};
8use gc::{Finalize, Trace};
9use std::fmt;
10
11#[cfg(feature = "deser")]
12use serde::{Deserialize, Serialize};
13
14/// An async function expression is very similar to an async function declaration except used within
15/// a wider expression (for example during an assignment).
16///
17/// More information:
18///  - [ECMAScript reference][spec]
19///  - [MDN documentation][mdn]
20///
21/// [spec]: https://tc39.es/ecma262/#prod-AsyncFunctionExpression
22/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function
23#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
24#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
25pub struct AsyncFunctionExpr {
26    name: Option<Box<str>>,
27    parameters: Box<[FormalParameter]>,
28    body: StatementList,
29}
30
31impl AsyncFunctionExpr {
32    /// Creates a new function expression
33    pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
34    where
35        N: Into<Option<Box<str>>>,
36        P: Into<Box<[FormalParameter]>>,
37        B: Into<StatementList>,
38    {
39        Self {
40            name: name.into(),
41            parameters: parameters.into(),
42            body: body.into(),
43        }
44    }
45
46    /// Gets the name of the function declaration.
47    pub fn name(&self) -> Option<&str> {
48        self.name.as_ref().map(Box::as_ref)
49    }
50
51    /// Gets the list of parameters of the function declaration.
52    pub fn parameters(&self) -> &[FormalParameter] {
53        &self.parameters
54    }
55
56    /// Gets the body of the function declaration.
57    pub fn body(&self) -> &[Node] {
58        self.body.items()
59    }
60
61    /// Implements the display formatting with indentation.
62    pub(in crate::syntax::ast::node) fn display(
63        &self,
64        f: &mut fmt::Formatter<'_>,
65        indentation: usize,
66    ) -> fmt::Result {
67        f.write_str("async function")?;
68        if let Some(ref name) = self.name {
69            write!(f, " {}", name)?;
70        }
71        f.write_str("(")?;
72        join_nodes(f, &self.parameters)?;
73        if self.body().is_empty() {
74            f.write_str(") {}")
75        } else {
76            f.write_str(") {\n")?;
77            self.body.display(f, indentation + 1)?;
78            write!(f, "{}}}", "    ".repeat(indentation))
79        }
80    }
81}
82
83impl Executable for AsyncFunctionExpr {
84    fn run(&self, _: &mut Context) -> JsResult<JsValue> {
85        // TODO: Implement AsyncFunctionExpr
86        Ok(JsValue::undefined())
87    }
88}
89
90impl fmt::Display for AsyncFunctionExpr {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        self.display(f, 0)
93    }
94}
95
96impl From<AsyncFunctionExpr> for Node {
97    fn from(expr: AsyncFunctionExpr) -> Self {
98        Self::AsyncFunctionExpr(expr)
99    }
100}