diff --git a/Cargo.lock b/Cargo.lock index 5e75919ede770..4a2e82a978c5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1796,7 +1796,6 @@ dependencies = [ "oxc_allocator", "oxc_ast", "oxc_diagnostics", - "oxc_ecmascript", "oxc_regular_expression", "oxc_span", "oxc_syntax", diff --git a/crates/oxc_parser/Cargo.toml b/crates/oxc_parser/Cargo.toml index d8ea5eaeb25b2..a74281a880846 100644 --- a/crates/oxc_parser/Cargo.toml +++ b/crates/oxc_parser/Cargo.toml @@ -22,7 +22,6 @@ doctest = false oxc_allocator = { workspace = true } oxc_ast = { workspace = true } oxc_diagnostics = { workspace = true } -oxc_ecmascript = { workspace = true } oxc_regular_expression = { workspace = true } oxc_span = { workspace = true } oxc_syntax = { workspace = true } diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index 4f763ff75baa9..d18cc1d1e5b1c 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -1,7 +1,6 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::ast::*; use oxc_diagnostics::Result; -use oxc_ecmascript::PropName; use oxc_span::{GetSpan, Span}; use crate::{ @@ -16,6 +15,15 @@ type Extends<'a> = type Implements<'a> = Vec<'a, TSClassImplements<'a>>; +fn prop_name<'a>(key: &'a PropertyKey<'a>) -> Option<(&'a str, Span)> { + match key { + PropertyKey::StaticIdentifier(ident) => Some((&ident.name, ident.span)), + PropertyKey::Identifier(ident) => Some((&ident.name, ident.span)), + PropertyKey::StringLiteral(lit) => Some((&lit.value, lit.span)), + _ => None, + } +} + /// Section 15.7 Class Definitions impl<'a> ParserImpl<'a> { // `start_span` points at the start of all decoractors and `class` keyword. @@ -309,6 +317,24 @@ impl<'a> ParserImpl<'a> { ) .map(Some) } else if self.at(Kind::LParen) || self.at(Kind::LAngle) || r#async || generator { + if !computed { + if let Some((name, span)) = prop_name(&key) { + if r#static && name == "prototype" && !self.ctx.has_ambient() { + self.error(diagnostics::static_prototype(span)); + } + if !r#static && name == "constructor" { + if kind == MethodDefinitionKind::Get || kind == MethodDefinitionKind::Set { + self.error(diagnostics::constructor_getter_setter(span)); + } + if r#async { + self.error(diagnostics::constructor_async(span)); + } + if generator { + self.error(diagnostics::constructor_generator(span)); + } + } + } + } // LAngle for start of type parameters `foo` // ^ let definition = self.parse_class_method_definition( @@ -324,28 +350,22 @@ impl<'a> ParserImpl<'a> { accessibility, optional, )?; - if let Some((name, span)) = definition.prop_name() { - if r#static && name == "prototype" && !self.ctx.has_ambient() { - self.error(diagnostics::static_prototype(span)); - } - if !r#static && name == "constructor" { - if kind == MethodDefinitionKind::Get || kind == MethodDefinitionKind::Set { - self.error(diagnostics::constructor_getter_setter(span)); - } - if r#async { - self.error(diagnostics::constructor_async(span)); - } - if generator { - self.error(diagnostics::constructor_generator(span)); - } - } - } Ok(Some(definition)) } else { // getter and setter has no ts type annotation if !kind.is_method() { return Err(self.unexpected()); } + if !computed { + if let Some((name, span)) = prop_name(&key) { + if name == "constructor" { + self.error(diagnostics::field_constructor(span)); + } + if r#static && name == "prototype" && !self.ctx.has_ambient() { + self.error(diagnostics::static_prototype(span)); + } + } + } let definition = self.parse_class_property_definition( span, key, @@ -359,14 +379,6 @@ impl<'a> ParserImpl<'a> { optional, definite, )?; - if let Some((name, span)) = definition.prop_name() { - if name == "constructor" { - self.error(diagnostics::field_constructor(span)); - } - if r#static && name == "prototype" && !self.ctx.has_ambient() { - self.error(diagnostics::static_prototype(span)); - } - } Ok(Some(definition)) } } @@ -398,7 +410,7 @@ impl<'a> ParserImpl<'a> { ) -> Result> { let kind = if !r#static && !computed - && key.prop_name().map_or(false, |(name, _)| name == "constructor") + && prop_name(&key).map_or(false, |(name, _)| name == "constructor") { MethodDefinitionKind::Constructor } else {