Browse Source

Give the arrow function its proper name (#1832)

With this change an arrow function name is correctly set to the name of the variable:

```javascript
const myFunction = () => {};
console.log(myFunction.name); // Prints "myFunction"
```

_Note:_ I'm still getting familiar with the codebase and am pretty new to Rust so I won't be offended if this isn't merged. I am actually surprised I had to make so many changes to give the right code the name it needed. Maybe there is a better way? I'm all ears :)
pull/1839/head
Djordje Lukic 3 years ago
parent
commit
7e772768e2
  1. 2
      boa/src/bytecompiler.rs
  2. 17
      boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs
  3. 13
      boa/src/syntax/parser/expression/assignment/arrow_function.rs
  4. 20
      boa/src/syntax/parser/expression/assignment/conditional.rs
  5. 15
      boa/src/syntax/parser/expression/assignment/mod.rs
  6. 2
      boa/src/syntax/parser/expression/assignment/yield.rs
  7. 4
      boa/src/syntax/parser/expression/left_hand_side/arguments.rs
  8. 2
      boa/src/syntax/parser/expression/left_hand_side/call.rs
  9. 2
      boa/src/syntax/parser/expression/left_hand_side/member.rs
  10. 2
      boa/src/syntax/parser/expression/left_hand_side/template.rs
  11. 9
      boa/src/syntax/parser/expression/mod.rs
  12. 7
      boa/src/syntax/parser/expression/primary/array_initializer/mod.rs
  13. 2
      boa/src/syntax/parser/expression/primary/mod.rs
  14. 17
      boa/src/syntax/parser/expression/primary/object_initializer/mod.rs
  15. 4
      boa/src/syntax/parser/expression/primary/template/mod.rs
  16. 8
      boa/src/syntax/parser/function/mod.rs
  17. 14
      boa/src/syntax/parser/function/tests.rs
  18. 20
      boa/src/syntax/parser/statement/declaration/lexical.rs
  19. 4
      boa/src/syntax/parser/statement/expression/mod.rs
  20. 4
      boa/src/syntax/parser/statement/if_stm/mod.rs
  21. 4
      boa/src/syntax/parser/statement/iteration/do_while_statement.rs
  22. 10
      boa/src/syntax/parser/statement/iteration/for_statement.rs
  23. 4
      boa/src/syntax/parser/statement/iteration/while_statement.rs
  24. 43
      boa/src/syntax/parser/statement/mod.rs
  25. 4
      boa/src/syntax/parser/statement/return_stm/mod.rs
  26. 6
      boa/src/syntax/parser/statement/switch/mod.rs
  27. 4
      boa/src/syntax/parser/statement/throw/mod.rs
  28. 20
      boa/src/syntax/parser/statement/variable/mod.rs
  29. 5
      boa/src/syntax/parser/tests.rs

2
boa/src/bytecompiler.rs

@ -1423,7 +1423,7 @@ impl<'b> ByteCompiler<'b> {
), ),
Node::ArrowFunctionDecl(function) => ( Node::ArrowFunctionDecl(function) => (
FunctionKind::Arrow, FunctionKind::Arrow,
None, function.name(),
function.params(), function.params(),
function.body(), function.body(),
), ),

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

