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

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