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, property_name,
)); ));
} }
let (property_name, method) = let (class_element_name, method) =
AsyncMethod::new(self.allow_yield, self.allow_await).parse(cursor, interner)?; 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. // It is a Syntax Error if HasDirectSuper of MethodDefinition is true.
if has_direct_super(method.body(), method.parameters()) { if has_direct_super(method.body(), method.parameters()) {
return Err(ParseError::general("invalid super usage", position)); return Err(ParseError::general("invalid super usage", position));
@ -888,7 +899,7 @@ impl<R> TokenParser<R> for AsyncMethod
where where
R: Read, R: Read,
{ {
type Output = (object::PropertyName, MethodDefinition); type Output = (object::ClassElementName, MethodDefinition);
fn parse( fn parse(
self, self,
@ -897,8 +908,8 @@ where
) -> Result<Self::Output, ParseError> { ) -> Result<Self::Output, ParseError> {
let _timer = Profiler::global().start_event("AsyncMethod", "Parsing"); let _timer = Profiler::global().start_event("AsyncMethod", "Parsing");
let property_name = let class_element_name =
PropertyName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?; ClassElementName::new(self.allow_yield, self.allow_await).parse(cursor, interner)?;
let params = UniqueFormalParameters::new(false, true).parse(cursor, interner)?; let params = UniqueFormalParameters::new(false, true).parse(cursor, interner)?;
@ -941,7 +952,7 @@ where
} }
Ok(( Ok((
property_name, class_element_name,
MethodDefinition::Async(AsyncFunctionExpr::new(None, params, body)), 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 name_position = token.span().start();
let strict = cursor.strict_mode(); let strict = cursor.strict_mode();
cursor.set_strict_mode(true); cursor.set_strict_mode(true);
let (property_name, method) = let (class_element_name, method) =
AsyncMethod::new(self.allow_yield, self.allow_await) AsyncMethod::new(self.allow_yield, self.allow_await)
.parse(cursor, interner)?; .parse(cursor, interner)?;
cursor.set_strict_mode(strict); cursor.set_strict_mode(strict);
if r#static {
if let Some(name) = property_name.prop_name() { match class_element_name {
if name == Sym::PROTOTYPE { ClassElementName::PropertyName(property_name) if r#static => {
if let Some(Sym::PROTOTYPE) = property_name.prop_name() {
return Err(ParseError::general( return Err(ParseError::general(
"class may not have static method definitions named 'prototype'", "class may not have static method definitions named 'prototype'",
name_position, 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