Browse Source

Parse class private async generator methods (#2220)

Currently async generator class methods are not being parsed correctly. In comparison to the current main branch this only fixes a few tests, but after #2200 is merged, it should be aroud 1000 additional passing tests.
pull/2224/head
raskad 2 years ago
parent
commit
3d6a8d5232
  1. 22
      boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs
  2. 46
      boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs

22
boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs

@ -182,7 +182,7 @@ where
let position = token.span().start();
if let TokenKind::Punctuator(Punctuator::Mul) = token.kind() {
let (property_name, method) =
let (class_element_name, method) =
AsyncGeneratorMethod::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)?;
@ -191,6 +191,18 @@ where
return Err(ParseError::general("invalid super usage", position));
}
let property_name =
if let object::ClassElementName::PropertyName(property_name) =
class_element_name
{
property_name
} else {
return Err(ParseError::general(
"private identifiers not allowed in object literal",
position,
));
};
return Ok(object::PropertyDefinition::method_definition(
method,
property_name,
@ -751,7 +763,7 @@ impl<R> TokenParser<R> for AsyncGeneratorMethod
where
R: Read,
{
type Output = (object::PropertyName, MethodDefinition);
type Output = (object::ClassElementName, MethodDefinition);
fn parse(
self,
@ -765,8 +777,8 @@ where
interner,
)?;
let property_name =
PropertyName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
let name =
ClassElementName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
let params = UniqueFormalParameters::new(true, true).parse(cursor, interner)?;
@ -809,7 +821,7 @@ where
}
Ok((
property_name,
name,
MethodDefinition::AsyncGenerator(AsyncGeneratorExpr::new(None, params, body)),
))
}

46
boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs

@ -4,7 +4,7 @@ use crate::syntax::{
self,
declaration::class_decl::ClassElement as ClassElementNode,
function_contains_super, has_direct_super,
object::{MethodDefinition, PropertyName::Literal},
object::{ClassElementName, MethodDefinition, PropertyName::Literal},
Class, ContainsSymbol, FormalParameterList, FunctionExpr,
},
Keyword, Punctuator,
@ -736,30 +736,44 @@ where
TokenKind::Punctuator(Punctuator::Mul) => {
let token = cursor.peek(1, interner)?.ok_or(ParseError::AbruptEnd)?;
let name_position = token.span().start();
if let TokenKind::Identifier(Sym::CONSTRUCTOR) = token.kind() {
return Err(ParseError::general(
"class constructor may not be a generator method",
token.span().start(),
));
match token.kind() {
TokenKind::Identifier(Sym::CONSTRUCTOR)
| TokenKind::PrivateIdentifier(Sym::CONSTRUCTOR) => {
return Err(ParseError::general(
"class constructor may not be a generator method",
token.span().start(),
));
}
_ => {}
}
let strict = cursor.strict_mode();
cursor.set_strict_mode(true);
let (property_name, method) =
let (class_element_name, method) =
AsyncGeneratorMethod::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)?;
cursor.set_strict_mode(strict);
if r#static {
if let Some(name) = property_name.prop_name() {
if name == Sym::PROTOTYPE {
match class_element_name {
ClassElementName::PropertyName(property_name) if r#static => {
if let Some(Sym::PROTOTYPE) = property_name.prop_name() {
return Err(ParseError::general(
"class may not have static method definitions named 'prototype'",
name_position,
));
"class may not have static method definitions named 'prototype'",
name_position,
));
}
ClassElementNode::StaticMethodDefinition(property_name, method)
}
ClassElementName::PropertyName(property_name) => {
ClassElementNode::MethodDefinition(property_name, method)
}
ClassElementName::PrivateIdentifier(private_ident) if r#static => {
ClassElementNode::PrivateStaticMethodDefinition(
private_ident,
method,
)
}
ClassElementName::PrivateIdentifier(private_ident) => {
ClassElementNode::PrivateMethodDefinition(private_ident, method)
}
ClassElementNode::StaticMethodDefinition(property_name, method)
} else {
ClassElementNode::MethodDefinition(property_name, method)
}
}
TokenKind::Identifier(Sym::CONSTRUCTOR) => {

Loading…
Cancel
Save