Browse Source

Parse static async private methods in classes (#2315)

This Pull Request changes the following:

- Adjust `AsyncMethod` parsing to parse private identifiers.
pull/2320/head
raskad 2 years ago
parent
commit
7f1d1a992a
  1. 21
      boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs
  2. 28
      boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs

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

@ -215,9 +215,20 @@ where
property_name,
));
}
let (property_name, method) =
let (class_element_name, method) =
AsyncMethod::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
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,
));
};
// It is a Syntax Error if HasDirectSuper of MethodDefinition is true.
if has_direct_super(method.body(), method.parameters()) {
return Err(ParseError::general("invalid super usage", position));
@ -888,7 +899,7 @@ impl<R> TokenParser<R> for AsyncMethod
where
R: Read,
{
type Output = (object::PropertyName, MethodDefinition);
type Output = (object::ClassElementName, MethodDefinition);
fn parse(
self,
@ -897,8 +908,8 @@ where
) -> Result<Self::Output, ParseError> {
let _timer = Profiler::global().start_event("AsyncMethod", "Parsing");
let property_name =
PropertyName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
let class_element_name =
ClassElementName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
let params = UniqueFormalParameters::new(false, true).parse(cursor, interner)?;
@ -941,7 +952,7 @@ where
}
Ok((
property_name,
class_element_name,
MethodDefinition::Async(AsyncFunctionExpr::new(None, params, body)),
))
}

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

@ -793,22 +793,36 @@ where
let name_position = token.span().start();
let strict = cursor.strict_mode();
cursor.set_strict_mode(true);
let (property_name, method) =
let (class_element_name, method) =
AsyncMethod::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,
));
}
ClassElementNode::StaticMethodDefinition(property_name, method)
}
ClassElementName::PropertyName(property_name) => {
ClassElementNode::MethodDefinition(property_name, method)
}
ClassElementName::PrivateIdentifier(Sym::CONSTRUCTOR) if r#static => {
return Err(ParseError::general(
"class constructor may not be a private method",
name_position,
))
}
ClassElementName::PrivateIdentifier(identifier) if r#static => {
ClassElementNode::PrivateStaticMethodDefinition(identifier, method)
}
ClassElementName::PrivateIdentifier(identifier) => {
ClassElementNode::PrivateMethodDefinition(identifier, method)
}
ClassElementNode::StaticMethodDefinition(property_name, method)
} else {
ClassElementNode::MethodDefinition(property_name, method)
}
}
}

Loading…
Cancel
Save