@ -2,7 +2,7 @@ use crate::{
gc::{Finalize, Trace}, gc::{Finalize, Trace},
syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList},
}; };
use boa_interner::{Interner, ToInternedString}; use boa_interner::{Interner, Sym, ToInternedString};
#[cfg(feature = "deser")] #[cfg(feature = "deser")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -23,23 +23,36 @@ use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)] #[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct ArrowFunctionDecl { pub struct ArrowFunctionDecl {
name: Option<Sym>,
params: Box<[FormalParameter]>, params: Box<[FormalParameter]>,
body: StatementList, body: StatementList,
} }
impl ArrowFunctionDecl { impl ArrowFunctionDecl {
/// Creates a new `ArrowFunctionDecl` AST node. /// Creates a new `ArrowFunctionDecl` AST node.
pub(in crate::syntax) fn new<P, B>(params: P, body: B) -> Self pub(in crate::syntax) fn new<N, P, B>(name: N, params: P, body: B) -> Self
where where
N: Into<Option<Sym>>,
P: Into<Box<[FormalParameter]>>, P: Into<Box<[FormalParameter]>>,
B: Into<StatementList>, B: Into<StatementList>,
{ {
Self { Self {
name: name.into(),
params: params.into(), params: params.into(),
body: body.into(), body: body.into(),
} }
} }
/// Gets the name of the function declaration.
pub fn name(&self) -> Option<Sym> {
self.name
}
/// Sets the name of the function declaration.
pub fn set_name(&mut self, name: Option<Sym>) {
self.name = name;
}
/// Gets the list of parameters of the arrow function. /// Gets the list of parameters of the arrow function.
pub(crate) fn params(&self) -> &[FormalParameter] { pub(crate) fn params(&self) -> &[FormalParameter] {
&self.params &self.params

13
boa/src/syntax/parser/expression/assignment/arrow_function.rs

@ -7,6 +7,8 @@
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
//! [spec]: https://tc39.es/ecma262/#sec-arrow-function-definitions //! [spec]: https://tc39.es/ecma262/#sec-arrow-function-definitions
use boa_interner::Sym;
use super::AssignmentExpression; use super::AssignmentExpression;
use crate::{ use crate::{
syntax::{ syntax::{
@ -40,6 +42,7 @@ use std::io::Read;
/// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction /// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser) struct ArrowFunction { pub(in crate::syntax::parser) struct ArrowFunction {
name: Option<Sym>,
allow_in: AllowIn, allow_in: AllowIn,
allow_yield: AllowYield, allow_yield: AllowYield,
allow_await: AllowAwait, allow_await: AllowAwait,
@ -47,17 +50,20 @@ pub(in crate::syntax::parser) struct ArrowFunction {
impl ArrowFunction { impl ArrowFunction {
/// Creates a new `ArrowFunction` parser. /// Creates a new `ArrowFunction` parser.
pub(in crate::syntax::parser) fn new<I, Y, A>( pub(in crate::syntax::parser) fn new<N, I, Y, A>(
name: N,
allow_in: I, allow_in: I,
allow_yield: Y, allow_yield: Y,
allow_await: A, allow_await: A,
) -> Self ) -> Self
where where
N: Into<Option<Sym>>,
I: Into<AllowIn>, I: Into<AllowIn>,
Y: Into<AllowYield>, Y: Into<AllowYield>,
A: Into<AllowAwait>, A: Into<AllowAwait>,
{ {
Self { Self {
name: name.into(),
allow_in: allow_in.into(), allow_in: allow_in.into(),
allow_yield: allow_yield.into(), allow_yield: allow_yield.into(),
allow_await: allow_await.into(), allow_await: allow_await.into(),
@ -159,7 +165,7 @@ where
} }
} }
Ok(ArrowFunctionDecl::new(params.parameters, body)) Ok(ArrowFunctionDecl::new(self.name, params.parameters, body))
} }
} }
@ -240,6 +246,7 @@ where
type Output = Node; type Output = Node;
fn parse(self, cursor: &mut Cursor<R>, interner: &mut Interner) -> ParseResult { fn parse(self, cursor: &mut Cursor<R>, interner: &mut Interner) -> ParseResult {
AssignmentExpression::new(self.allow_in, false, self.allow_await).parse(cursor, interner) AssignmentExpression::new(None, self.allow_in, false, self.allow_await)
.parse(cursor, interner)
} }
} }

20
boa/src/syntax/parser/expression/assignment/conditional.rs

@ -72,14 +72,22 @@ where
if let Some(tok) = cursor.peek(0, interner)? { if let Some(tok) = cursor.peek(0, interner)? {
if tok.kind() == &TokenKind::Punctuator(Punctuator::Question) { if tok.kind() == &TokenKind::Punctuator(Punctuator::Question) {
cursor.next(interner)?.expect("? character vanished"); // Consume the token. cursor.next(interner)?.expect("? character vanished"); // Consume the token.
let then_clause = let then_clause = AssignmentExpression::new(
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
cursor.expect(Punctuator::Colon, "conditional expression", interner)?; cursor.expect(Punctuator::Colon, "conditional expression", interner)?;
let else_clause = let else_clause = AssignmentExpression::new(
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
return Ok(ConditionalOp::new(lhs, then_clause, else_clause).into()); return Ok(ConditionalOp::new(lhs, then_clause, else_clause).into());
} }
} }

15
boa/src/syntax/parser/expression/assignment/mod.rs

@ -26,6 +26,7 @@ use crate::{
}, },
BoaProfiler, BoaProfiler,
}; };
use boa_interner::Sym;
pub(super) use exponentiation::ExponentiationExpression; pub(super) use exponentiation::ExponentiationExpression;
use std::io::Read; use std::io::Read;
@ -50,6 +51,7 @@ use std::io::Read;
/// [lhs]: ../lhs_expression/struct.LeftHandSideExpression.html /// [lhs]: ../lhs_expression/struct.LeftHandSideExpression.html
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser) struct AssignmentExpression { pub(in crate::syntax::parser) struct AssignmentExpression {
name: Option<Sym>,
allow_in: AllowIn, allow_in: AllowIn,
allow_yield: AllowYield, allow_yield: AllowYield,
allow_await: AllowAwait, allow_await: AllowAwait,
@ -57,17 +59,20 @@ pub(in crate::syntax::parser) struct AssignmentExpression {
impl AssignmentExpression { impl AssignmentExpression {
/// Creates a new `AssignmentExpression` parser. /// Creates a new `AssignmentExpression` parser.
pub(in crate::syntax::parser) fn new<I, Y, A>( pub(in crate::syntax::parser) fn new<N, I, Y, A>(
name: N,
allow_in: I, allow_in: I,
allow_yield: Y, allow_yield: Y,
allow_await: A, allow_await: A,
) -> Self ) -> Self
where where
N: Into<Option<Sym>>,
I: Into<AllowIn>, I: Into<AllowIn>,
Y: Into<AllowYield>, Y: Into<AllowYield>,
A: Into<AllowAwait>, A: Into<AllowAwait>,
{ {
Self { Self {
name: name.into(),
allow_in: allow_in.into(), allow_in: allow_in.into(),
allow_yield: allow_yield.into(), allow_yield: allow_yield.into(),
allow_await: allow_await.into(), allow_await: allow_await.into(),
@ -102,6 +107,7 @@ where
{ {
if tok.kind() == &TokenKind::Punctuator(Punctuator::Arrow) { if tok.kind() == &TokenKind::Punctuator(Punctuator::Arrow) {
return ArrowFunction::new( return ArrowFunction::new(
self.name,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -121,6 +127,7 @@ where
if let Some(t) = cursor.peek(2, interner)? { if let Some(t) = cursor.peek(2, interner)? {
if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) { if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) {
return ArrowFunction::new( return ArrowFunction::new(
self.name,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -132,6 +139,7 @@ where
} }
TokenKind::Punctuator(Punctuator::Spread) => { TokenKind::Punctuator(Punctuator::Spread) => {
return ArrowFunction::new( return ArrowFunction::new(
None,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -145,6 +153,7 @@ where
TokenKind::Punctuator(Punctuator::Comma) => { TokenKind::Punctuator(Punctuator::Comma) => {
// This must be an argument list and therefore (a, b) => {} // This must be an argument list and therefore (a, b) => {}
return ArrowFunction::new( return ArrowFunction::new(
self.name,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -160,6 +169,7 @@ where
if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow) if t.kind() == &TokenKind::Punctuator(Punctuator::Arrow)
{ {
return ArrowFunction::new( return ArrowFunction::new(
self.name,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -193,7 +203,8 @@ where
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
cursor.next(interner)?.expect("= token vanished"); // Consume the token. cursor.next(interner)?.expect("= token vanished"); // Consume the token.
if is_assignable(&lhs) { if is_assignable(&lhs) {
lhs = Assign::new(lhs, self.parse(cursor, interner)?).into(); let expr = self.parse(cursor, interner)?;
lhs = Assign::new(lhs, expr).into();
} else { } else {
return Err(ParseError::lex(LexError::Syntax( return Err(ParseError::lex(LexError::Syntax(
"Invalid left-hand side in assignment".into(), "Invalid left-hand side in assignment".into(),

2
boa/src/syntax/parser/expression/assignment/yield.rs

@ -87,7 +87,7 @@ where
delegate = true; delegate = true;
} }
expr = Some( expr = Some(
AssignmentExpression::new(self.allow_in, true, self.allow_await) AssignmentExpression::new(None, self.allow_in, true, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
); );
} }

4
boa/src/syntax/parser/expression/left_hand_side/arguments.rs

@ -104,7 +104,7 @@ where
if cursor.next_if(Punctuator::Spread, interner)?.is_some() { if cursor.next_if(Punctuator::Spread, interner)?.is_some() {
args.push( args.push(
Spread::new( Spread::new(
AssignmentExpression::new(true, self.allow_yield, self.allow_await) AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
) )
.into(), .into(),
@ -112,7 +112,7 @@ where
} else { } else {
cursor.set_goal(InputElement::RegExp); cursor.set_goal(InputElement::RegExp);
args.push( args.push(
AssignmentExpression::new(true, self.allow_yield, self.allow_await) AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
); );
} }

2
boa/src/syntax/parser/expression/left_hand_side/call.rs

@ -111,7 +111,7 @@ where
} }
TokenKind::Punctuator(Punctuator::OpenBracket) => { TokenKind::Punctuator(Punctuator::OpenBracket) => {
let _next = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; // We move the parser. let _next = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; // We move the parser.
let idx = Expression::new(true, self.allow_yield, self.allow_await) let idx = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseBracket, "call expression", interner)?; cursor.expect(Punctuator::CloseBracket, "call expression", interner)?;
lhs = GetField::new(lhs, idx).into(); lhs = GetField::new(lhs, idx).into();

2
boa/src/syntax/parser/expression/left_hand_side/member.rs

@ -112,7 +112,7 @@ where
cursor cursor
.next(interner)? .next(interner)?
.expect("open bracket punctuator token disappeared"); // We move the parser forward. .expect("open bracket punctuator token disappeared"); // We move the parser forward.
let idx = Expression::new(true, self.allow_yield, self.allow_await) let idx = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseBracket, "member expression", interner)?; cursor.expect(Punctuator::CloseBracket, "member expression", interner)?;
lhs = GetField::new(lhs, idx).into(); lhs = GetField::new(lhs, idx).into();

2
boa/src/syntax/parser/expression/left_hand_side/template.rs

@ -64,7 +64,7 @@ where
raws.push(template_string.as_raw()); raws.push(template_string.as_raw());
cookeds.push(template_string.to_owned_cooked(interner).ok()); cookeds.push(template_string.to_owned_cooked(interner).ok());
exprs.push( exprs.push(
Expression::new(true, self.allow_yield, self.allow_await) Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
); );
cursor.expect( cursor.expect(

9
boa/src/syntax/parser/expression/mod.rs

@ -17,6 +17,8 @@ mod update;
pub(in crate::syntax::parser) mod await_expr; pub(in crate::syntax::parser) mod await_expr;
use boa_interner::Sym;
use self::assignment::ExponentiationExpression; use self::assignment::ExponentiationExpression;
pub(super) use self::{assignment::AssignmentExpression, primary::Initializer}; pub(super) use self::{assignment::AssignmentExpression, primary::Initializer};
use super::{AllowAwait, AllowIn, AllowYield, Cursor, ParseResult, TokenParser}; use super::{AllowAwait, AllowIn, AllowYield, Cursor, ParseResult, TokenParser};
@ -121,6 +123,7 @@ macro_rules! expression { ($name:ident, $lower:ident, [$( $op:path ),*], [$( $lo
/// [spec]: https://tc39.es/ecma262/#prod-Expression /// [spec]: https://tc39.es/ecma262/#prod-Expression
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(super) struct Expression { pub(super) struct Expression {
name: Option<Sym>,
allow_in: AllowIn, allow_in: AllowIn,
allow_yield: AllowYield, allow_yield: AllowYield,
allow_await: AllowAwait, allow_await: AllowAwait,
@ -128,13 +131,15 @@ pub(super) struct Expression {
impl Expression { impl Expression {
/// Creates a new `Expression` parser. /// Creates a new `Expression` parser.
pub(super) fn new<I, Y, A>(allow_in: I, allow_yield: Y, allow_await: A) -> Self pub(super) fn new<N, I, Y, A>(name: N, allow_in: I, allow_yield: Y, allow_await: A) -> Self
where where
N: Into<Option<Sym>>,
I: Into<AllowIn>, I: Into<AllowIn>,
Y: Into<AllowYield>, Y: Into<AllowYield>,
A: Into<AllowAwait>, A: Into<AllowAwait>,
{ {
Self { Self {
name: name.into(),
allow_in: allow_in.into(), allow_in: allow_in.into(),
allow_yield: allow_yield.into(), allow_yield: allow_yield.into(),
allow_await: allow_await.into(), allow_await: allow_await.into(),
@ -146,7 +151,7 @@ expression!(
Expression, Expression,
AssignmentExpression, AssignmentExpression,
[Punctuator::Comma], [Punctuator::Comma],
[allow_in, allow_yield, allow_await], [name, allow_in, allow_yield, allow_await],
None::<InputElement> None::<InputElement>
); );

7
boa/src/syntax/parser/expression/primary/array_initializer/mod.rs

@ -84,12 +84,13 @@ where
let _next = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd); // Check that there are more tokens to read. let _next = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd); // Check that there are more tokens to read.
if cursor.next_if(Punctuator::Spread, interner)?.is_some() { if cursor.next_if(Punctuator::Spread, interner)?.is_some() {
let node = AssignmentExpression::new(true, self.allow_yield, self.allow_await) let node =
.parse(cursor, interner)?; AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?;
elements.push(Spread::new(node).into()); elements.push(Spread::new(node).into());
} else { } else {
elements.push( elements.push(
AssignmentExpression::new(true, self.allow_yield, self.allow_await) AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
); );
} }

2
boa/src/syntax/parser/expression/primary/mod.rs

@ -108,7 +108,7 @@ where
} }
TokenKind::Punctuator(Punctuator::OpenParen) => { TokenKind::Punctuator(Punctuator::OpenParen) => {
cursor.set_goal(InputElement::RegExp); cursor.set_goal(InputElement::RegExp);
let expr = Expression::new(true, self.allow_yield, self.allow_await) let expr = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseParen, "primary expression", interner)?; cursor.expect(Punctuator::CloseParen, "primary expression", interner)?;
Ok(expr) Ok(expr)

17
boa/src/syntax/parser/expression/primary/object_initializer/mod.rs

@ -9,8 +9,6 @@
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use boa_interner::Sym;
use crate::{ use crate::{
syntax::{ syntax::{
ast::{ ast::{
@ -26,6 +24,7 @@ use crate::{
}, },
BoaProfiler, Interner, BoaProfiler, Interner,
}; };
use boa_interner::Sym;
use std::io::Read; use std::io::Read;
/// Parses an object literal. /// Parses an object literal.
@ -195,7 +194,7 @@ where
// ... AssignmentExpression[+In, ?Yield, ?Await] // ... AssignmentExpression[+In, ?Yield, ?Await]
if cursor.next_if(Punctuator::Spread, interner)?.is_some() { if cursor.next_if(Punctuator::Spread, interner)?.is_some() {
let node = AssignmentExpression::new(true, self.allow_yield, self.allow_await) let node = AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
return Ok(node::PropertyDefinition::SpreadObject(node)); return Ok(node::PropertyDefinition::SpreadObject(node));
} }
@ -441,7 +440,7 @@ where
// PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] // PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await]
if cursor.next_if(Punctuator::Colon, interner)?.is_some() { if cursor.next_if(Punctuator::Colon, interner)?.is_some() {
let value = AssignmentExpression::new(true, self.allow_yield, self.allow_await) let value = AssignmentExpression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
return Ok(node::PropertyDefinition::property(property_name, value)); return Ok(node::PropertyDefinition::property(property_name, value));
} }
@ -639,7 +638,7 @@ where
// ComputedPropertyName[?Yield, ?Await] -> [ AssignmentExpression[+In, ?Yield, ?Await] ] // ComputedPropertyName[?Yield, ?Await] -> [ AssignmentExpression[+In, ?Yield, ?Await] ]
if cursor.next_if(Punctuator::OpenBracket, interner)?.is_some() { if cursor.next_if(Punctuator::OpenBracket, interner)?.is_some() {
let node = AssignmentExpression::new(false, self.allow_yield, self.allow_await) let node = AssignmentExpression::new(None, false, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseBracket, "expected token ']'", interner)?; cursor.expect(Punctuator::CloseBracket, "expected token ']'", interner)?;
return Ok(node.into()); return Ok(node.into());
@ -662,6 +661,7 @@ where
/// [spec]: https://tc39.es/ecma262/#prod-Initializer /// [spec]: https://tc39.es/ecma262/#prod-Initializer
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(in crate::syntax::parser) struct Initializer { pub(in crate::syntax::parser) struct Initializer {
name: Option<Sym>,
allow_in: AllowIn, allow_in: AllowIn,
allow_yield: AllowYield, allow_yield: AllowYield,
allow_await: AllowAwait, allow_await: AllowAwait,
@ -669,17 +669,20 @@ pub(in crate::syntax::parser) struct Initializer {
impl Initializer { impl Initializer {
/// Creates a new `Initializer` parser. /// Creates a new `Initializer` parser.
pub(in crate::syntax::parser) fn new<I, Y, A>( pub(in crate::syntax::parser) fn new<N, I, Y, A>(
name: N,
allow_in: I, allow_in: I,
allow_yield: Y, allow_yield: Y,
allow_await: A, allow_await: A,
) -> Self ) -> Self
where where
N: Into<Option<Sym>>,
I: Into<AllowIn>, I: Into<AllowIn>,
Y: Into<AllowYield>, Y: Into<AllowYield>,
A: Into<AllowAwait>, A: Into<AllowAwait>,
{ {
Self { Self {
name: name.into(),
allow_in: allow_in.into(), allow_in: allow_in.into(),
allow_yield: allow_yield.into(), allow_yield: allow_yield.into(),
allow_await: allow_await.into(), allow_await: allow_await.into(),
@ -697,7 +700,7 @@ where
let _timer = BoaProfiler::global().start_event("Initializer", "Parsing"); let _timer = BoaProfiler::global().start_event("Initializer", "Parsing");
cursor.expect(Punctuator::Assign, "initializer", interner)?; cursor.expect(Punctuator::Assign, "initializer", interner)?;
AssignmentExpression::new(self.allow_in, self.allow_yield, self.allow_await) AssignmentExpression::new(self.name, self.allow_in, self.allow_yield, self.allow_await)
.parse(cursor, interner) .parse(cursor, interner)
} }
} }

4
boa/src/syntax/parser/expression/primary/template/mod.rs

@ -69,7 +69,7 @@ where
let mut elements = vec![ let mut elements = vec![
TemplateElement::String(self.first), TemplateElement::String(self.first),
TemplateElement::Expr( TemplateElement::Expr(
Expression::new(true, self.allow_yield, self.allow_await) Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
), ),
]; ];
@ -88,7 +88,7 @@ where
elements.push(TemplateElement::String(cooked)); elements.push(TemplateElement::String(cooked));
elements.push(TemplateElement::Expr( elements.push(TemplateElement::Expr(
Expression::new(true, self.allow_yield, self.allow_await) Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
)); ));
cursor.expect( cursor.expect(

8
boa/src/syntax/parser/function/mod.rs

@ -231,7 +231,7 @@ where
*t.kind() == TokenKind::Punctuator(Punctuator::Assign) *t.kind() == TokenKind::Punctuator(Punctuator::Assign)
}) })
.map(|_| { .map(|_| {
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner) .parse(cursor, interner)
}) })
.transpose()?; .transpose()?;
@ -257,7 +257,7 @@ where
*t.kind() == TokenKind::Punctuator(Punctuator::Assign) *t.kind() == TokenKind::Punctuator(Punctuator::Assign)
}) })
.map(|_| { .map(|_| {
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner) .parse(cursor, interner)
}) })
.transpose()?; .transpose()?;
@ -330,7 +330,7 @@ where
*t.kind() == TokenKind::Punctuator(Punctuator::Assign) *t.kind() == TokenKind::Punctuator(Punctuator::Assign)
}) })
.map(|_| { .map(|_| {
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner) .parse(cursor, interner)
}) })
.transpose()?; .transpose()?;
@ -357,7 +357,7 @@ where
*t.kind() == TokenKind::Punctuator(Punctuator::Assign) *t.kind() == TokenKind::Punctuator(Punctuator::Assign)
}) })
.map(|_| { .map(|_| {
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner) .parse(cursor, interner)
}) })
.transpose()?; .transpose()?;

14
boa/src/syntax/parser/function/tests.rs

@ -154,6 +154,7 @@ fn check_arrow_only_rest() {
check_parser( check_parser(
"(...a) => {}", "(...a) => {}",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![FormalParameter::new( vec![FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
true, true,
@ -172,6 +173,7 @@ fn check_arrow_rest() {
check_parser( check_parser(
"(a, b, ...c) => {}", "(a, b, ...c) => {}",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
@ -200,6 +202,7 @@ fn check_arrow() {
check_parser( check_parser(
"(a, b) => { return a + b; }", "(a, b) => { return a + b; }",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
@ -232,6 +235,7 @@ fn check_arrow_semicolon_insertion() {
check_parser( check_parser(
"(a, b) => { return a + b }", "(a, b) => { return a + b }",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
@ -264,6 +268,7 @@ fn check_arrow_epty_return() {
check_parser( check_parser(
"(a, b) => { return; }", "(a, b) => { return; }",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
@ -288,6 +293,7 @@ fn check_arrow_empty_return_semicolon_insertion() {
check_parser( check_parser(
"(a, b) => { return }", "(a, b) => { return }",
vec![ArrowFunctionDecl::new( vec![ArrowFunctionDecl::new(
None,
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier(interner.get_or_intern_static("a"), None), Declaration::new_with_identifier(interner.get_or_intern_static("a"), None),
@ -315,6 +321,7 @@ fn check_arrow_assignment() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![FormalParameter::new( vec![FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
interner.get_or_intern_static("a"), interner.get_or_intern_static("a"),
@ -348,6 +355,7 @@ fn check_arrow_assignment_nobrackets() {
interner.get_or_intern_static("foo"), interner.get_or_intern_static("foo"),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![FormalParameter::new( vec![FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
interner.get_or_intern_static("a"), interner.get_or_intern_static("a"),
@ -381,6 +389,7 @@ fn check_arrow_assignment_noparenthesis() {
interner.get_or_intern_static("foo"), interner.get_or_intern_static("foo"),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![FormalParameter::new( vec![FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
interner.get_or_intern_static("a"), interner.get_or_intern_static("a"),
@ -414,6 +423,7 @@ fn check_arrow_assignment_noparenthesis_nobrackets() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![FormalParameter::new( vec![FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
interner.get_or_intern_static("a"), interner.get_or_intern_static("a"),
@ -447,6 +457,7 @@ fn check_arrow_assignment_2arg() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
@ -489,6 +500,7 @@ fn check_arrow_assignment_2arg_nobrackets() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
@ -531,6 +543,7 @@ fn check_arrow_assignment_3arg() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(
@ -580,6 +593,7 @@ fn check_arrow_assignment_3arg_nobrackets() {
Identifier::new(interner.get_or_intern_static("foo")), Identifier::new(interner.get_or_intern_static("foo")),
Some( Some(
ArrowFunctionDecl::new( ArrowFunctionDecl::new(
Some(interner.get_or_intern_static("foo")),
vec![ vec![
FormalParameter::new( FormalParameter::new(
Declaration::new_with_identifier( Declaration::new_with_identifier(

20
boa/src/syntax/parser/statement/declaration/lexical.rs

@ -269,8 +269,13 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) Initializer::new(
.parse(cursor, interner)?, None,
self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?,
) )
} else { } else {
None None
@ -289,8 +294,13 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) Initializer::new(
.parse(cursor, interner)?, None,
self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?,
) )
} else { } else {
None None
@ -309,7 +319,7 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(Some(ident), true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
) )
} else { } else {

4
boa/src/syntax/parser/statement/expression/mod.rs

@ -73,8 +73,8 @@ where
_ => {} _ => {}
} }
let expr = let expr = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect_semicolon("expression statement", interner)?; cursor.expect_semicolon("expression statement", interner)?;

4
boa/src/syntax/parser/statement/if_stm/mod.rs

@ -64,8 +64,8 @@ where
cursor.expect(Keyword::If, "if statement", interner)?; cursor.expect(Keyword::If, "if statement", interner)?;
cursor.expect(Punctuator::OpenParen, "if statement", interner)?; cursor.expect(Punctuator::OpenParen, "if statement", interner)?;
let condition = let condition = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
let position = cursor let position = cursor
.expect(Punctuator::CloseParen, "if statement", interner)? .expect(Punctuator::CloseParen, "if statement", interner)?

4
boa/src/syntax/parser/statement/iteration/do_while_statement.rs

@ -96,8 +96,8 @@ where
cursor.expect(Punctuator::OpenParen, "do while statement", interner)?; cursor.expect(Punctuator::OpenParen, "do while statement", interner)?;
let cond = let cond = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseParen, "do while statement", interner)?; cursor.expect(Punctuator::CloseParen, "do while statement", interner)?;

10
boa/src/syntax/parser/statement/iteration/for_statement.rs

@ -97,7 +97,7 @@ where
), ),
TokenKind::Punctuator(Punctuator::Semicolon) => None, TokenKind::Punctuator(Punctuator::Semicolon) => None,
_ => Some( _ => Some(
Expression::new(false, self.allow_yield, self.allow_await) Expression::new(None, false, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
), ),
}; };
@ -107,7 +107,7 @@ where
let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?; let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?;
let _next = cursor.next(interner)?; let _next = cursor.next(interner)?;
let expr = Expression::new(true, self.allow_yield, self.allow_await) let expr = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
let position = cursor let position = cursor
@ -129,7 +129,7 @@ where
let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?; let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?;
let _next = cursor.next(interner)?; let _next = cursor.next(interner)?;
let iterable = Expression::new(true, self.allow_yield, self.allow_await) let iterable = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
let position = cursor let position = cursor
@ -155,7 +155,7 @@ where
let cond = if cursor.next_if(Punctuator::Semicolon, interner)?.is_some() { let cond = if cursor.next_if(Punctuator::Semicolon, interner)?.is_some() {
Const::from(true).into() Const::from(true).into()
} else { } else {
let step = Expression::new(true, self.allow_yield, self.allow_await) let step = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::Semicolon, "for statement", interner)?; cursor.expect(Punctuator::Semicolon, "for statement", interner)?;
step step
@ -164,7 +164,7 @@ where
let step = if cursor.next_if(Punctuator::CloseParen, interner)?.is_some() { let step = if cursor.next_if(Punctuator::CloseParen, interner)?.is_some() {
None None
} else { } else {
let step = Expression::new(true, self.allow_yield, self.allow_await) let step = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect( cursor.expect(
TokenKind::Punctuator(Punctuator::CloseParen), TokenKind::Punctuator(Punctuator::CloseParen),

4
boa/src/syntax/parser/statement/iteration/while_statement.rs

@ -62,8 +62,8 @@ where
cursor.expect(Punctuator::OpenParen, "while statement", interner)?; cursor.expect(Punctuator::OpenParen, "while statement", interner)?;
let cond = let cond = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
let position = cursor let position = cursor
.expect(Punctuator::CloseParen, "while statement", interner)? .expect(Punctuator::CloseParen, "while statement", interner)?

43
boa/src/syntax/parser/statement/mod.rs

@ -677,9 +677,13 @@ where
if let Some(peek_token) = cursor.peek(0, interner)? { if let Some(peek_token) = cursor.peek(0, interner)? {
match peek_token.kind() { match peek_token.kind() {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let init = let init = Initializer::new(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
patterns.push(BindingPatternTypeObject::SingleName { patterns.push(BindingPatternTypeObject::SingleName {
ident: property_name, ident: property_name,
property_name, property_name,
@ -707,6 +711,7 @@ where
match peek_token.kind() { match peek_token.kind() {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let init = Initializer::new( let init = Initializer::new(
None,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -752,6 +757,7 @@ where
match peek_token.kind() { match peek_token.kind() {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let init = Initializer::new( let init = Initializer::new(
None,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -796,6 +802,7 @@ where
match peek_token.kind() { match peek_token.kind() {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let init = Initializer::new( let init = Initializer::new(
None,
self.allow_in, self.allow_in,
self.allow_yield, self.allow_yield,
self.allow_await, self.allow_await,
@ -1012,9 +1019,13 @@ where
.kind() .kind()
{ {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let default_init = let default_init = Initializer::new(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
patterns.push(BindingPatternTypeArray::BindingPattern { patterns.push(BindingPatternTypeArray::BindingPattern {
pattern: DeclarationPattern::Object(DeclarationPatternObject::new( pattern: DeclarationPattern::Object(DeclarationPatternObject::new(
bindings, bindings,
@ -1043,9 +1054,13 @@ where
.kind() .kind()
{ {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let default_init = let default_init = Initializer::new(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
patterns.push(BindingPatternTypeArray::BindingPattern { patterns.push(BindingPatternTypeArray::BindingPattern {
pattern: DeclarationPattern::Array(DeclarationPatternArray::new( pattern: DeclarationPattern::Array(DeclarationPatternArray::new(
bindings, bindings,
@ -1073,9 +1088,13 @@ where
.kind() .kind()
{ {
TokenKind::Punctuator(Punctuator::Assign) => { TokenKind::Punctuator(Punctuator::Assign) => {
let default_init = let default_init = Initializer::new(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) None,
.parse(cursor, interner)?; self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?;
patterns.push(BindingPatternTypeArray::SingleName { patterns.push(BindingPatternTypeArray::SingleName {
ident, ident,
default_init: Some(default_init), default_init: Some(default_init),

4
boa/src/syntax/parser/statement/return_stm/mod.rs

@ -70,8 +70,8 @@ where
return Ok(Return::new::<Node, Option<_>, Option<_>>(None, None)); return Ok(Return::new::<Node, Option<_>, Option<_>>(None, None));
} }
let expr = let expr = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect_semicolon("return statement", interner)?; cursor.expect_semicolon("return statement", interner)?;

6
boa/src/syntax/parser/statement/switch/mod.rs

@ -68,8 +68,8 @@ where
cursor.expect(Keyword::Switch, "switch statement", interner)?; cursor.expect(Keyword::Switch, "switch statement", interner)?;
cursor.expect(Punctuator::OpenParen, "switch statement", interner)?; cursor.expect(Punctuator::OpenParen, "switch statement", interner)?;
let condition = let condition = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::CloseParen, "switch statement", interner)?; cursor.expect(Punctuator::CloseParen, "switch statement", interner)?;
@ -130,7 +130,7 @@ where
match cursor.next(interner)? { match cursor.next(interner)? {
Some(token) if token.kind() == &TokenKind::Keyword(Keyword::Case) => { Some(token) if token.kind() == &TokenKind::Keyword(Keyword::Case) => {
// Case statement. // Case statement.
let cond = Expression::new(true, self.allow_yield, self.allow_await) let cond = Expression::new(None, true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.expect(Punctuator::Colon, "switch case block", interner)?; cursor.expect(Punctuator::Colon, "switch case block", interner)?;

4
boa/src/syntax/parser/statement/throw/mod.rs

@ -57,8 +57,8 @@ where
cursor.peek_expect_no_lineterminator(0, "throw statement", interner)?; cursor.peek_expect_no_lineterminator(0, "throw statement", interner)?;
let expr = let expr = Expression::new(None, true, self.allow_yield, self.allow_await)
Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; .parse(cursor, interner)?;
if let Some(tok) = cursor.peek(0, interner)? { if let Some(tok) = cursor.peek(0, interner)? {
if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) { if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) {
let _next = cursor.next(interner).expect("token disappeared"); let _next = cursor.next(interner).expect("token disappeared");

20
boa/src/syntax/parser/statement/variable/mod.rs

@ -191,8 +191,13 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) Initializer::new(
.parse(cursor, interner)?, None,
self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?,
) )
} else { } else {
None None
@ -211,8 +216,13 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(self.allow_in, self.allow_yield, self.allow_await) Initializer::new(
.parse(cursor, interner)?, None,
self.allow_in,
self.allow_yield,
self.allow_await,
)
.parse(cursor, interner)?,
) )
} else { } else {
None None
@ -231,7 +241,7 @@ where
let init = if let Some(t) = cursor.peek(0, interner)? { let init = if let Some(t) = cursor.peek(0, interner)? {
if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) { if *t.kind() == TokenKind::Punctuator(Punctuator::Assign) {
Some( Some(
Initializer::new(true, self.allow_yield, self.allow_await) Initializer::new(Some(ident), true, self.allow_yield, self.allow_await)
.parse(cursor, interner)?, .parse(cursor, interner)?,
) )
} else { } else {

5
boa/src/syntax/parser/tests.rs

@ -1,5 +1,7 @@
//! Tests for the parser. //! Tests for the parser.
use boa_interner::Sym;
use super::Parser; use super::Parser;
use crate::{ use crate::{
syntax::ast::{ syntax::ast::{
@ -407,7 +409,8 @@ fn spread_in_arrow_function() {
check_parser( check_parser(
s, s,
vec![ vec![
ArrowFunctionDecl::new::<Box<[FormalParameter]>, StatementList>( ArrowFunctionDecl::new::<Option<Sym>, Box<[FormalParameter]>, StatementList>(
None,
Box::new([FormalParameter::new( Box::new([FormalParameter::new(
Declaration::new_with_identifier::<_, Option<Node>>(b, None), Declaration::new_with_identifier::<_, Option<Node>>(b, None),
true, true,

Loading…
Cancel
Save