boa/syntax/ast/node/declaration/function_expr/
mod.rs1use 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#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
30#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
31pub struct FunctionExpr {
32 name: Option<Box<str>>,
33 parameters: Box<[FormalParameter]>,
34 body: StatementList,
35}
36
37impl FunctionExpr {
38 pub(in crate::syntax) fn new<N, P, B>(name: N, parameters: P, body: B) -> Self
40 where
41 N: Into<Option<Box<str>>>,
42 P: Into<Box<[FormalParameter]>>,
43 B: Into<StatementList>,
44 {
45 Self {
46 name: name.into(),
47 parameters: parameters.into(),
48 body: body.into(),
49 }
50 }
51
52 pub fn name(&self) -> Option<&str> {
54 self.name.as_ref().map(Box::as_ref)
55 }
56
57 pub fn parameters(&self) -> &[FormalParameter] {
59 &self.parameters
60 }
61
62 pub fn body(&self) -> &StatementList {
64 &self.body
65 }
66
67 pub(in crate::syntax::ast::node) fn display(
69 &self,
70 f: &mut fmt::Formatter<'_>,
71 indentation: usize,
72 ) -> fmt::Result {
73 f.write_str("function")?;
74 if let Some(ref name) = self.name {
75 write!(f, " {}", name)?;
76 }
77 f.write_str("(")?;
78 join_nodes(f, &self.parameters)?;
79 f.write_str(") ")?;
80 self.display_block(f, indentation)
81 }
82
83 pub(in crate::syntax::ast::node) fn display_block(
86 &self,
87 f: &mut fmt::Formatter<'_>,
88 indentation: usize,
89 ) -> fmt::Result {
90 if self.body().items().is_empty() {
91 f.write_str("{}")
92 } else {
93 f.write_str("{\n")?;
94 self.body.display(f, indentation + 1)?;
95 write!(f, "{}}}", " ".repeat(indentation))
96 }
97 }
98}
99
100impl Executable for FunctionExpr {
101 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
102 let val = context.create_function(
103 self.name().unwrap_or(""),
104 self.parameters().to_vec(),
105 self.body().clone(),
106 FunctionFlags::CONSTRUCTABLE,
107 )?;
108
109 Ok(val)
110 }
111}
112
113impl fmt::Display for FunctionExpr {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 self.display(f, 0)
116 }
117}
118
119impl From<FunctionExpr> for Node {
120 fn from(expr: FunctionExpr) -> Self {
121 Self::FunctionExpr(expr)
122 }
123}