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

1use crate::{
2    builtins::function::FunctionFlags,
3    exec::Executable,
4    gc::{Finalize, Trace},
5    syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList},
6    Context, JsResult, JsValue,
7};
8use std::fmt;
9
10#[cfg(feature = "deser")]
11use serde::{Deserialize, Serialize};
12
13/// An arrow function expression is a syntactically compact alternative to a regular function
14/// expression.
15///
16/// Arrow function expressions are ill suited as methods, and they cannot be used as
17/// constructors. Arrow functions cannot be used as constructors and will throw an error when
18/// used with new.
19///
20/// More information:
21///  - [ECMAScript reference][spec]
22///  - [MDN documentation][mdn]
23///
24/// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction
25/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
26#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
27#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
28pub struct ArrowFunctionDecl {
29    params: Box<[FormalParameter]>,
30    body: StatementList,
31}
32
33impl ArrowFunctionDecl {
34    /// Creates a new `ArrowFunctionDecl` AST node.
35    pub(in crate::syntax) fn new<P, B>(params: P, body: B) -> Self
36    where
37        P: Into<Box<[FormalParameter]>>,
38        B: Into<StatementList>,
39    {
40        Self {
41            params: params.into(),
42            body: body.into(),
43        }
44    }
45
46    /// Gets the list of parameters of the arrow function.
47    pub(crate) fn params(&self) -> &[FormalParameter] {
48        &self.params
49    }
50
51    /// Gets the body of the arrow function.
52    pub(crate) fn body(&self) -> &StatementList {
53        &self.body
54    }
55
56    /// Implements the display formatting with indentation.
57    pub(in crate::syntax::ast::node) fn display(
58        &self,
59        f: &mut fmt::Formatter<'_>,
60        indentation: usize,
61    ) -> fmt::Result {
62        write!(f, "(")?;
63        join_nodes(f, &self.params)?;
64        if self.body().items().is_empty() {
65            f.write_str(") => {}")
66        } else {
67            f.write_str(") => {\n")?;
68            self.body.display(f, indentation + 1)?;
69            write!(f, "{}}}", "    ".repeat(indentation))
70        }
71    }
72}
73
74impl Executable for ArrowFunctionDecl {
75    fn run(&self, context: &mut Context) -> JsResult<JsValue> {
76        context.create_function(
77            "",
78            self.params().to_vec(),
79            self.body().clone(),
80            FunctionFlags::LEXICAL_THIS_MODE,
81        )
82    }
83}
84
85impl fmt::Display for ArrowFunctionDecl {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        self.display(f, 0)
88    }
89}
90
91impl From<ArrowFunctionDecl> for Node {
92    fn from(decl: ArrowFunctionDecl) -> Self {
93        Self::ArrowFunctionDecl(decl)
94    }
95}