From 910193e0aa3874fa4383f8e78185d4e6f370181e Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Mon, 17 Jun 2024 08:49:12 +0000 Subject: [PATCH] feat(transformer-dts): report error for super class (#3711) --- crates/oxc_ast/src/ast/js.rs | 22 +++++++++++++++++++ crates/oxc_transformer_dts/src/class.rs | 18 ++++++++++++++- crates/oxc_transformer_dts/src/declaration.rs | 6 +---- crates/oxc_transformer_dts/src/diagnostics.rs | 5 +++++ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 634fc0856999..6674b3141da5 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -902,6 +902,28 @@ pub struct StaticMemberExpression<'a> { pub optional: bool, // for optional chaining } +impl<'a> StaticMemberExpression<'a> { + pub fn get_first_object(&self) -> &Expression<'a> { + match &self.object { + Expression::StaticMemberExpression(member) => { + if let Expression::StaticMemberExpression(expr) = &member.object { + expr.get_first_object() + } else { + &self.object + } + } + Expression::ChainExpression(chain) => { + if let ChainElement::StaticMemberExpression(expr) = &chain.expression { + expr.get_first_object() + } else { + &self.object + } + } + _ => &self.object, + } + } +} + /// `MemberExpression[?Yield, ?Await] . PrivateIdentifier` #[visited_node] #[derive(Debug, Hash)] diff --git a/crates/oxc_transformer_dts/src/class.rs b/crates/oxc_transformer_dts/src/class.rs index 5edd58f26f42..15e48f65e78b 100644 --- a/crates/oxc_transformer_dts/src/class.rs +++ b/crates/oxc_transformer_dts/src/class.rs @@ -4,7 +4,10 @@ use oxc_ast::ast::*; use oxc_allocator::Box; use oxc_span::{GetSpan, SPAN}; -use crate::{diagnostics::computed_property_name, TransformerDts}; +use crate::{ + diagnostics::{computed_property_name, extends_clause_expression}, + TransformerDts, +}; impl<'a> TransformerDts<'a> { pub fn is_literal_key(&self, key: &PropertyKey<'a>) -> bool { @@ -199,6 +202,19 @@ impl<'a> TransformerDts<'a> { return None; } + if let Some(super_class) = &decl.super_class { + let is_not_allowed = match super_class { + Expression::Identifier(_) => false, + Expression::StaticMemberExpression(expr) => { + !expr.get_first_object().is_identifier_reference() + } + _ => true, + }; + if is_not_allowed { + self.ctx.error(extends_clause_expression(super_class.span())); + } + } + let mut elements = self.ctx.ast.new_vec(); let mut has_private_key = false; for element in &decl.body.body { diff --git a/crates/oxc_transformer_dts/src/declaration.rs b/crates/oxc_transformer_dts/src/declaration.rs index a33a9a5be482..5a244bead9b5 100644 --- a/crates/oxc_transformer_dts/src/declaration.rs +++ b/crates/oxc_transformer_dts/src/declaration.rs @@ -251,11 +251,7 @@ impl<'a> TransformerDts<'a> { let is_not_allowed = match key { PropertyKey::StaticIdentifier(_) | PropertyKey::Identifier(_) => false, PropertyKey::StaticMemberExpression(expr) => { - let mut object = &expr.object; - while let Expression::StaticMemberExpression(expr) = &object { - object = &expr.object; - } - !object.is_identifier_reference() + !expr.get_first_object().is_identifier_reference() } key => !self.is_literal_key(key), }; diff --git a/crates/oxc_transformer_dts/src/diagnostics.rs b/crates/oxc_transformer_dts/src/diagnostics.rs index 8395d0adf7cf..4ea844f08540 100644 --- a/crates/oxc_transformer_dts/src/diagnostics.rs +++ b/crates/oxc_transformer_dts/src/diagnostics.rs @@ -36,3 +36,8 @@ pub fn enum_member_initializers(span: Span) -> OxcDiagnostic { OxcDiagnostic::error("Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.") .with_label(span) } + +pub fn extends_clause_expression(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("Extends clause can't contain an expression with --isolatedDeclarations.") + .with_label(span) +}