From 7f1d1a992a585fb6d1e72045a04e6e40cd52cc22 Mon Sep 17 00:00:00 2001 From: raskad <32105367+raskad@users.noreply.github.com> Date: Sun, 2 Oct 2022 09:31:59 +0000 Subject: [PATCH] Parse static async private methods in classes (#2315) This Pull Request changes the following: - Adjust `AsyncMethod` parsing to parse private identifiers. --- .../primary/object_initializer/mod.rs | 21 ++++++++++---- .../declaration/hoistable/class_decl/mod.rs | 28 ++++++++++++++----- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs b/boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs index a53318f18e3..d3870e4a167 100644 --- a/boa_engine/src/syntax/parser/expression/primary/object_initializer/mod.rs +++ b/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 TokenParser for AsyncMethod where R: Read, { - type Output = (object::PropertyName, MethodDefinition); + type Output = (object::ClassElementName, MethodDefinition); fn parse( self, @@ -897,8 +908,8 @@ where ) -> Result { 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)), )) } diff --git a/boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs b/boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs index 9840ef6c450..0d568958c73 100644 --- a/boa_engine/src/syntax/parser/statement/declaration/hoistable/class_decl/mod.rs +++ b/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) } } }