From f7ca45c3ff259e04a43d999c424df42e6561b577 Mon Sep 17 00:00:00 2001 From: Paul Lancaster Date: Fri, 9 Oct 2020 23:29:39 +0100 Subject: [PATCH] Created AsyncFunctionDecl/Expr nodes --- .../declaration/async_function_decl/mod.rs | 92 ++++++++++++++++++ .../declaration/async_function_expr/mod.rs | 94 +++++++++++++++++++ boa/src/syntax/ast/node/declaration/mod.rs | 4 + boa/src/syntax/ast/node/mod.rs | 16 +++- 4 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs create mode 100644 boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs diff --git a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs new file mode 100644 index 0000000000..44d47e36ba --- /dev/null +++ b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs @@ -0,0 +1,92 @@ +use crate::{ + exec::Executable, + syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, + BoaProfiler, Context, Result, Value, +}; +use gc::{Finalize, Trace}; +use std::fmt; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// Async Function Declaration. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-async-function-prototype-properties +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Debug, Trace, Finalize, PartialEq)] +pub struct AsyncFunctionDecl { + name: Box, + parameters: Box<[FormalParameter]>, + body: StatementList, +} + +impl AsyncFunctionDecl { + /// Creates a new async function declaration. + pub(in crate::syntax) fn new(name: N, parameters: P, body: B) -> Self + where + N: Into>, + P: Into>, + B: Into, + { + Self { + name: name.into(), + parameters: parameters.into(), + body: body.into(), + } + } + + /// Gets the name of the async function declaration. + pub fn name(&self) -> &str { + &self.name + } + + /// Gets the list of parameters of the async function declaration. + pub fn parameters(&self) -> &[FormalParameter] { + &self.parameters + } + + /// Gets the body of the async function declaration. + pub fn body(&self) -> &[Node] { + self.body.statements() + } + + /// Implements the display formatting with indentation. + pub(in crate::syntax::ast::node) fn display( + &self, + f: &mut fmt::Formatter<'_>, + indentation: usize, + ) -> fmt::Result { + write!(f, "async function {}(", self.name)?; + join_nodes(f, &self.parameters)?; + f.write_str(") {{")?; + + self.body.display(f, indentation + 1)?; + + writeln!(f, "}}") + } +} + +impl Executable for AsyncFunctionDecl { + fn run(&self, interpreter: &mut Context) -> Result { + let _timer = BoaProfiler::global().start_event("AsyncFunctionDecl", "exec"); + unimplemented!("Execute AsyncFunctionDecl"); + Ok(Value::undefined()) + } +} + +impl From for Node { + fn from(decl: AsyncFunctionDecl) -> Self { + Self::AsyncFunctionDecl(decl) + } +} + +impl fmt::Display for AsyncFunctionDecl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.display(f, 0) + } +} diff --git a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs new file mode 100644 index 0000000000..2a1979d717 --- /dev/null +++ b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs @@ -0,0 +1,94 @@ +use crate::{ + exec::Executable, + syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, + Context, Result, Value, +}; +use gc::{Finalize, Trace}; +use std::fmt; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// AsyncFunctionExpr. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#prod-AsyncFunctionExpression +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Debug, Trace, Finalize, PartialEq)] +pub struct AsyncFunctionExpr { + name: Option>, + parameters: Box<[FormalParameter]>, + body: StatementList, +} + +impl AsyncFunctionExpr { + /// Creates a new function expression + pub(in crate::syntax) fn new(name: N, parameters: P, body: B) -> Self + where + N: Into>>, + P: Into>, + B: Into, + { + Self { + name: name.into(), + parameters: parameters.into(), + body: body.into(), + } + } + + /// Gets the name of the function declaration. + pub fn name(&self) -> Option<&str> { + self.name.as_ref().map(Box::as_ref) + } + + /// Gets the list of parameters of the function declaration. + pub fn parameters(&self) -> &[FormalParameter] { + &self.parameters + } + + /// Gets the body of the function declaration. + pub fn body(&self) -> &[Node] { + self.body.statements() + } + + /// Implements the display formatting with indentation. + pub(in crate::syntax::ast::node) fn display( + &self, + f: &mut fmt::Formatter<'_>, + indentation: usize, + ) -> fmt::Result { + f.write_str("function")?; + if let Some(ref name) = self.name { + write!(f, " {}", name)?; + } + f.write_str("(")?; + join_nodes(f, &self.parameters)?; + f.write_str(") {{")?; + + self.body.display(f, indentation + 1)?; + + writeln!(f, "}}") + } +} + +impl Executable for AsyncFunctionExpr { + fn run(&self, interpreter: &mut Context) -> Result { + unimplemented!("Execute AsyncFunctionExpr"); + } +} + +impl fmt::Display for AsyncFunctionExpr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.display(f, 0) + } +} + +impl From for Node { + fn from(expr: AsyncFunctionExpr) -> Self { + Self::AsyncFunctionExpr(expr) + } +} diff --git a/boa/src/syntax/ast/node/declaration/mod.rs b/boa/src/syntax/ast/node/declaration/mod.rs index 9e5d181a81..a256a75e87 100644 --- a/boa/src/syntax/ast/node/declaration/mod.rs +++ b/boa/src/syntax/ast/node/declaration/mod.rs @@ -1,6 +1,8 @@ //! Declaration nodes pub mod arrow_function_decl; +pub mod async_function_decl; +pub mod async_function_expr; pub mod const_decl_list; pub mod function_decl; pub mod function_expr; @@ -9,6 +11,8 @@ pub mod var_decl_list; pub use self::{ arrow_function_decl::ArrowFunctionDecl, + async_function_decl::AsyncFunctionDecl, + async_function_expr::AsyncFunctionExpr, const_decl_list::{ConstDecl, ConstDeclList}, function_decl::FunctionDecl, function_expr::FunctionExpr, diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 5180c1ad70..d65914c9e8 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -26,8 +26,8 @@ pub use self::{ call::Call, conditional::{ConditionalOp, If}, declaration::{ - ArrowFunctionDecl, ConstDecl, ConstDeclList, FunctionDecl, FunctionExpr, LetDecl, - LetDeclList, VarDecl, VarDeclList, + ArrowFunctionDecl, AsyncFunctionDecl, AsyncFunctionExpr, ConstDecl, ConstDeclList, + FunctionDecl, FunctionExpr, LetDecl, LetDeclList, VarDecl, VarDeclList, }, field::{GetConstField, GetField}, identifier::Identifier, @@ -65,6 +65,12 @@ pub enum Node { /// An assignment operator node. [More information](./operator/struct.Assign.html). Assign(Assign), + /// An async function declaration node. [More information](./declaration/struct.AsyncFunctionDecl.html). + AsyncFunctionDecl(AsyncFunctionDecl), + + /// An async function expression node. [More information](./declaration/struct.AsyncFunctionExpr.html). + AsyncFunctionExpr(AsyncFunctionExpr), + /// A binary operator node. [More information](./operator/struct.BinOp.html). BinOp(BinOp), @@ -104,7 +110,7 @@ pub enum Node { /// A function declaration node. [More information](./declaration/struct.FunctionDecl.html). FunctionDecl(FunctionDecl), - /// A function expressino node. [More information](./declaration/struct.FunctionExpr.html). + /// A function expression node. [More information](./declaration/struct.FunctionExpr.html). FunctionExpr(FunctionExpr), /// Provides access to an object types' constant properties. [More information](./declaration/struct.GetConstField.html). @@ -243,6 +249,8 @@ impl Node { Self::Assign(ref op) => Display::fmt(op, f), Self::LetDeclList(ref decl) => Display::fmt(decl, f), Self::ConstDeclList(ref decl) => Display::fmt(decl, f), + Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation), + Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation), } } } @@ -251,6 +259,8 @@ impl Executable for Node { fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Executable", "exec"); match *self { + Node::AsyncFunctionDecl(ref decl) => decl.run(interpreter), + Node::AsyncFunctionExpr(ref function_expr) => function_expr.run(interpreter), Node::Call(ref call) => call.run(interpreter), Node::Const(Const::Null) => Ok(Value::null()), Node::Const(Const::Num(num)) => Ok(Value::rational(num)),