From 35fb7455cac402452b5d4d1d4bb93cef50e51d94 Mon Sep 17 00:00:00 2001 From: Paul Lancaster Date: Sat, 10 Oct 2020 11:22:27 +0100 Subject: [PATCH] AsyncFunctionExpr parsing --- .../primary/async_function_expression.rs | 51 +++++++++++++++++-- .../syntax/parser/expression/primary/mod.rs | 6 +-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/boa/src/syntax/parser/expression/primary/async_function_expression.rs b/boa/src/syntax/parser/expression/primary/async_function_expression.rs index 61f24e8412..d030f848d6 100644 --- a/boa/src/syntax/parser/expression/primary/async_function_expression.rs +++ b/boa/src/syntax/parser/expression/primary/async_function_expression.rs @@ -6,11 +6,15 @@ //! //! [mdn]: //! [spec]: - use crate::{ syntax::{ - ast::node::AsyncFunctionExpr, - parser::{Cursor, ParseError, TokenParser}, + ast::{node::AsyncFunctionExpr, Keyword, Punctuator}, + lexer::TokenKind, + parser::{ + function::{FormalParameters, FunctionBody}, + statement::BindingIdentifier, + AllowYield, Cursor, ParseError, TokenParser, + }, }, BoaProfiler, }; @@ -26,7 +30,21 @@ use std::io::Read; /// [mdn]: /// [spec]: #[derive(Debug, Clone, Copy)] -pub(super) struct AsyncFunctionExpression; +pub(super) struct AsyncFunctionExpression { + allow_yield: AllowYield, +} + +impl AsyncFunctionExpression { + /// Creates a new `AsyncFunctionExpression` parser. + pub(super) fn new(allow_yield: Y) -> Self + where + Y: Into, + { + Self { + allow_yield: allow_yield.into(), + } + } +} impl TokenParser for AsyncFunctionExpression where @@ -36,7 +54,30 @@ where fn parse(self, cursor: &mut Cursor) -> Result { let _timer = BoaProfiler::global().start_event("AsyncFunctionExpression", "Parsing"); + cursor.expect_no_skip_lineterminator(Keyword::Function, "async function expression")?; + + let tok = cursor.peek(0)?; + + let name = if let Some(token) = tok { + match token.kind() { + TokenKind::Punctuator(Punctuator::OpenParen) => None, + _ => Some(BindingIdentifier::new(self.allow_yield, true).parse(cursor)?), + } + } else { + return Err(ParseError::AbruptEnd); + }; + + cursor.expect(Punctuator::OpenParen, "function expression")?; + + let params = FormalParameters::new(!self.allow_yield.0, true).parse(cursor)?; + + cursor.expect(Punctuator::CloseParen, "function expression")?; + cursor.expect(Punctuator::OpenBlock, "function expression")?; + + let body = FunctionBody::new(!self.allow_yield.0, true).parse(cursor)?; + + cursor.expect(Punctuator::CloseBlock, "function expression")?; - unimplemented!("Async function expression parse"); + Ok(AsyncFunctionExpr::new(name, params, body)) } } diff --git a/boa/src/syntax/parser/expression/primary/mod.rs b/boa/src/syntax/parser/expression/primary/mod.rs index 9963df4b57..7f55346663 100644 --- a/boa/src/syntax/parser/expression/primary/mod.rs +++ b/boa/src/syntax/parser/expression/primary/mod.rs @@ -78,9 +78,9 @@ where TokenKind::Keyword(Keyword::Function) => { FunctionExpression.parse(cursor).map(Node::from) } - TokenKind::Keyword(Keyword::Async) => { - AsyncFunctionExpression.parse(cursor).map(Node::from) - } + TokenKind::Keyword(Keyword::Async) => AsyncFunctionExpression::new(self.allow_yield) + .parse(cursor) + .map(Node::from), TokenKind::Punctuator(Punctuator::OpenParen) => { cursor.set_goal(InputElement::RegExp); let expr =