feat(ast)!: group class heritage into ClassHeritage (#25360)

## Summary

- Groups `Class::super_class` and `Class::super_type_arguments` into `Class::heritage`.
- Introduces `ClassHeritage` containing the superclass expression and its optional TypeScript type arguments.
- Makes superclass type arguments without a superclass expression unrepresentable.

## Breaking Change

The Rust AST changes from:

```rust
pub struct Class<'a> {
    pub node_id: Cell<NodeId>,
    pub span: Span,
    pub r#type: ClassType,
    pub decorators: Vec<'a, Decorator<'a>>,
    pub id: Option<BindingIdentifier<'a>>,
    #[ts]
    pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
    pub super_class: Option<Expression<'a>>,
    #[ts]
    pub super_type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
    #[ts]
    pub implements: Vec<'a, TSClassImplements<'a>>,
    pub body: Box<'a, ClassBody<'a>>,
    #[ts]
    pub r#abstract: bool,
    #[ts]
    pub declare: bool,
    pub scope_id: Cell<Option<ScopeId>>,
}
```

to:

```rust
pub struct Class<'a> {
    pub node_id: Cell<NodeId>,
    pub span: Span,
    pub r#type: ClassType,
    pub decorators: Vec<'a, Decorator<'a>>,
    pub id: Option<BindingIdentifier<'a>>,
    #[ts]
    pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
    pub heritage: Option<ClassHeritage<'a>>,
    #[ts]
    pub implements: Vec<'a, TSClassImplements<'a>>,
    pub body: Box<'a, ClassBody<'a>>,
    #[ts]
    pub r#abstract: bool,
    #[ts]
    pub declare: bool,
    pub scope_id: Cell<Option<ScopeId>>,
}

pub struct ClassHeritage<'a> {
    pub expression: Expression<'a>,
    #[ts]
    pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
}
```

## Why?

ECMAScript defines the complete `extends` clause as `ClassHeritage`:

```text
ClassHeritage : extends LeftHandSideExpression
```

TypeScript additionally permits type arguments on the heritage expression:

```ts
class Derived extends Base<T> {}
```

Previously, the AST stored the expression and type arguments independently:

```text
Class {
    super_class: Some(Base),
    super_type_arguments: Some(<T>),
    ...
}
```

This allowed an invalid state to be constructed:

```text
Class {
    super_class: None,
    super_type_arguments: Some(<T>),
    ...
}
```

Superclass type arguments cannot exist without an `extends` expression.

The parser already treated these fields as a pair. It parsed a class heritage entry and then split its expression and type arguments into two independent fields. Builders and transforms therefore had to preserve their relationship manually.

Grouping them into `ClassHeritage` makes the syntactic dependency explicit and prevents consumers from observing or constructing contradictory class heritage.

## Class heritage forms

A class without an `extends` clause has no heritage:

```js
class Base {}
```

```text
Class {
    heritage: None,
    ...
}
```

A class extending an expression has heritage without type arguments:

```js
class Derived extends Base {}
```

```text
Class {
    heritage: Some(ClassHeritage {
        expression: Base,
        type_arguments: None,
    }),
    ...
}
```

TypeScript type arguments belong to the same heritage structure:

```ts
class Derived extends Base<T> {}
```

```text
Class {
    heritage: Some(ClassHeritage {
        expression: Base,
        type_arguments: Some(<T>),
    }),
    ...
}
```

The heritage expression may be any valid class heritage expression:

```js
class Derived extends mixin(Base) {}
class NullDerived extends null {}
```

## How to migrate

Code that previously accessed the superclass expression directly:

```rust
if let Some(super_class) = &class.super_class {
    // ...
}
```

can use the compatibility accessor:

```rust
if let Some(super_class) = class.super_class() {
    // ...
}
```

Code that needs both parts should access the grouped heritage:

```rust
if let Some(heritage) = &class.heritage {
    let expression = &heritage.expression;
    let type_arguments = heritage.type_arguments.as_deref();
}
```

Mutating consumers should update the nested fields:

```rust
if let Some(heritage) = &mut class.heritage {
    heritage.type_arguments = None;
}
```

Common migrations:

| Previous representation | New representation |
| --- | --- |
| `class.super_class` | `class.heritage.as_ref().map(\|h\| &h.expression)` or `class.super_class()` |
| `class.super_type_arguments` | `class.heritage.as_ref()?.type_arguments` or `class.super_type_arguments()` |
| `class.super_class.is_some()` | `class.heritage.is_some()` |
| Mutate `class.super_class` | Mutate `class.heritage.expression` |
| Clear `class.super_type_arguments` | Clear `class.heritage.type_arguments` |
| Pass superclass and type arguments separately to a `Class` builder | Construct and pass `ClassHeritage` |
| Clone both fields independently | Clone `class.heritage` |

```ts
superClass: Expression | null;
superTypeArguments?: TSTypeParameterInstantiation | null;
```

No `heritage` property or `ClassHeritage` node is added to the ESTree output.

fixes https://github.com/oxc-project/backlog/issues/216
This commit is contained in:
camc314 committed 2026-08-07 14:18:59 +00:00
1 parent 275c2f8302
commit a33788e13e
73 files changed
+2189 -2136

No files matched your search

+7 -3
View File
@@ -2714,12 +2714,16 @@ function deserializeClass(pos) {
end: (end = deserializeI32(pos + 4)),
range: [start, end],
parent,
});
}),
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.typeParameters = deserializeOptionBoxTSTypeParameterDeclaration(pos + 72);
node.superClass = deserializeOptionExpression(pos + 80);
node.superTypeArguments = deserializeOptionBoxTSTypeParameterInstantiation(pos + 96);
node.superClass = superClass;
node.superTypeArguments =
superClass === null
? null
: deserializeOptionBoxTSTypeParameterInstantiation(pos + 80 + (pos + 16 - pos));
node.implements = deserializeVecTSClassImplements(pos + 104);
node.body = deserializeBoxClassBody(pos + 128);
parent = previousParent;
+41 -12
View File
@@ -2057,6 +2057,22 @@ pub struct YieldExpression<'a> {
#[derive(Debug)]
#[generate_derive(CloneIn, Dummy, ReplaceWith, TakeIn)]
#[generate_derive(ContentEq, ESTree, GetSpan, GetSpanMut, UnstableAddress)]
#[estree(
add_fields(superClass = ClassSuperClass, superTypeArguments = ClassSuperTypeArguments),
field_order(
r#type,
decorators,
id,
type_parameters,
superClass,
superTypeArguments,
implements,
body,
r#abstract,
declare,
span,
),
)]
pub struct Class<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
@@ -2077,23 +2093,15 @@ pub struct Class<'a> {
#[scope(enter_before)]
#[ts]
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
/// Super class. When present, this will usually be an [`IdentifierReference`].
///
/// ## Example
/// ```ts
/// class Foo extends Bar {}
/// // ^^^
/// ```
pub super_class: Option<Expression<'a>>,
/// Type parameters passed to super class.
/// The class heritage.
///
/// ## Example
/// ```ts
/// class Foo<T> extends Bar<T> {}
/// // ^
/// // ^^^^^^^^^^^^^^
/// ```
#[ts]
pub super_type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
#[estree(skip)]
pub heritage: Option<ClassHeritage<'a>>,
/// Interface implementation clause for TypeScript classes.
///
/// ## Example
@@ -2127,6 +2135,27 @@ pub struct Class<'a> {
pub scope_id: Cell<Option<ScopeId>>,
}
/// The expression and optional type arguments in a class heritage clause.
///
/// ```ts
/// class Foo extends Bar<Baz> {}
/// // ^^^ ^^^^^
/// // | |
/// // | +-- type_arguments
/// // +------ expression
/// ```
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, Dummy, ReplaceWith, TakeIn, ContentEq, ESTree)]
#[estree(skip, no_type, no_ts_def)]
pub struct ClassHeritage<'a> {
/// Superclass expression. This will usually be an [`IdentifierReference`].
pub expression: Expression<'a>,
/// Type arguments passed to the superclass.
#[ts]
pub type_arguments: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
}
#[ast]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[generate_derive(CloneIn, Dummy, ContentEq, ESTree)]
+32
View File
@@ -1651,6 +1651,28 @@ impl<'a> ArrowFunctionExpression<'a> {
}
impl<'a> Class<'a> {
/// Returns the expression in this class's heritage clause, when present.
///
/// ```ts
/// class Foo extends Bar<Baz> {}
/// // ^^^
/// ```
#[inline]
pub fn heritage_expression(&self) -> Option<&Expression<'a>> {
self.heritage.as_ref().map(|heritage| &heritage.expression)
}
/// Returns the type arguments in this class's heritage clause, when present.
///
/// ```ts
/// class Foo extends Bar<Baz> {}
/// // ^^^^^
/// ```
#[inline]
pub fn heritage_type_arguments(&self) -> Option<&TSTypeParameterInstantiation<'a>> {
self.heritage.as_ref()?.type_arguments.as_deref()
}
/// Returns this [`Class`]'s name, if it has one.
#[inline]
pub fn name(&self) -> Option<Ident<'a>> {
@@ -1685,6 +1707,16 @@ impl<'a> Class<'a> {
}
}
impl GetSpan for ClassHeritage<'_> {
#[inline]
fn span(&self) -> Span {
let expression_span = self.expression.span();
self.type_arguments
.as_ref()
.map_or(expression_span, |type_arguments| expression_span.merge(type_arguments.span))
}
}
impl<'a> ClassElement<'a> {
/// Returns `true` if this is a [`ClassElement::StaticBlock`].
pub fn is_static_block(&self) -> bool {
+14 -4
View File
@@ -735,14 +735,19 @@ const _: () = {
assert!(offset_of!(Class, decorators) == 16);
assert!(offset_of!(Class, id) == 40);
assert!(offset_of!(Class, type_parameters) == 72);
assert!(offset_of!(Class, super_class) == 80);
assert!(offset_of!(Class, super_type_arguments) == 96);
assert!(offset_of!(Class, heritage) == 80);
assert!(offset_of!(Class, implements) == 104);
assert!(offset_of!(Class, body) == 128);
assert!(offset_of!(Class, r#type) == 136);
assert!(offset_of!(Class, r#abstract) == 137);
assert!(offset_of!(Class, declare) == 138);
// Padding: 0 bytes
assert!(size_of::<ClassHeritage>() == 24);
assert!(align_of::<ClassHeritage>() == 8);
assert!(offset_of!(ClassHeritage, expression) == 0);
assert!(offset_of!(ClassHeritage, type_arguments) == 16);
assert!(size_of::<ClassType>() == 1);
assert!(align_of::<ClassType>() == 1);
@@ -2572,14 +2577,19 @@ const _: () = if cfg!(target_family = "wasm") || align_of::<u64>() == 8 {
assert!(offset_of!(Class, decorators) == 16);
assert!(offset_of!(Class, id) == 32);
assert!(offset_of!(Class, type_parameters) == 60);
assert!(offset_of!(Class, super_class) == 64);
assert!(offset_of!(Class, super_type_arguments) == 72);
assert!(offset_of!(Class, heritage) == 64);
assert!(offset_of!(Class, implements) == 76);
assert!(offset_of!(Class, body) == 92);
assert!(offset_of!(Class, r#type) == 96);
assert!(offset_of!(Class, r#abstract) == 97);
assert!(offset_of!(Class, declare) == 98);
// Padding: 0 bytes
assert!(size_of::<ClassHeritage>() == 12);
assert!(align_of::<ClassHeritage>() == 4);
assert!(offset_of!(ClassHeritage, expression) == 0);
assert!(offset_of!(ClassHeritage, type_arguments) == 8);
assert!(size_of::<ClassType>() == 1);
assert!(align_of::<ClassType>() == 1);
+96 -156
View File
@@ -538,8 +538,7 @@ impl<'a> Expression<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -551,8 +550,7 @@ impl<'a> Expression<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -565,8 +563,7 @@ impl<'a> Expression<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -585,8 +582,7 @@ impl<'a> Expression<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -599,8 +595,7 @@ impl<'a> Expression<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -614,8 +609,7 @@ impl<'a> Expression<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -2072,8 +2066,7 @@ impl<'a> ArrayExpressionElement<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -2085,8 +2078,7 @@ impl<'a> ArrayExpressionElement<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -2099,8 +2091,7 @@ impl<'a> ArrayExpressionElement<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -2119,8 +2110,7 @@ impl<'a> ArrayExpressionElement<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -2133,8 +2123,7 @@ impl<'a> ArrayExpressionElement<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -2148,8 +2137,7 @@ impl<'a> ArrayExpressionElement<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -3513,8 +3501,7 @@ impl<'a> PropertyKey<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -3526,8 +3513,7 @@ impl<'a> PropertyKey<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -3540,8 +3526,7 @@ impl<'a> PropertyKey<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -3560,8 +3545,7 @@ impl<'a> PropertyKey<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -3574,8 +3558,7 @@ impl<'a> PropertyKey<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -3589,8 +3572,7 @@ impl<'a> PropertyKey<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -5461,8 +5443,7 @@ impl<'a> Argument<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -5474,8 +5455,7 @@ impl<'a> Argument<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -5488,8 +5468,7 @@ impl<'a> Argument<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -5508,8 +5487,7 @@ impl<'a> Argument<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -5522,8 +5500,7 @@ impl<'a> Argument<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -5537,8 +5514,7 @@ impl<'a> Argument<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -8611,8 +8587,7 @@ impl<'a> Statement<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -8624,8 +8599,7 @@ impl<'a> Statement<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -8638,8 +8612,7 @@ impl<'a> Statement<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -8658,8 +8631,7 @@ impl<'a> Statement<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -8672,8 +8644,7 @@ impl<'a> Statement<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -8687,8 +8658,7 @@ impl<'a> Statement<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -9506,8 +9476,7 @@ impl<'a> Declaration<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -9519,8 +9488,7 @@ impl<'a> Declaration<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -9533,8 +9501,7 @@ impl<'a> Declaration<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -9553,8 +9520,7 @@ impl<'a> Declaration<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -9567,8 +9533,7 @@ impl<'a> Declaration<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -9582,8 +9547,7 @@ impl<'a> Declaration<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -10815,8 +10779,7 @@ impl<'a> ForStatementInit<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -10828,8 +10791,7 @@ impl<'a> ForStatementInit<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -10842,8 +10804,7 @@ impl<'a> ForStatementInit<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -10862,8 +10823,7 @@ impl<'a> ForStatementInit<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -10876,8 +10836,7 @@ impl<'a> ForStatementInit<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -10891,8 +10850,7 @@ impl<'a> ForStatementInit<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -13883,8 +13841,7 @@ impl<'a> ArrowFunctionBody<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -13896,8 +13853,7 @@ impl<'a> ArrowFunctionBody<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -13910,8 +13866,7 @@ impl<'a> ArrowFunctionBody<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -13930,8 +13885,7 @@ impl<'a> ArrowFunctionBody<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -13944,8 +13898,7 @@ impl<'a> ArrowFunctionBody<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -13959,8 +13912,7 @@ impl<'a> ArrowFunctionBody<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -14870,8 +14822,7 @@ impl<'a> Class<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -14883,8 +14834,7 @@ impl<'a> Class<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -14899,8 +14849,7 @@ impl<'a> Class<'a> {
decorators: decorators.into_in(builder.allocator()),
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements: implements.into_in(builder.allocator()),
body,
r#abstract,
@@ -14920,8 +14869,7 @@ impl<'a> Class<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -14933,8 +14881,7 @@ impl<'a> Class<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -14949,8 +14896,7 @@ impl<'a> Class<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -14972,8 +14918,7 @@ impl<'a> Class<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -14986,8 +14931,7 @@ impl<'a> Class<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -15003,8 +14947,7 @@ impl<'a> Class<'a> {
decorators: decorators.into_in(builder.allocator()),
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements: implements.into_in(builder.allocator()),
body,
r#abstract,
@@ -15024,8 +14967,7 @@ impl<'a> Class<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -15038,8 +14980,7 @@ impl<'a> Class<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -15055,8 +14996,7 @@ impl<'a> Class<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -15069,6 +15009,24 @@ impl<'a> Class<'a> {
}
}
impl<'a> ClassHeritage<'a> {
/// Build a [`ClassHeritage`].
///
/// ## Parameters
/// * `expression`: Superclass expression. This will usually be an [`IdentifierReference`].
/// * `type_arguments`: Type arguments passed to the superclass.
#[expect(unused_variables)]
#[inline]
pub fn new(
expression: Expression<'a>,
type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
builder: &impl GetAstBuilder<'a>,
) -> Self {
let builder = builder.builder();
ClassHeritage { expression, type_arguments }
}
}
impl<'a> ClassBody<'a> {
/// Build a [`ClassBody`].
///
@@ -16765,8 +16723,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -16778,8 +16735,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -16792,8 +16748,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -16812,8 +16767,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -16826,8 +16780,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -16841,8 +16794,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -17358,8 +17310,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -17371,8 +17322,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -17385,8 +17335,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -17405,8 +17354,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -17419,8 +17367,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -17434,8 +17381,7 @@ impl<'a> ExportDefaultDeclarationKind<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -19555,8 +19501,7 @@ impl<'a> JSXExpression<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -19568,8 +19513,7 @@ impl<'a> JSXExpression<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -19582,8 +19526,7 @@ impl<'a> JSXExpression<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -19602,8 +19545,7 @@ impl<'a> JSXExpression<'a> {
/// * `decorators`: Decorators applied to the class.
/// * `id`: Class identifier, AKA the name
/// * `type_parameters`
/// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`].
/// * `super_type_arguments`: Type parameters passed to super class.
/// * `heritage`: The class heritage.
/// * `implements`: Interface implementation clause for TypeScript classes.
/// * `body`
/// * `abstract`: Whether the class is abstract
@@ -19616,8 +19558,7 @@ impl<'a> JSXExpression<'a> {
decorators: impl IntoIn<'a, ArenaVec<'a, Decorator<'a>>>,
id: Option<BindingIdentifier<'a>>,
type_parameters: Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>,
super_class: Option<Expression<'a>>,
super_type_arguments: Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>,
heritage: Option<ClassHeritage<'a>>,
implements: impl IntoIn<'a, ArenaVec<'a, TSClassImplements<'a>>>,
body: ArenaBox<'a, ClassBody<'a>>,
r#abstract: bool,
@@ -19631,8 +19572,7 @@ impl<'a> JSXExpression<'a> {
decorators,
id,
type_parameters,
super_class,
super_type_arguments,
heritage,
implements,
body,
r#abstract,
@@ -2438,12 +2438,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for Class<'_> {
with_semantic_ids,
allocator,
),
super_class: CloneIn::clone_in_impl(&self.super_class, with_semantic_ids, allocator),
super_type_arguments: CloneIn::clone_in_impl(
&self.super_type_arguments,
with_semantic_ids,
allocator,
),
heritage: CloneIn::clone_in_impl(&self.heritage, with_semantic_ids, allocator),
implements: CloneIn::clone_in_impl(&self.implements, with_semantic_ids, allocator),
body: CloneIn::clone_in_impl(&self.body, with_semantic_ids, allocator),
r#abstract: CloneIn::clone_in_impl(&self.r#abstract, with_semantic_ids, allocator),
@@ -2456,6 +2451,25 @@ impl<'new_alloc> CloneIn<'new_alloc> for Class<'_> {
}
}
impl<'new_alloc> CloneIn<'new_alloc> for ClassHeritage<'_> {
type Cloned = ClassHeritage<'new_alloc>;
fn clone_in_impl(
&self,
with_semantic_ids: CloneInSemanticIds,
allocator: &'new_alloc Allocator,
) -> Self::Cloned {
ClassHeritage {
expression: CloneIn::clone_in_impl(&self.expression, with_semantic_ids, allocator),
type_arguments: CloneIn::clone_in_impl(
&self.type_arguments,
with_semantic_ids,
allocator,
),
}
}
}
impl<'new_alloc> CloneIn<'new_alloc> for ClassType {
type Cloned = ClassType;
@@ -1205,8 +1205,7 @@ impl ContentEq for Class<'_> {
&& ContentEq::content_eq(&self.decorators, &other.decorators)
&& ContentEq::content_eq(&self.id, &other.id)
&& ContentEq::content_eq(&self.type_parameters, &other.type_parameters)
&& ContentEq::content_eq(&self.super_class, &other.super_class)
&& ContentEq::content_eq(&self.super_type_arguments, &other.super_type_arguments)
&& ContentEq::content_eq(&self.heritage, &other.heritage)
&& ContentEq::content_eq(&self.implements, &other.implements)
&& ContentEq::content_eq(&self.body, &other.body)
&& ContentEq::content_eq(&self.r#abstract, &other.r#abstract)
@@ -1214,6 +1213,13 @@ impl ContentEq for Class<'_> {
}
}
impl ContentEq for ClassHeritage<'_> {
fn content_eq(&self, other: &Self) -> bool {
ContentEq::content_eq(&self.expression, &other.expression)
&& ContentEq::content_eq(&self.type_arguments, &other.type_arguments)
}
}
impl ContentEq for ClassType {
fn content_eq(&self, other: &Self) -> bool {
self == other
+10 -2
View File
@@ -1315,8 +1315,7 @@ impl<'a> Dummy<'a> for Class<'a> {
decorators: Dummy::dummy(allocator),
id: Dummy::dummy(allocator),
type_parameters: Dummy::dummy(allocator),
super_class: Dummy::dummy(allocator),
super_type_arguments: Dummy::dummy(allocator),
heritage: Dummy::dummy(allocator),
implements: Dummy::dummy(allocator),
body: Dummy::dummy(allocator),
r#abstract: Dummy::dummy(allocator),
@@ -1326,6 +1325,15 @@ impl<'a> Dummy<'a> for Class<'a> {
}
}
impl<'a> Dummy<'a> for ClassHeritage<'a> {
/// Create a dummy [`ClassHeritage`].
///
/// Has cost of making 1 allocation (16 bytes).
fn dummy(allocator: &'a Allocator) -> Self {
Self { expression: Dummy::dummy(allocator), type_arguments: Dummy::dummy(allocator) }
}
}
impl<'a> Dummy<'a> for ClassType {
/// Create a dummy [`ClassType`].
///
+14 -2
View File
@@ -1464,8 +1464,11 @@ impl ESTree for Class<'_> {
state.serialize_field("decorators", &self.decorators);
state.serialize_field("id", &self.id);
state.serialize_ts_field("typeParameters", &self.type_parameters);
state.serialize_field("superClass", &self.super_class);
state.serialize_ts_field("superTypeArguments", &self.super_type_arguments);
state.serialize_field("superClass", &crate::serialize::js::ClassSuperClass(self));
state.serialize_ts_field(
"superTypeArguments",
&crate::serialize::js::ClassSuperTypeArguments(self),
);
state.serialize_ts_field("implements", &self.implements);
state.serialize_field("body", &self.body);
state.serialize_ts_field("abstract", &self.r#abstract);
@@ -1475,6 +1478,15 @@ impl ESTree for Class<'_> {
}
}
impl ESTree for ClassHeritage<'_> {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut state = serializer.serialize_struct();
state.serialize_field("expression", &self.expression);
state.serialize_ts_field("typeArguments", &self.type_arguments);
state.end();
}
}
impl ESTree for ClassType {
fn serialize<S: Serializer>(&self, serializer: S) {
match self {
@@ -200,6 +200,8 @@ impl<'a> ReplaceWith<'a> for YieldExpression<'a> {}
impl<'a> ReplaceWith<'a> for Class<'a> {}
impl<'a> ReplaceWith<'a> for ClassHeritage<'a> {}
impl<'a> ReplaceWith<'a> for ClassBody<'a> {}
impl<'a> ReplaceWith<'a> for ClassElement<'a> {}
@@ -202,6 +202,8 @@ impl<'a> TakeIn<'a> for YieldExpression<'a> {}
impl<'a> TakeIn<'a> for Class<'a> {}
impl<'a> TakeIn<'a> for ClassHeritage<'a> {}
impl<'a> TakeIn<'a> for ClassBody<'a> {}
impl<'a> TakeIn<'a> for ClassElement<'a> {}
+30
View File
@@ -13,6 +13,36 @@ use crate::ast::*;
use super::{EmptyArray, Null};
/// Preserve ESTree's nullable `superClass` field while the Rust AST groups class heritage.
#[ast_meta]
#[estree(
ts_type = "Expression | null",
raw_deser = "DESER[Option<Expression>](POS_OFFSET.heritage)"
)]
pub struct ClassSuperClass<'a, 'b>(pub &'b Class<'a>);
impl ESTree for ClassSuperClass<'_, '_> {
fn serialize<S: Serializer>(&self, serializer: S) {
self.0.heritage_expression().serialize(serializer);
}
}
/// Preserve TS-ESTree's nullable `superTypeArguments` field while the Rust AST groups class
/// heritage.
#[ast_meta]
#[estree(
ts_type = "TSTypeParameterInstantiation | null",
raw_deser = "THIS.superClass === null ? null : DESER[Option<Box<TSTypeParameterInstantiation>>](POS_OFFSET.heritage + (POS_OFFSET<ClassHeritage>.type_arguments - pos))"
)]
#[ts]
pub struct ClassSuperTypeArguments<'a, 'b>(pub &'b Class<'a>);
impl ESTree for ClassSuperTypeArguments<'_, '_> {
fn serialize<S: Serializer>(&self, serializer: S) {
self.0.heritage_type_arguments().serialize(serializer);
}
}
// ----------------------------------------
// Meta properties
// ----------------------------------------
File diff suppressed because it is too large. Load diff
+16 -5
View File
@@ -521,6 +521,11 @@ pub trait Visit<'a>: Sized {
walk_class(self, it);
}
#[inline]
fn visit_class_heritage(&mut self, it: &ClassHeritage<'a>) {
walk_class_heritage(self, it);
}
#[inline]
fn visit_class_body(&mut self, it: &ClassBody<'a>) {
walk_class_body(self, it);
@@ -2608,11 +2613,8 @@ pub mod walk {
if let Some(type_parameters) = &it.type_parameters {
visitor.visit_ts_type_parameter_declaration(type_parameters);
}
if let Some(super_class) = &it.super_class {
visitor.visit_expression(super_class);
}
if let Some(super_type_arguments) = &it.super_type_arguments {
visitor.visit_ts_type_parameter_instantiation(super_type_arguments);
if let Some(heritage) = &it.heritage {
visitor.visit_class_heritage(heritage);
}
visitor.visit_ts_class_implements_list(&it.implements);
visitor.visit_class_body(&it.body);
@@ -2620,6 +2622,15 @@ pub mod walk {
visitor.leave_node(kind);
}
#[inline]
pub fn walk_class_heritage<'a, V: Visit<'a>>(visitor: &mut V, it: &ClassHeritage<'a>) {
// No `AstKind` for this type
visitor.visit_expression(&it.expression);
if let Some(type_arguments) = &it.type_arguments {
visitor.visit_ts_type_parameter_instantiation(type_arguments);
}
}
#[inline]
pub fn walk_class_body<'a, V: Visit<'a>>(visitor: &mut V, it: &ClassBody<'a>) {
let kind = AstKind::ClassBody(visitor.alloc(it));
+13 -2
View File
@@ -548,6 +548,11 @@ pub trait VisitJs<'a>: Sized {
walk_class(self, it);
}
#[inline]
fn visit_class_heritage(&mut self, it: &ClassHeritage<'a>) {
walk_class_heritage(self, it);
}
#[inline]
fn visit_class_body(&mut self, it: &ClassBody<'a>) {
walk_class_body(self, it);
@@ -2263,14 +2268,20 @@ pub mod walk_js {
visitor.visit_binding_identifier(id);
}
visitor.enter_scope(ScopeFlags::StrictMode, &it.scope_id);
if let Some(super_class) = &it.super_class {
visitor.visit_expression(super_class);
if let Some(heritage) = &it.heritage {
visitor.visit_class_heritage(heritage);
}
visitor.visit_class_body(&it.body);
visitor.leave_scope();
visitor.leave_node(kind);
}
#[inline]
pub fn walk_class_heritage<'a, V: VisitJs<'a>>(visitor: &mut V, it: &ClassHeritage<'a>) {
// No `AstKind` for this type
visitor.visit_expression(&it.expression);
}
#[inline]
pub fn walk_class_body<'a, V: VisitJs<'a>>(visitor: &mut V, it: &ClassBody<'a>) {
let kind = AstKind::ClassBody(visitor.alloc(it));
@@ -540,6 +540,11 @@ pub trait VisitJsMut<'a>: Sized {
walk_class(self, it);
}
#[inline]
fn visit_class_heritage(&mut self, it: &mut ClassHeritage<'a>) {
walk_class_heritage(self, it);
}
#[inline]
fn visit_class_body(&mut self, it: &mut ClassBody<'a>) {
walk_class_body(self, it);
@@ -2362,14 +2367,20 @@ pub mod walk_js_mut {
visitor.visit_binding_identifier(id);
}
visitor.enter_scope(ScopeFlags::StrictMode, &it.scope_id);
if let Some(super_class) = &mut it.super_class {
visitor.visit_expression(super_class);
if let Some(heritage) = &mut it.heritage {
visitor.visit_class_heritage(heritage);
}
visitor.visit_class_body(&mut it.body);
visitor.leave_scope();
visitor.leave_node(kind);
}
#[inline]
pub fn walk_class_heritage<'a, V: VisitJsMut<'a>>(visitor: &mut V, it: &mut ClassHeritage<'a>) {
// No `AstType` for this type
visitor.visit_expression(&mut it.expression);
}
#[inline]
pub fn walk_class_body<'a, V: VisitJsMut<'a>>(visitor: &mut V, it: &mut ClassBody<'a>) {
let kind = AstType::ClassBody;
@@ -513,6 +513,11 @@ pub trait VisitMut<'a>: Sized {
walk_class(self, it);
}
#[inline]
fn visit_class_heritage(&mut self, it: &mut ClassHeritage<'a>) {
walk_class_heritage(self, it);
}
#[inline]
fn visit_class_body(&mut self, it: &mut ClassBody<'a>) {
walk_class_body(self, it);
@@ -2699,11 +2704,8 @@ pub mod walk_mut {
if let Some(type_parameters) = &mut it.type_parameters {
visitor.visit_ts_type_parameter_declaration(type_parameters);
}
if let Some(super_class) = &mut it.super_class {
visitor.visit_expression(super_class);
}
if let Some(super_type_arguments) = &mut it.super_type_arguments {
visitor.visit_ts_type_parameter_instantiation(super_type_arguments);
if let Some(heritage) = &mut it.heritage {
visitor.visit_class_heritage(heritage);
}
visitor.visit_ts_class_implements_list(&mut it.implements);
visitor.visit_class_body(&mut it.body);
@@ -2711,6 +2713,15 @@ pub mod walk_mut {
visitor.leave_node(kind);
}
#[inline]
pub fn walk_class_heritage<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut ClassHeritage<'a>) {
// No `AstType` for this type
visitor.visit_expression(&mut it.expression);
if let Some(type_arguments) = &mut it.type_arguments {
visitor.visit_ts_type_parameter_instantiation(type_arguments);
}
}
#[inline]
pub fn walk_class_body<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut ClassBody<'a>) {
let kind = AstType::ClassBody;
@@ -141,11 +141,11 @@ impl Utf8ToUtf16Converter<'_> {
if let Some(type_parameters) = &mut class.type_parameters {
self.visit_ts_type_parameter_declaration(type_parameters);
}
if let Some(super_class) = &mut class.super_class {
self.visit_expression(super_class);
}
if let Some(super_type_arguments) = &mut class.super_type_arguments {
self.visit_ts_type_parameter_instantiation(super_type_arguments);
if let Some(heritage) = &mut class.heritage {
self.visit_expression(&mut heritage.expression);
if let Some(type_arguments) = &mut heritage.type_arguments {
self.visit_ts_type_parameter_instantiation(type_arguments);
}
}
self.visit_ts_class_implements_list(&mut class.implements);
self.visit_class_body(&mut class.body);
+3 -3
View File
@@ -2545,12 +2545,12 @@ impl Gen for Class<'_> {
if let Some(type_parameters) = self.type_parameters.as_ref() {
type_parameters.print(p, ctx);
}
if let Some(super_class) = self.super_class.as_ref() {
if let Some(heritage) = &self.heritage {
p.print_soft_space();
p.print_space_before_identifier();
p.print_str("extends ");
super_class.print_expr(p, Precedence::Postfix, Context::empty());
if let Some(super_type_parameters) = &self.super_type_arguments {
heritage.expression.print_expr(p, Precedence::Postfix, Context::empty());
if let Some(super_type_parameters) = &heritage.type_arguments {
super_type_parameters.print(p, ctx);
}
}
@@ -357,7 +357,7 @@ impl<'a> MayHaveSideEffects<'a> for Class<'a> {
// Example cases: `class A extends 0 {}`, `class A extends (async function() {}) {}`
// Considering these cases is difficult and requires to de-opt most classes with a super class.
// To allow classes with a super class to be removed, we ignore this side effect.
if self.super_class.as_ref().is_some_and(|sup| {
if self.heritage_expression().is_some_and(|sup| {
// `(class C extends (() => {}))` is TypeError.
matches!(sup.without_parentheses(), Expression::ArrowFunctionExpression(_))
|| sup.may_have_side_effects(ctx)
@@ -5029,8 +5029,7 @@ impl<'a> AstNode<'a, Class<'a>> {
.as_ref()
.map(|n| n.span().start)
.or_else(|| self.inner.type_parameters.as_deref().map(|n| n.span().start))
.or_else(|| self.inner.super_class.as_ref().map(|n| n.span().start))
.or_else(|| self.inner.super_type_arguments.as_deref().map(|n| n.span().start))
.or_else(|| self.inner.heritage.as_ref().map(|n| n.span().start))
.or_else(|| self.inner.implements.first().map(|n| n.span().start))
.or_else(|| Some(self.inner.body.span().start))
.unwrap_or(0);
@@ -5049,8 +5048,7 @@ impl<'a> AstNode<'a, Class<'a>> {
.type_parameters
.as_deref()
.map(|n| n.span().start)
.or_else(|| self.inner.super_class.as_ref().map(|n| n.span().start))
.or_else(|| self.inner.super_type_arguments.as_deref().map(|n| n.span().start))
.or_else(|| self.inner.heritage.as_ref().map(|n| n.span().start))
.or_else(|| self.inner.implements.first().map(|n| n.span().start))
.or_else(|| Some(self.inner.body.span().start))
.unwrap_or(0);
@@ -5068,10 +5066,9 @@ impl<'a> AstNode<'a, Class<'a>> {
pub fn type_parameters(&self) -> Option<&AstNode<'a, TSTypeParameterDeclaration<'a>>> {
let following_span_start = self
.inner
.super_class
.heritage
.as_ref()
.map(|n| n.span().start)
.or_else(|| self.inner.super_type_arguments.as_deref().map(|n| n.span().start))
.or_else(|| self.inner.implements.first().map(|n| n.span().start))
.or_else(|| Some(self.inner.body.span().start))
.unwrap_or(0);
@@ -5086,27 +5083,7 @@ impl<'a> AstNode<'a, Class<'a>> {
}
#[inline]
pub fn super_class(&self) -> Option<&AstNode<'a, Expression<'a>>> {
let following_span_start = self
.inner
.super_type_arguments
.as_deref()
.map(|n| n.span().start)
.or_else(|| self.inner.implements.first().map(|n| n.span().start))
.or_else(|| Some(self.inner.body.span().start))
.unwrap_or(0);
self.allocator
.alloc(self.inner.super_class.as_ref().map(|inner| AstNode {
inner,
allocator: self.allocator,
parent: AstNodes::Class(transmute_self(self)),
following_span_start,
}))
.as_ref()
}
#[inline]
pub fn super_type_arguments(&self) -> Option<&AstNode<'a, TSTypeParameterInstantiation<'a>>> {
pub fn heritage(&self) -> Option<&AstNode<'a, ClassHeritage<'a>>> {
let following_span_start = self
.inner
.implements
@@ -5115,8 +5092,8 @@ impl<'a> AstNode<'a, Class<'a>> {
.or_else(|| Some(self.inner.body.span().start))
.unwrap_or(0);
self.allocator
.alloc(self.inner.super_type_arguments.as_ref().map(|inner| AstNode {
inner: inner.as_ref(),
.alloc(self.inner.heritage.as_ref().map(|inner| AstNode {
inner,
allocator: self.allocator,
parent: AstNodes::Class(transmute_self(self)),
following_span_start,
@@ -5166,6 +5143,47 @@ impl<'a> AstNode<'a, Class<'a>> {
}
}
impl<'a> AstNode<'a, ClassHeritage<'a>> {
#[inline]
pub fn expression(&self) -> &AstNode<'a, Expression<'a>> {
let following_span_start = self
.inner
.type_arguments
.as_deref()
.map(|n| n.span().start)
.or(Some(self.following_span_start))
.unwrap_or(0);
self.allocator.alloc(AstNode {
inner: &self.inner.expression,
allocator: self.allocator,
parent: self.parent,
following_span_start,
})
}
#[inline]
pub fn type_arguments(&self) -> Option<&AstNode<'a, TSTypeParameterInstantiation<'a>>> {
let following_span_start = self.following_span_start;
self.allocator
.alloc(self.inner.type_arguments.as_ref().map(|inner| AstNode {
inner: inner.as_ref(),
allocator: self.allocator,
parent: self.parent,
following_span_start,
}))
.as_ref()
}
pub fn format_leading_comments(&self, f: &mut JsFormatter<'_, 'a>) {
format_leading_comments(self.span()).fmt(f);
}
pub fn format_trailing_comments(&self, f: &mut JsFormatter<'_, 'a>) {
format_trailing_comments(self.parent.span(), self.inner.span(), self.following_span_start)
.fmt(f);
}
}
impl<'a> AstNode<'a, ClassBody<'a>> {
#[inline]
pub fn node_id(&self) -> NodeId {
@@ -2599,6 +2599,19 @@ impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, Class<'a>> {
}
}
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ClassHeritage<'a>> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
let is_suppressed = f.comments().is_suppressed(self.span().start);
self.format_leading_comments(f);
if is_suppressed {
FormatSuppressedNode(self.span()).fmt(f);
} else {
self.write(f);
}
self.format_trailing_comments(f);
}
}
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ClassBody<'a>> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
let is_suppressed = f.comments().is_suppressed(self.span().start);
@@ -988,7 +988,8 @@ fn binary_like_needs_parens(binary_like: BinaryLikeExpression<'_, '_>) -> bool {
return computed.object.span() == binary_like.span();
}
AstNodes::Class(class) => {
return class.super_class.as_ref().is_some_and(|super_class| {
return class.heritage().is_some_and(|heritage| {
let super_class = heritage.expression();
super_class.span().contains_inclusive(binary_like.span())
});
}
@@ -1242,7 +1243,7 @@ fn ts_as_or_satisfies_needs_parens(
fn is_class_extends(span: Span, parent: &AstNodes<'_>) -> bool {
if let AstNodes::Class(c) = parent {
return c.super_class.as_ref().is_some_and(|c| c.span() == span);
return c.heritage().is_some_and(|heritage| heritage.expression().span() == span);
}
false
}
+21 -8
View File
@@ -244,6 +244,12 @@ impl<'a> FormatWrite<'a> for AstNode<'a, TSClassImplements<'a>> {
}
}
impl<'a> FormatWrite<'a> for AstNode<'a, ClassHeritage<'a>> {
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
write!(f, [self.expression(), self.type_arguments()]);
}
}
impl<'a> FormatWrite<'a> for AstNode<'a, Class<'a>> {
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
if self.r#type == ClassType::ClassExpression
@@ -270,7 +276,9 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatClass<'a, '_> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
let decorators = self.decorators();
let type_parameters = self.type_parameters();
let super_class = self.super_class();
let heritage = self.heritage();
let super_class = heritage.map(AstNode::<ClassHeritage<'a>>::expression);
let super_type_arguments = heritage.and_then(AstNode::<ClassHeritage<'a>>::type_arguments);
let implements = self.implements();
let body = self.body();
@@ -339,7 +347,7 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatClass<'a, '_> {
if let Some(extends) = super_class {
// Format the extends clause with its expression and optional type arguments
let format_super = format_with(|f| {
let type_arguments = self.super_type_arguments();
let type_arguments = super_type_arguments;
// Collect comments after the extends expression (and type arguments if present)
// These comments need careful handling to preserve their association
@@ -481,14 +489,18 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatClass<'a, '_> {
/// 3. Implements is a qualified name and has no type arguments
/// 4. There are comments in the heritage clause area
/// 5. There are trailing line comments after type parameters
fn should_group<'a>(class: &AstNode<Class<'a>>, f: &JsFormatter<'_, 'a>) -> bool {
if usize::from(class.super_class.is_some()) + class.implements.len() > 1 {
fn should_group<'a>(class: &AstNode<'a, Class<'a>>, f: &JsFormatter<'_, 'a>) -> bool {
let heritage = class.heritage.as_ref();
if usize::from(heritage.is_some()) + class.implements.len() > 1 {
return true;
}
if (!class.is_expression() || !matches!(class.parent(), AstNodes::AssignmentExpression(_)))
&& class.super_class.as_ref().is_some_and(is_member_expression_without_chain_wrappers)
&& class.super_type_arguments.is_none()
&& heritage.is_some_and(|heritage| {
is_member_expression_without_chain_wrappers(&heritage.expression)
})
&& heritage.is_none_or(|heritage| heritage.type_arguments.is_none())
|| class.implements.first().is_some_and(|implements| {
implements.type_arguments.is_none() && implements.expression.is_qualified_name()
})
@@ -500,8 +512,9 @@ fn should_group<'a>(class: &AstNode<Class<'a>>, f: &JsFormatter<'_, 'a>) -> bool
let id_span = class.id.as_ref().map(GetSpan::span);
let type_parameters_span = class.type_parameters.as_ref().map(|t| t.span);
let super_class_span = class.super_class.as_ref().map(GetSpan::span);
let super_type_arguments_span = class.super_type_arguments.as_ref().map(|t| t.span);
let super_class_span = heritage.map(|heritage| heritage.expression.span());
let super_type_arguments_span =
heritage.and_then(|heritage| heritage.type_arguments.as_deref()).map(GetSpan::span);
let implements_span = class.implements.first().map(GetSpan::span);
let spans = [
@@ -464,7 +464,7 @@ impl<'a> IsolatedDeclarations<'a> {
decl: &Class<'a>,
declare: Option<bool>,
) -> ArenaBox<'a, Class<'a>> {
if let Some(super_class) = &decl.super_class {
if let Some(super_class) = decl.heritage_expression() {
let is_not_allowed = match super_class {
Expression::Identifier(_) => false,
Expression::StaticMemberExpression(expr) => {
@@ -719,8 +719,7 @@ impl<'a> IsolatedDeclarations<'a> {
[],
decl.id.clone_in(self.allocator()),
decl.type_parameters.clone_in(self.allocator()),
decl.super_class.clone_in(self.allocator()),
decl.super_type_arguments.clone_in(self.allocator()),
decl.heritage.clone_in(self.allocator()),
decl.implements.clone_in(self.allocator()),
body,
decl.r#abstract,
@@ -220,9 +220,9 @@ impl Rule for ConstructorSuper {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let AstKind::Class(class) = node.kind() else { return };
let super_class_type = Self::classify_super_class(class.super_class.as_ref());
let super_class_type = Self::classify_super_class(class.heritage_expression());
let super_class_context =
Self::super_class_context(super_class_type, class.super_class.as_ref());
Self::super_class_context(super_class_type, class.heritage_expression());
let Some(constructor) = class.body.body.iter().find_map(|elem| {
if let ClassElement::MethodDefinition(method) = elem
@@ -160,7 +160,7 @@ impl NoThisBeforeSuper {
let parent_3 = ctx.nodes().parent_node(parent_2.id());
let class = parent_3.kind().as_class()?;
let super_class = class.super_class.as_ref()?;
let super_class = class.heritage_expression()?;
return Some(!matches!(super_class, Expression::NullLiteral(_)));
}
@@ -213,8 +213,7 @@ impl NoUnsafeOptionalChaining {
}
AstKind::Class(class)
if class
.super_class
.as_ref()
.heritage_expression()
.is_some_and(|expr| expr.node_id() == current_id) =>
{
return Some(ErrorType::Usage);
@@ -128,7 +128,7 @@ impl Rule for NoUselessConstructor {
Some(TSAccessibility::Private | TSAccessibility::Protected) => {
return;
}
Some(TSAccessibility::Public) if class.super_class.is_some() => {
Some(TSAccessibility::Public) if class.heritage.is_some() => {
return;
}
_ => {}
@@ -138,7 +138,7 @@ impl Rule for NoUselessConstructor {
return;
}
if class.super_class.is_none() {
if class.heritage.is_none() {
lint_empty_constructor(ctx, constructor, body);
} else {
lint_redundant_super_call(ctx, constructor, body);
@@ -329,7 +329,7 @@ fn is_create_context_call(call: &oxc_ast::ast::CallExpression) -> bool {
/// Check if a class extends React.Component or React.PureComponent
fn extends_react_component(class: &oxc_ast::ast::Class) -> bool {
class.super_class.as_ref().is_some_and(|super_class| {
class.heritage_expression().is_some_and(|super_class| {
if let Some(member_expr) = super_class.as_member_expression()
&& let Expression::Identifier(ident) = member_expr.object()
{
@@ -408,7 +408,7 @@ fn is_function_returning_null(expr: &Expression) -> bool {
/// Check if a class is an ES6 React component (extends React.Component or React.PureComponent)
fn is_es6_component_class(class: &Class) -> bool {
class.super_class.as_ref().is_some_and(|super_class| {
class.heritage_expression().is_some_and(|super_class| {
if let Some(member_expr) = super_class.as_member_expression()
&& let Expression::Identifier(ident) = member_expr.object()
&& ident.name == "React"
@@ -140,7 +140,7 @@ fn get_should_component_update(class: &Class<'_>) -> Option<Span> {
/// Checks if class is React.PureComponent and returns this class if true
fn is_react_pure_component<'a>(class: &'a Class<'a>) -> bool {
if let Some(super_class) = &class.super_class {
if let Some(super_class) = class.heritage_expression() {
if let Some(member_expr) = super_class.as_member_expression()
&& let Expression::Identifier(ident) = member_expr.object()
{
@@ -625,7 +625,7 @@ impl OnlyExportComponents {
}
fn extends_react_component(class: &Class) -> bool {
class.super_class.as_ref().is_some_and(|super_class| {
class.heritage_expression().is_some_and(|super_class| {
if let Some(member_expr) = super_class.as_member_expression()
&& let Expression::Identifier(ident) = member_expr.object()
&& ident.name == "React"
@@ -123,9 +123,7 @@ impl Rule for NoExtraneousClass {
let AstKind::Class(class) = node.kind() else {
return;
};
if class.super_class.is_some()
|| (self.allow_with_decorator && !class.decorators.is_empty())
{
if class.heritage.is_some() || (self.allow_with_decorator && !class.decorators.is_empty()) {
return;
}
let span = class.id.as_ref().map_or(class.span, |id| id.span);
@@ -283,11 +283,10 @@ fn get_generic_type_argument_name<'a>(
Some(ctx.source_range(interface_heritage.type_name.span()))
}
AstKind::Class(class) => class
.super_type_arguments
.as_ref()
.heritage_type_arguments()
.filter(|type_arguments| type_arguments.span == type_arguments_span)
.and_then(|_| {
class.super_class.as_ref().map(|super_class| ctx.source_range(super_class.span()))
class.heritage_expression().map(|super_class| ctx.source_range(super_class.span()))
}),
_ => None,
}
@@ -337,7 +337,7 @@ fn is_valid_super_class_name(name: &str) -> bool {
}
fn has_valid_super_class(class: &Class) -> bool {
let Some(super_class) = &class.super_class else {
let Some(super_class) = class.heritage_expression() else {
return false;
};
let name = match super_class.get_inner_expression() {
@@ -66,7 +66,7 @@ impl Rule for NoStaticOnlyClass {
return;
};
if class.super_class.is_some() {
if class.heritage.is_some() {
return;
}
if !class.decorators.is_empty() {
@@ -154,7 +154,7 @@ fn get_error_subclass_if_in_constructor<'a>(
fn is_error_class(class: &oxc_ast::ast::Class, ctx: &LintContext) -> bool {
// Check if the class extends a built-in Error type
let Some(super_class) = &class.super_class else {
let Some(super_class) = class.heritage_expression() else {
return false;
};
@@ -58,7 +58,7 @@ impl Rule for PreferEventTarget {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let ident = match node.kind() {
AstKind::Class(class) => {
let Some(Expression::Identifier(ident)) = &class.super_class else {
let Some(Expression::Identifier(ident)) = class.heritage_expression() else {
return;
};
ident
+1 -1
View File
@@ -578,7 +578,7 @@ pub fn is_es6_component(node: &AstNode) -> bool {
let AstKind::Class(class_expr) = node.kind() else {
return false;
};
if let Some(super_class) = &class_expr.super_class {
if let Some(super_class) = class_expr.heritage_expression() {
if let Some(member_expr) = super_class.as_member_expression()
&& let Expression::Identifier(ident) = member_expr.object()
{
+253 -348
View File
@@ -152,178 +152,179 @@ pub(crate) enum AncestorType {
ClassDecorators = 128,
ClassId = 129,
ClassTypeParameters = 130,
ClassSuperClass = 131,
ClassSuperTypeArguments = 132,
ClassImplements = 133,
ClassBody = 134,
ClassBodyBody = 135,
MethodDefinitionDecorators = 136,
MethodDefinitionKey = 137,
MethodDefinitionValue = 138,
PropertyDefinitionDecorators = 139,
PropertyDefinitionKey = 140,
PropertyDefinitionTypeAnnotation = 141,
PropertyDefinitionValue = 142,
StaticBlockBody = 143,
AccessorPropertyDecorators = 144,
AccessorPropertyKey = 145,
AccessorPropertyTypeAnnotation = 146,
AccessorPropertyValue = 147,
ImportExpressionSource = 148,
ImportExpressionOptions = 149,
ImportDeclarationSpecifiers = 150,
ImportDeclarationSource = 151,
ImportDeclarationWithClause = 152,
ImportSpecifierImported = 153,
ImportSpecifierLocal = 154,
ImportDefaultSpecifierLocal = 155,
ImportNamespaceSpecifierLocal = 156,
WithClauseWithEntries = 157,
ImportAttributeKey = 158,
ImportAttributeValue = 159,
ExportDeclarationDeclaration = 160,
ExportNamedDeclarationSpecifiers = 161,
ExportFromDeclarationSpecifiers = 162,
ExportFromDeclarationSource = 163,
ExportFromDeclarationWithClause = 164,
ExportDefaultDeclarationDeclaration = 165,
ExportAllDeclarationExported = 166,
ExportAllDeclarationSource = 167,
ExportAllDeclarationWithClause = 168,
ExportSpecifierLocal = 169,
ExportSpecifierExported = 170,
V8IntrinsicExpressionName = 171,
V8IntrinsicExpressionArguments = 172,
JSXElementOpeningElement = 173,
JSXElementChildren = 174,
JSXElementClosingElement = 175,
JSXOpeningElementName = 176,
JSXOpeningElementTypeArguments = 177,
JSXOpeningElementAttributes = 178,
JSXClosingElementName = 179,
JSXFragmentOpeningFragment = 180,
JSXFragmentChildren = 181,
JSXFragmentClosingFragment = 182,
JSXNamespacedNameNamespace = 183,
JSXNamespacedNameName = 184,
JSXMemberExpressionObject = 185,
JSXMemberExpressionProperty = 186,
JSXExpressionContainerExpression = 187,
JSXAttributeName = 188,
JSXAttributeValue = 189,
JSXSpreadAttributeArgument = 190,
JSXSpreadChildExpression = 191,
TSThisParameterTypeAnnotation = 192,
TSEnumDeclarationId = 193,
TSEnumDeclarationBody = 194,
TSEnumBodyMembers = 195,
TSEnumMemberId = 196,
TSEnumMemberInitializer = 197,
TSTypeAnnotationTypeAnnotation = 198,
TSLiteralTypeLiteral = 199,
TSConditionalTypeCheckType = 200,
TSConditionalTypeExtendsType = 201,
TSConditionalTypeTrueType = 202,
TSConditionalTypeFalseType = 203,
TSUnionTypeTypes = 204,
TSIntersectionTypeTypes = 205,
TSParenthesizedTypeTypeAnnotation = 206,
TSTypeOperatorTypeAnnotation = 207,
TSArrayTypeElementType = 208,
TSIndexedAccessTypeObjectType = 209,
TSIndexedAccessTypeIndexType = 210,
TSTupleTypeElementTypes = 211,
TSNamedTupleMemberLabel = 212,
TSNamedTupleMemberElementType = 213,
TSOptionalTypeTypeAnnotation = 214,
TSRestTypeTypeAnnotation = 215,
TSTypeReferenceTypeName = 216,
TSTypeReferenceTypeArguments = 217,
TSQualifiedNameLeft = 218,
TSQualifiedNameRight = 219,
TSTypeParameterInstantiationParams = 220,
TSTypeParameterName = 221,
TSTypeParameterConstraint = 222,
TSTypeParameterDefault = 223,
TSTypeParameterDeclarationParams = 224,
TSTypeAliasDeclarationId = 225,
TSTypeAliasDeclarationTypeParameters = 226,
TSTypeAliasDeclarationTypeAnnotation = 227,
TSClassImplementsExpression = 228,
TSClassImplementsTypeArguments = 229,
TSInterfaceDeclarationId = 230,
TSInterfaceDeclarationTypeParameters = 231,
TSInterfaceDeclarationExtends = 232,
TSInterfaceDeclarationBody = 233,
TSInterfaceBodyBody = 234,
TSPropertySignatureKey = 235,
TSPropertySignatureTypeAnnotation = 236,
TSIndexSignatureParameter = 237,
TSIndexSignatureTypeAnnotation = 238,
TSCallSignatureDeclarationTypeParameters = 239,
TSCallSignatureDeclarationThisParam = 240,
TSCallSignatureDeclarationParams = 241,
TSCallSignatureDeclarationReturnType = 242,
TSMethodSignatureKey = 243,
TSMethodSignatureTypeParameters = 244,
TSMethodSignatureThisParam = 245,
TSMethodSignatureParams = 246,
TSMethodSignatureReturnType = 247,
TSConstructSignatureDeclarationTypeParameters = 248,
TSConstructSignatureDeclarationParams = 249,
TSConstructSignatureDeclarationReturnType = 250,
TSIndexSignatureNameTypeAnnotation = 251,
TSInterfaceHeritageTypeName = 252,
TSInterfaceHeritageTypeArguments = 253,
TSTypePredicateParameterName = 254,
TSTypePredicateTypeAnnotation = 255,
TSExternalModuleDeclarationId = 256,
TSExternalModuleDeclarationBody = 257,
TSNamespaceDeclarationId = 258,
TSNamespaceDeclarationBody = 259,
TSGlobalDeclarationBody = 260,
TSModuleBlockDirectives = 261,
TSModuleBlockBody = 262,
TSTypeLiteralMembers = 263,
TSInferTypeTypeParameter = 264,
TSTypeQueryExprName = 265,
TSTypeQueryTypeArguments = 266,
TSImportTypeSource = 267,
TSImportTypeOptions = 268,
TSImportTypeQualifier = 269,
TSImportTypeTypeArguments = 270,
TSImportTypeQualifiedNameLeft = 271,
TSImportTypeQualifiedNameRight = 272,
TSFunctionTypeTypeParameters = 273,
TSFunctionTypeThisParam = 274,
TSFunctionTypeParams = 275,
TSFunctionTypeReturnType = 276,
TSConstructorTypeTypeParameters = 277,
TSConstructorTypeParams = 278,
TSConstructorTypeReturnType = 279,
TSMappedTypeKey = 280,
TSMappedTypeConstraint = 281,
TSMappedTypeNameType = 282,
TSMappedTypeTypeAnnotation = 283,
TSTemplateLiteralTypeQuasis = 284,
TSTemplateLiteralTypeTypes = 285,
TSAsExpressionExpression = 286,
TSAsExpressionTypeAnnotation = 287,
TSSatisfiesExpressionExpression = 288,
TSSatisfiesExpressionTypeAnnotation = 289,
TSTypeAssertionTypeAnnotation = 290,
TSTypeAssertionExpression = 291,
TSImportEqualsDeclarationId = 292,
TSImportEqualsDeclarationModuleReference = 293,
TSExternalModuleReferenceExpression = 294,
TSNonNullExpressionExpression = 295,
DecoratorExpression = 296,
TSExportAssignmentExpression = 297,
TSNamespaceExportDeclarationId = 298,
TSInstantiationExpressionExpression = 299,
TSInstantiationExpressionTypeArguments = 300,
JSDocNullableTypeTypeAnnotation = 301,
JSDocNonNullableTypeTypeAnnotation = 302,
ClassHeritage = 131,
ClassImplements = 132,
ClassBody = 133,
ClassHeritageExpression = 134,
ClassHeritageTypeArguments = 135,
ClassBodyBody = 136,
MethodDefinitionDecorators = 137,
MethodDefinitionKey = 138,
MethodDefinitionValue = 139,
PropertyDefinitionDecorators = 140,
PropertyDefinitionKey = 141,
PropertyDefinitionTypeAnnotation = 142,
PropertyDefinitionValue = 143,
StaticBlockBody = 144,
AccessorPropertyDecorators = 145,
AccessorPropertyKey = 146,
AccessorPropertyTypeAnnotation = 147,
AccessorPropertyValue = 148,
ImportExpressionSource = 149,
ImportExpressionOptions = 150,
ImportDeclarationSpecifiers = 151,
ImportDeclarationSource = 152,
ImportDeclarationWithClause = 153,
ImportSpecifierImported = 154,
ImportSpecifierLocal = 155,
ImportDefaultSpecifierLocal = 156,
ImportNamespaceSpecifierLocal = 157,
WithClauseWithEntries = 158,
ImportAttributeKey = 159,
ImportAttributeValue = 160,
ExportDeclarationDeclaration = 161,
ExportNamedDeclarationSpecifiers = 162,
ExportFromDeclarationSpecifiers = 163,
ExportFromDeclarationSource = 164,
ExportFromDeclarationWithClause = 165,
ExportDefaultDeclarationDeclaration = 166,
ExportAllDeclarationExported = 167,
ExportAllDeclarationSource = 168,
ExportAllDeclarationWithClause = 169,
ExportSpecifierLocal = 170,
ExportSpecifierExported = 171,
V8IntrinsicExpressionName = 172,
V8IntrinsicExpressionArguments = 173,
JSXElementOpeningElement = 174,
JSXElementChildren = 175,
JSXElementClosingElement = 176,
JSXOpeningElementName = 177,
JSXOpeningElementTypeArguments = 178,
JSXOpeningElementAttributes = 179,
JSXClosingElementName = 180,
JSXFragmentOpeningFragment = 181,
JSXFragmentChildren = 182,
JSXFragmentClosingFragment = 183,
JSXNamespacedNameNamespace = 184,
JSXNamespacedNameName = 185,
JSXMemberExpressionObject = 186,
JSXMemberExpressionProperty = 187,
JSXExpressionContainerExpression = 188,
JSXAttributeName = 189,
JSXAttributeValue = 190,
JSXSpreadAttributeArgument = 191,
JSXSpreadChildExpression = 192,
TSThisParameterTypeAnnotation = 193,
TSEnumDeclarationId = 194,
TSEnumDeclarationBody = 195,
TSEnumBodyMembers = 196,
TSEnumMemberId = 197,
TSEnumMemberInitializer = 198,
TSTypeAnnotationTypeAnnotation = 199,
TSLiteralTypeLiteral = 200,
TSConditionalTypeCheckType = 201,
TSConditionalTypeExtendsType = 202,
TSConditionalTypeTrueType = 203,
TSConditionalTypeFalseType = 204,
TSUnionTypeTypes = 205,
TSIntersectionTypeTypes = 206,
TSParenthesizedTypeTypeAnnotation = 207,
TSTypeOperatorTypeAnnotation = 208,
TSArrayTypeElementType = 209,
TSIndexedAccessTypeObjectType = 210,
TSIndexedAccessTypeIndexType = 211,
TSTupleTypeElementTypes = 212,
TSNamedTupleMemberLabel = 213,
TSNamedTupleMemberElementType = 214,
TSOptionalTypeTypeAnnotation = 215,
TSRestTypeTypeAnnotation = 216,
TSTypeReferenceTypeName = 217,
TSTypeReferenceTypeArguments = 218,
TSQualifiedNameLeft = 219,
TSQualifiedNameRight = 220,
TSTypeParameterInstantiationParams = 221,
TSTypeParameterName = 222,
TSTypeParameterConstraint = 223,
TSTypeParameterDefault = 224,
TSTypeParameterDeclarationParams = 225,
TSTypeAliasDeclarationId = 226,
TSTypeAliasDeclarationTypeParameters = 227,
TSTypeAliasDeclarationTypeAnnotation = 228,
TSClassImplementsExpression = 229,
TSClassImplementsTypeArguments = 230,
TSInterfaceDeclarationId = 231,
TSInterfaceDeclarationTypeParameters = 232,
TSInterfaceDeclarationExtends = 233,
TSInterfaceDeclarationBody = 234,
TSInterfaceBodyBody = 235,
TSPropertySignatureKey = 236,
TSPropertySignatureTypeAnnotation = 237,
TSIndexSignatureParameter = 238,
TSIndexSignatureTypeAnnotation = 239,
TSCallSignatureDeclarationTypeParameters = 240,
TSCallSignatureDeclarationThisParam = 241,
TSCallSignatureDeclarationParams = 242,
TSCallSignatureDeclarationReturnType = 243,
TSMethodSignatureKey = 244,
TSMethodSignatureTypeParameters = 245,
TSMethodSignatureThisParam = 246,
TSMethodSignatureParams = 247,
TSMethodSignatureReturnType = 248,
TSConstructSignatureDeclarationTypeParameters = 249,
TSConstructSignatureDeclarationParams = 250,
TSConstructSignatureDeclarationReturnType = 251,
TSIndexSignatureNameTypeAnnotation = 252,
TSInterfaceHeritageTypeName = 253,
TSInterfaceHeritageTypeArguments = 254,
TSTypePredicateParameterName = 255,
TSTypePredicateTypeAnnotation = 256,
TSExternalModuleDeclarationId = 257,
TSExternalModuleDeclarationBody = 258,
TSNamespaceDeclarationId = 259,
TSNamespaceDeclarationBody = 260,
TSGlobalDeclarationBody = 261,
TSModuleBlockDirectives = 262,
TSModuleBlockBody = 263,
TSTypeLiteralMembers = 264,
TSInferTypeTypeParameter = 265,
TSTypeQueryExprName = 266,
TSTypeQueryTypeArguments = 267,
TSImportTypeSource = 268,
TSImportTypeOptions = 269,
TSImportTypeQualifier = 270,
TSImportTypeTypeArguments = 271,
TSImportTypeQualifiedNameLeft = 272,
TSImportTypeQualifiedNameRight = 273,
TSFunctionTypeTypeParameters = 274,
TSFunctionTypeThisParam = 275,
TSFunctionTypeParams = 276,
TSFunctionTypeReturnType = 277,
TSConstructorTypeTypeParameters = 278,
TSConstructorTypeParams = 279,
TSConstructorTypeReturnType = 280,
TSMappedTypeKey = 281,
TSMappedTypeConstraint = 282,
TSMappedTypeNameType = 283,
TSMappedTypeTypeAnnotation = 284,
TSTemplateLiteralTypeQuasis = 285,
TSTemplateLiteralTypeTypes = 286,
TSAsExpressionExpression = 287,
TSAsExpressionTypeAnnotation = 288,
TSSatisfiesExpressionExpression = 289,
TSSatisfiesExpressionTypeAnnotation = 290,
TSTypeAssertionTypeAnnotation = 291,
TSTypeAssertionExpression = 292,
TSImportEqualsDeclarationId = 293,
TSImportEqualsDeclarationModuleReference = 294,
TSExternalModuleReferenceExpression = 295,
TSNonNullExpressionExpression = 296,
DecoratorExpression = 297,
TSExportAssignmentExpression = 298,
TSNamespaceExportDeclarationId = 299,
TSInstantiationExpressionExpression = 300,
TSInstantiationExpressionTypeArguments = 301,
JSDocNullableTypeTypeAnnotation = 302,
JSDocNonNullableTypeTypeAnnotation = 303,
}
/// Ancestor type used in AST traversal.
@@ -578,11 +579,13 @@ pub enum Ancestor<'a, 't> {
ClassId(ClassWithoutId<'a, 't>) = AncestorType::ClassId as u16,
ClassTypeParameters(ClassWithoutTypeParameters<'a, 't>) =
AncestorType::ClassTypeParameters as u16,
ClassSuperClass(ClassWithoutSuperClass<'a, 't>) = AncestorType::ClassSuperClass as u16,
ClassSuperTypeArguments(ClassWithoutSuperTypeArguments<'a, 't>) =
AncestorType::ClassSuperTypeArguments as u16,
ClassHeritage(ClassWithoutHeritage<'a, 't>) = AncestorType::ClassHeritage as u16,
ClassImplements(ClassWithoutImplements<'a, 't>) = AncestorType::ClassImplements as u16,
ClassBody(ClassWithoutBody<'a, 't>) = AncestorType::ClassBody as u16,
ClassHeritageExpression(ClassHeritageWithoutExpression<'a, 't>) =
AncestorType::ClassHeritageExpression as u16,
ClassHeritageTypeArguments(ClassHeritageWithoutTypeArguments<'a, 't>) =
AncestorType::ClassHeritageTypeArguments as u16,
ClassBodyBody(ClassBodyWithoutBody<'a, 't>) = AncestorType::ClassBodyBody as u16,
MethodDefinitionDecorators(MethodDefinitionWithoutDecorators<'a, 't>) =
AncestorType::MethodDefinitionDecorators as u16,
@@ -1332,13 +1335,17 @@ impl<'a, 't> Ancestor<'a, 't> {
Self::ClassDecorators(_)
| Self::ClassId(_)
| Self::ClassTypeParameters(_)
| Self::ClassSuperClass(_)
| Self::ClassSuperTypeArguments(_)
| Self::ClassHeritage(_)
| Self::ClassImplements(_)
| Self::ClassBody(_)
)
}
#[inline]
pub fn is_class_heritage(self) -> bool {
matches!(self, Self::ClassHeritageExpression(_) | Self::ClassHeritageTypeArguments(_))
}
#[inline]
pub fn is_class_body(self) -> bool {
matches!(self, Self::ClassBodyBody(_))
@@ -2011,7 +2018,7 @@ impl<'a, 't> Ancestor<'a, 't> {
| Self::AssignmentPatternRight(_)
| Self::FormalParameterInitializer(_)
| Self::YieldExpressionArgument(_)
| Self::ClassSuperClass(_)
| Self::ClassHeritageExpression(_)
| Self::PropertyDefinitionValue(_)
| Self::AccessorPropertyValue(_)
| Self::ImportExpressionSource(_)
@@ -2401,10 +2408,11 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> {
Self::ClassDecorators(a) => a.address(),
Self::ClassId(a) => a.address(),
Self::ClassTypeParameters(a) => a.address(),
Self::ClassSuperClass(a) => a.address(),
Self::ClassSuperTypeArguments(a) => a.address(),
Self::ClassHeritage(a) => a.address(),
Self::ClassImplements(a) => a.address(),
Self::ClassBody(a) => a.address(),
Self::ClassHeritageExpression(a) => a.address(),
Self::ClassHeritageTypeArguments(a) => a.address(),
Self::ClassBodyBody(a) => a.address(),
Self::MethodDefinitionDecorators(a) => a.address(),
Self::MethodDefinitionKey(a) => a.address(),
@@ -9042,8 +9050,7 @@ pub(crate) const OFFSET_CLASS_TYPE: usize = offset_of!(Class, r#type);
pub(crate) const OFFSET_CLASS_DECORATORS: usize = offset_of!(Class, decorators);
pub(crate) const OFFSET_CLASS_ID: usize = offset_of!(Class, id);
pub(crate) const OFFSET_CLASS_TYPE_PARAMETERS: usize = offset_of!(Class, type_parameters);
pub(crate) const OFFSET_CLASS_SUPER_CLASS: usize = offset_of!(Class, super_class);
pub(crate) const OFFSET_CLASS_SUPER_TYPE_ARGUMENTS: usize = offset_of!(Class, super_type_arguments);
pub(crate) const OFFSET_CLASS_HERITAGE: usize = offset_of!(Class, heritage);
pub(crate) const OFFSET_CLASS_IMPLEMENTS: usize = offset_of!(Class, implements);
pub(crate) const OFFSET_CLASS_BODY: usize = offset_of!(Class, body);
pub(crate) const OFFSET_CLASS_ABSTRACT: usize = offset_of!(Class, r#abstract);
@@ -9089,19 +9096,9 @@ impl<'a, 't> ClassWithoutDecorators<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9182,19 +9179,9 @@ impl<'a, 't> ClassWithoutId<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9277,19 +9264,9 @@ impl<'a, 't> ClassWithoutTypeParameters<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9335,12 +9312,12 @@ impl<'a, 't> GetAddress for ClassWithoutTypeParameters<'a, 't> {
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassWithoutSuperClass<'a, 't>(
pub struct ClassWithoutHeritage<'a, 't>(
pub(crate) *const Class<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
impl<'a, 't> ClassWithoutHeritage<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_NODE_ID) as *const Cell<NodeId>) }
@@ -9379,16 +9356,6 @@ impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
}
}
#[inline]
pub fn implements(self) -> &'t ArenaVec<'a, TSClassImplements<'a>> {
unsafe {
@@ -9422,100 +9389,7 @@ impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
}
}
impl<'a, 't> GetAddress for ClassWithoutSuperClass<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassWithoutSuperTypeArguments<'a, 't>(
pub(crate) *const Class<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassWithoutSuperTypeArguments<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_NODE_ID) as *const Cell<NodeId>) }
}
#[inline]
pub fn span(self) -> &'t Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_SPAN) as *const Span) }
}
#[inline]
pub fn r#type(self) -> &'t ClassType {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_TYPE) as *const ClassType) }
}
#[inline]
pub fn decorators(self) -> &'t ArenaVec<'a, Decorator<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_DECORATORS)
as *const ArenaVec<'a, Decorator<'a>>)
}
}
#[inline]
pub fn id(self) -> &'t Option<BindingIdentifier<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_ID) as *const Option<BindingIdentifier<'a>>)
}
}
#[inline]
pub fn type_parameters(self) -> &'t Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_TYPE_PARAMETERS)
as *const Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>)
}
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn implements(self) -> &'t ArenaVec<'a, TSClassImplements<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_IMPLEMENTS)
as *const ArenaVec<'a, TSClassImplements<'a>>)
}
}
#[inline]
pub fn body(self) -> &'t ArenaBox<'a, ClassBody<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_BODY) as *const ArenaBox<'a, ClassBody<'a>>)
}
}
#[inline]
pub fn r#abstract(self) -> &'t bool {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) }
}
#[inline]
pub fn declare(self) -> &'t bool {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) }
}
#[inline]
pub fn scope_id(self) -> &'t Cell<Option<ScopeId>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SCOPE_ID) as *const Cell<Option<ScopeId>>)
}
}
}
impl<'a, 't> GetAddress for ClassWithoutSuperTypeArguments<'a, 't> {
impl<'a, 't> GetAddress for ClassWithoutHeritage<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
@@ -9569,19 +9443,9 @@ impl<'a, 't> ClassWithoutImplements<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9661,19 +9525,9 @@ impl<'a, 't> ClassWithoutBody<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9710,6 +9564,57 @@ impl<'a, 't> GetAddress for ClassWithoutBody<'a, 't> {
}
}
pub(crate) const OFFSET_CLASS_HERITAGE_EXPRESSION: usize = offset_of!(ClassHeritage, expression);
pub(crate) const OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS: usize =
offset_of!(ClassHeritage, type_arguments);
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassHeritageWithoutExpression<'a, 't>(
pub(crate) *const ClassHeritage<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassHeritageWithoutExpression<'a, 't> {
#[inline]
pub fn type_arguments(self) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
}
}
}
impl<'a, 't> GetAddress for ClassHeritageWithoutExpression<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassHeritageWithoutTypeArguments<'a, 't>(
pub(crate) *const ClassHeritage<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassHeritageWithoutTypeArguments<'a, 't> {
#[inline]
pub fn expression(self) -> &'t Expression<'a> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE_EXPRESSION) as *const Expression<'a>)
}
}
}
impl<'a, 't> GetAddress for ClassHeritageWithoutTypeArguments<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
pub(crate) const OFFSET_CLASS_BODY_NODE_ID: usize = offset_of!(ClassBody, node_id);
pub(crate) const OFFSET_CLASS_BODY_SPAN: usize = offset_of!(ClassBody, span);
pub(crate) const OFFSET_CLASS_BODY_BODY: usize = offset_of!(ClassBody, body);
@@ -993,6 +993,11 @@ pub trait Traverse<'a> {
#[inline]
fn exit_class(&mut self, node: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {}
#[inline]
fn enter_class_heritage(&mut self, node: &mut ClassHeritage<'a>, ctx: &mut TraverseCtx<'a>) {}
#[inline]
fn exit_class_heritage(&mut self, node: &mut ClassHeritage<'a>, ctx: &mut TraverseCtx<'a>) {}
#[inline]
fn enter_class_body(&mut self, node: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a>) {}
#[inline]
+28 -9
View File
@@ -2607,16 +2607,10 @@ unsafe fn walk_class<'a, Tr: Traverse<'a>>(
walk_ts_type_parameter_declaration(traverser, (&mut **field) as *mut _, ctx);
}
if let Some(field) =
&mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_SUPER_CLASS) as *mut Option<Expression>)
&mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_HERITAGE) as *mut Option<ClassHeritage>)
{
ctx.retag_stack(AncestorType::ClassSuperClass);
walk_expression(traverser, field as *mut _, ctx);
}
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *mut Option<ArenaBox<TSTypeParameterInstantiation>>)
{
ctx.retag_stack(AncestorType::ClassSuperTypeArguments);
walk_ts_type_parameter_instantiation(traverser, (&mut **field) as *mut _, ctx);
ctx.retag_stack(AncestorType::ClassHeritage);
walk_class_heritage(traverser, field as *mut _, ctx);
}
ctx.retag_stack(AncestorType::ClassImplements);
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_IMPLEMENTS)
@@ -2636,6 +2630,31 @@ unsafe fn walk_class<'a, Tr: Traverse<'a>>(
traverser.exit_class(&mut *node, ctx);
}
unsafe fn walk_class_heritage<'a, Tr: Traverse<'a>>(
traverser: &mut Tr,
node: *mut ClassHeritage<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_class_heritage(&mut *node, ctx);
let pop_token = ctx.push_stack(Ancestor::ClassHeritageExpression(
ancestor::ClassHeritageWithoutExpression(node, PhantomData),
));
walk_expression(
traverser,
(node as *mut u8).add(ancestor::OFFSET_CLASS_HERITAGE_EXPRESSION) as *mut Expression,
ctx,
);
if let Some(field) = &mut *((node as *mut u8)
.add(ancestor::OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS)
as *mut Option<ArenaBox<TSTypeParameterInstantiation>>)
{
ctx.retag_stack(AncestorType::ClassHeritageTypeArguments);
walk_ts_type_parameter_instantiation(traverser, (&mut **field) as *mut _, ctx);
}
ctx.pop_stack(pop_token);
traverser.exit_class_heritage(&mut *node, ctx);
}
unsafe fn walk_class_body<'a, Tr: Traverse<'a>>(
traverser: &mut Tr,
node: *mut ClassBody<'a>,
+1 -1
View File
@@ -187,7 +187,7 @@ impl<'a> PeepholeOptimizations {
// Classes with `extends` may inherit static setters from the parent.
// We can't statically determine the parent's static setters,
// so conservatively mark as non-fresh.
if class.super_class.is_some() {
if class.heritage.is_some() {
return true;
}
// Class-level decorators run arbitrary code during class creation and can
@@ -78,7 +78,7 @@ impl<'a> PeepholeOptimizations {
found_constructor_method = true;
}
Ancestor::ClassBody(class) if found_constructor_method => {
return class.super_class().is_some().then_some(scope_id);
return class.heritage().is_some().then_some(scope_id);
}
_ => {}
}
@@ -1035,10 +1035,10 @@ impl<'a> PeepholeOptimizations {
// when an `Extracts` class is actually removed.
let mut exprs = ArenaVec::new_in(ctx);
if let Some(e) = &mut c.super_class
&& e.may_have_side_effects(ctx)
if c.heritage_expression()
.is_some_and(|expression| expression.may_have_side_effects(ctx))
{
exprs.push(c.super_class.take().unwrap());
exprs.push(c.heritage.take().unwrap().expression);
}
for e in &mut c.body.body {
@@ -1092,7 +1092,7 @@ impl<'a> PeepholeOptimizations {
if !c.decorators.is_empty() {
return ClassRemovability::Keep;
}
if let Some(super_class) = &c.super_class {
if let Some(super_class) = c.heritage_expression() {
// Unwrap parens and sequence tails — `(0, x)` — so the
// classification does not change when a later fold surfaces
// the inner expression.
@@ -1142,7 +1142,7 @@ impl<'a> PeepholeOptimizations {
extracts = true;
}
}
if c.super_class.as_ref().is_some_and(|e| e.may_have_side_effects(ctx)) {
if c.heritage_expression().is_some_and(|e| e.may_have_side_effects(ctx)) {
extracts = true;
}
if extracts { ClassRemovability::Extracts } else { ClassRemovability::RemovesClean }
+3 -6
View File
@@ -92,14 +92,12 @@ impl<'a, C: Config> ParserImpl<'a, C> {
let type_parameters =
if self.is_ts { self.parse_ts_type_parameters_with_variance() } else { None };
let (extends, implements) = self.parse_class_heritage_clause();
let mut super_class = None;
let mut super_type_parameters = None;
let mut heritage = None;
if let Some(mut extends) = extends
&& !extends.is_empty()
{
let (expression, type_arguments) = extends.remove(0);
super_class = Some(expression);
super_type_parameters = type_arguments;
heritage = Some(ClassHeritage::new(expression, type_arguments, self));
for (expression, type_arguments) in extends {
let expression_span = expression.span();
let span = type_arguments.map_or(expression_span, |type_arguments| {
@@ -123,8 +121,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
decorators,
id,
type_parameters,
super_class,
super_type_parameters,
heritage,
implements.map_or_else(|| ArenaVec::new_in(self), |(_, implements)| implements),
body,
modifiers.contains_abstract(),
@@ -165,7 +165,7 @@ impl<'a> Visit<'a> for IdentifierLocVisitor {
if let Some(type_parameters) = &it.type_parameters {
self.visit_ts_type_parameter_declaration(type_parameters);
}
if let Some(super_type_arguments) = &it.super_type_arguments {
if let Some(super_type_arguments) = it.heritage_type_arguments() {
self.visit_ts_type_parameter_instantiation(super_type_arguments);
}
self.type_depth += 1;
+5 -5
View File
@@ -976,15 +976,15 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
if let Some(type_parameters) = &class.type_parameters {
self.visit_ts_type_parameter_declaration(type_parameters);
}
if let Some(super_class) = &class.super_class {
if let Some(heritage) = &class.heritage {
if self.in_ambient_context() {
self.current_reference_flags = ReferenceFlags::ValueAsType;
}
self.visit_expression(super_class);
self.visit_expression(&heritage.expression);
self.current_reference_flags = ReferenceFlags::empty();
}
if let Some(super_type_parameters) = &class.super_type_arguments {
self.visit_ts_type_parameter_instantiation(super_type_parameters);
if let Some(super_type_parameters) = &heritage.type_arguments {
self.visit_ts_type_parameter_instantiation(super_type_parameters);
}
}
self.visit_ts_class_implements_list(&class.implements);
self.visit_class_body(&class.body);
@@ -1204,7 +1204,7 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
let class_node_id = ctx.class_table_builder.classes.get_node_id(class_id);
let class =
ctx.ancestry().find_kind_by_node_id(class_node_id).as_class().unwrap();
if class.super_class.is_none() {
if class.heritage.is_none() {
ctx.error(diagnostics::super_without_derived_class(
sup.span, class.span,
));
@@ -1303,8 +1303,8 @@ impl<'a> VisitJsMut<'a> for ConstructorBodyThisAfterSuperInserter<'a, '_> {
// `class Inner extends super() {}`
// ^^^^^^^
if let Some(super_class) = &mut class.super_class {
self.visit_expression(super_class);
if let Some(heritage) = &mut class.heritage {
self.visit_expression(&mut heritage.expression);
}
for element in &mut class.body.body {
@@ -72,7 +72,7 @@ impl<'a> ClassProperties<'a> {
let is_declaration = *class.r#type() == ClassType::ClassDeclaration;
let mut class_name_binding = class.id().as_ref().map(BoundIdentifier::from_binding_ident);
let class_scope_id = class.scope_id().get().unwrap();
let has_super_class = class.super_class().is_some();
let has_super_class = class.heritage().is_some();
// Check if class has any properties, private methods, or static blocks
let mut instance_prop_count = 0;
+1 -1
View File
@@ -70,7 +70,7 @@ impl<'a> JsxSelf {
fn has_no_super_class(ctx: &TraverseCtx<'a>) -> bool {
for ancestor in ctx.ancestors() {
if let Ancestor::ClassBody(class) = ancestor {
return class.super_class().is_none();
return class.heritage().is_none();
}
}
true
@@ -232,7 +232,9 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
// Remove TypeScript annotations from class declarations
// Note: declare flag is preserved for exit_statements to handle declaration removal
class.type_parameters = None;
class.super_type_arguments = None;
if let Some(heritage) = &mut class.heritage {
heritage.type_arguments = None;
}
class.implements.clear();
class.r#abstract = false;
@@ -225,7 +225,7 @@ impl<'a> TypeScript<'a> {
);
let ctor = create_class_constructor(
property_assignments,
class.super_class.is_some(),
class.heritage.is_some(),
scope_id,
ctx,
);
+253 -348
View File
@@ -152,178 +152,179 @@ pub(crate) enum AncestorType {
ClassDecorators = 128,
ClassId = 129,
ClassTypeParameters = 130,
ClassSuperClass = 131,
ClassSuperTypeArguments = 132,
ClassImplements = 133,
ClassBody = 134,
ClassBodyBody = 135,
MethodDefinitionDecorators = 136,
MethodDefinitionKey = 137,
MethodDefinitionValue = 138,
PropertyDefinitionDecorators = 139,
PropertyDefinitionKey = 140,
PropertyDefinitionTypeAnnotation = 141,
PropertyDefinitionValue = 142,
StaticBlockBody = 143,
AccessorPropertyDecorators = 144,
AccessorPropertyKey = 145,
AccessorPropertyTypeAnnotation = 146,
AccessorPropertyValue = 147,
ImportExpressionSource = 148,
ImportExpressionOptions = 149,
ImportDeclarationSpecifiers = 150,
ImportDeclarationSource = 151,
ImportDeclarationWithClause = 152,
ImportSpecifierImported = 153,
ImportSpecifierLocal = 154,
ImportDefaultSpecifierLocal = 155,
ImportNamespaceSpecifierLocal = 156,
WithClauseWithEntries = 157,
ImportAttributeKey = 158,
ImportAttributeValue = 159,
ExportDeclarationDeclaration = 160,
ExportNamedDeclarationSpecifiers = 161,
ExportFromDeclarationSpecifiers = 162,
ExportFromDeclarationSource = 163,
ExportFromDeclarationWithClause = 164,
ExportDefaultDeclarationDeclaration = 165,
ExportAllDeclarationExported = 166,
ExportAllDeclarationSource = 167,
ExportAllDeclarationWithClause = 168,
ExportSpecifierLocal = 169,
ExportSpecifierExported = 170,
V8IntrinsicExpressionName = 171,
V8IntrinsicExpressionArguments = 172,
JSXElementOpeningElement = 173,
JSXElementChildren = 174,
JSXElementClosingElement = 175,
JSXOpeningElementName = 176,
JSXOpeningElementTypeArguments = 177,
JSXOpeningElementAttributes = 178,
JSXClosingElementName = 179,
JSXFragmentOpeningFragment = 180,
JSXFragmentChildren = 181,
JSXFragmentClosingFragment = 182,
JSXNamespacedNameNamespace = 183,
JSXNamespacedNameName = 184,
JSXMemberExpressionObject = 185,
JSXMemberExpressionProperty = 186,
JSXExpressionContainerExpression = 187,
JSXAttributeName = 188,
JSXAttributeValue = 189,
JSXSpreadAttributeArgument = 190,
JSXSpreadChildExpression = 191,
TSThisParameterTypeAnnotation = 192,
TSEnumDeclarationId = 193,
TSEnumDeclarationBody = 194,
TSEnumBodyMembers = 195,
TSEnumMemberId = 196,
TSEnumMemberInitializer = 197,
TSTypeAnnotationTypeAnnotation = 198,
TSLiteralTypeLiteral = 199,
TSConditionalTypeCheckType = 200,
TSConditionalTypeExtendsType = 201,
TSConditionalTypeTrueType = 202,
TSConditionalTypeFalseType = 203,
TSUnionTypeTypes = 204,
TSIntersectionTypeTypes = 205,
TSParenthesizedTypeTypeAnnotation = 206,
TSTypeOperatorTypeAnnotation = 207,
TSArrayTypeElementType = 208,
TSIndexedAccessTypeObjectType = 209,
TSIndexedAccessTypeIndexType = 210,
TSTupleTypeElementTypes = 211,
TSNamedTupleMemberLabel = 212,
TSNamedTupleMemberElementType = 213,
TSOptionalTypeTypeAnnotation = 214,
TSRestTypeTypeAnnotation = 215,
TSTypeReferenceTypeName = 216,
TSTypeReferenceTypeArguments = 217,
TSQualifiedNameLeft = 218,
TSQualifiedNameRight = 219,
TSTypeParameterInstantiationParams = 220,
TSTypeParameterName = 221,
TSTypeParameterConstraint = 222,
TSTypeParameterDefault = 223,
TSTypeParameterDeclarationParams = 224,
TSTypeAliasDeclarationId = 225,
TSTypeAliasDeclarationTypeParameters = 226,
TSTypeAliasDeclarationTypeAnnotation = 227,
TSClassImplementsExpression = 228,
TSClassImplementsTypeArguments = 229,
TSInterfaceDeclarationId = 230,
TSInterfaceDeclarationTypeParameters = 231,
TSInterfaceDeclarationExtends = 232,
TSInterfaceDeclarationBody = 233,
TSInterfaceBodyBody = 234,
TSPropertySignatureKey = 235,
TSPropertySignatureTypeAnnotation = 236,
TSIndexSignatureParameter = 237,
TSIndexSignatureTypeAnnotation = 238,
TSCallSignatureDeclarationTypeParameters = 239,
TSCallSignatureDeclarationThisParam = 240,
TSCallSignatureDeclarationParams = 241,
TSCallSignatureDeclarationReturnType = 242,
TSMethodSignatureKey = 243,
TSMethodSignatureTypeParameters = 244,
TSMethodSignatureThisParam = 245,
TSMethodSignatureParams = 246,
TSMethodSignatureReturnType = 247,
TSConstructSignatureDeclarationTypeParameters = 248,
TSConstructSignatureDeclarationParams = 249,
TSConstructSignatureDeclarationReturnType = 250,
TSIndexSignatureNameTypeAnnotation = 251,
TSInterfaceHeritageTypeName = 252,
TSInterfaceHeritageTypeArguments = 253,
TSTypePredicateParameterName = 254,
TSTypePredicateTypeAnnotation = 255,
TSExternalModuleDeclarationId = 256,
TSExternalModuleDeclarationBody = 257,
TSNamespaceDeclarationId = 258,
TSNamespaceDeclarationBody = 259,
TSGlobalDeclarationBody = 260,
TSModuleBlockDirectives = 261,
TSModuleBlockBody = 262,
TSTypeLiteralMembers = 263,
TSInferTypeTypeParameter = 264,
TSTypeQueryExprName = 265,
TSTypeQueryTypeArguments = 266,
TSImportTypeSource = 267,
TSImportTypeOptions = 268,
TSImportTypeQualifier = 269,
TSImportTypeTypeArguments = 270,
TSImportTypeQualifiedNameLeft = 271,
TSImportTypeQualifiedNameRight = 272,
TSFunctionTypeTypeParameters = 273,
TSFunctionTypeThisParam = 274,
TSFunctionTypeParams = 275,
TSFunctionTypeReturnType = 276,
TSConstructorTypeTypeParameters = 277,
TSConstructorTypeParams = 278,
TSConstructorTypeReturnType = 279,
TSMappedTypeKey = 280,
TSMappedTypeConstraint = 281,
TSMappedTypeNameType = 282,
TSMappedTypeTypeAnnotation = 283,
TSTemplateLiteralTypeQuasis = 284,
TSTemplateLiteralTypeTypes = 285,
TSAsExpressionExpression = 286,
TSAsExpressionTypeAnnotation = 287,
TSSatisfiesExpressionExpression = 288,
TSSatisfiesExpressionTypeAnnotation = 289,
TSTypeAssertionTypeAnnotation = 290,
TSTypeAssertionExpression = 291,
TSImportEqualsDeclarationId = 292,
TSImportEqualsDeclarationModuleReference = 293,
TSExternalModuleReferenceExpression = 294,
TSNonNullExpressionExpression = 295,
DecoratorExpression = 296,
TSExportAssignmentExpression = 297,
TSNamespaceExportDeclarationId = 298,
TSInstantiationExpressionExpression = 299,
TSInstantiationExpressionTypeArguments = 300,
JSDocNullableTypeTypeAnnotation = 301,
JSDocNonNullableTypeTypeAnnotation = 302,
ClassHeritage = 131,
ClassImplements = 132,
ClassBody = 133,
ClassHeritageExpression = 134,
ClassHeritageTypeArguments = 135,
ClassBodyBody = 136,
MethodDefinitionDecorators = 137,
MethodDefinitionKey = 138,
MethodDefinitionValue = 139,
PropertyDefinitionDecorators = 140,
PropertyDefinitionKey = 141,
PropertyDefinitionTypeAnnotation = 142,
PropertyDefinitionValue = 143,
StaticBlockBody = 144,
AccessorPropertyDecorators = 145,
AccessorPropertyKey = 146,
AccessorPropertyTypeAnnotation = 147,
AccessorPropertyValue = 148,
ImportExpressionSource = 149,
ImportExpressionOptions = 150,
ImportDeclarationSpecifiers = 151,
ImportDeclarationSource = 152,
ImportDeclarationWithClause = 153,
ImportSpecifierImported = 154,
ImportSpecifierLocal = 155,
ImportDefaultSpecifierLocal = 156,
ImportNamespaceSpecifierLocal = 157,
WithClauseWithEntries = 158,
ImportAttributeKey = 159,
ImportAttributeValue = 160,
ExportDeclarationDeclaration = 161,
ExportNamedDeclarationSpecifiers = 162,
ExportFromDeclarationSpecifiers = 163,
ExportFromDeclarationSource = 164,
ExportFromDeclarationWithClause = 165,
ExportDefaultDeclarationDeclaration = 166,
ExportAllDeclarationExported = 167,
ExportAllDeclarationSource = 168,
ExportAllDeclarationWithClause = 169,
ExportSpecifierLocal = 170,
ExportSpecifierExported = 171,
V8IntrinsicExpressionName = 172,
V8IntrinsicExpressionArguments = 173,
JSXElementOpeningElement = 174,
JSXElementChildren = 175,
JSXElementClosingElement = 176,
JSXOpeningElementName = 177,
JSXOpeningElementTypeArguments = 178,
JSXOpeningElementAttributes = 179,
JSXClosingElementName = 180,
JSXFragmentOpeningFragment = 181,
JSXFragmentChildren = 182,
JSXFragmentClosingFragment = 183,
JSXNamespacedNameNamespace = 184,
JSXNamespacedNameName = 185,
JSXMemberExpressionObject = 186,
JSXMemberExpressionProperty = 187,
JSXExpressionContainerExpression = 188,
JSXAttributeName = 189,
JSXAttributeValue = 190,
JSXSpreadAttributeArgument = 191,
JSXSpreadChildExpression = 192,
TSThisParameterTypeAnnotation = 193,
TSEnumDeclarationId = 194,
TSEnumDeclarationBody = 195,
TSEnumBodyMembers = 196,
TSEnumMemberId = 197,
TSEnumMemberInitializer = 198,
TSTypeAnnotationTypeAnnotation = 199,
TSLiteralTypeLiteral = 200,
TSConditionalTypeCheckType = 201,
TSConditionalTypeExtendsType = 202,
TSConditionalTypeTrueType = 203,
TSConditionalTypeFalseType = 204,
TSUnionTypeTypes = 205,
TSIntersectionTypeTypes = 206,
TSParenthesizedTypeTypeAnnotation = 207,
TSTypeOperatorTypeAnnotation = 208,
TSArrayTypeElementType = 209,
TSIndexedAccessTypeObjectType = 210,
TSIndexedAccessTypeIndexType = 211,
TSTupleTypeElementTypes = 212,
TSNamedTupleMemberLabel = 213,
TSNamedTupleMemberElementType = 214,
TSOptionalTypeTypeAnnotation = 215,
TSRestTypeTypeAnnotation = 216,
TSTypeReferenceTypeName = 217,
TSTypeReferenceTypeArguments = 218,
TSQualifiedNameLeft = 219,
TSQualifiedNameRight = 220,
TSTypeParameterInstantiationParams = 221,
TSTypeParameterName = 222,
TSTypeParameterConstraint = 223,
TSTypeParameterDefault = 224,
TSTypeParameterDeclarationParams = 225,
TSTypeAliasDeclarationId = 226,
TSTypeAliasDeclarationTypeParameters = 227,
TSTypeAliasDeclarationTypeAnnotation = 228,
TSClassImplementsExpression = 229,
TSClassImplementsTypeArguments = 230,
TSInterfaceDeclarationId = 231,
TSInterfaceDeclarationTypeParameters = 232,
TSInterfaceDeclarationExtends = 233,
TSInterfaceDeclarationBody = 234,
TSInterfaceBodyBody = 235,
TSPropertySignatureKey = 236,
TSPropertySignatureTypeAnnotation = 237,
TSIndexSignatureParameter = 238,
TSIndexSignatureTypeAnnotation = 239,
TSCallSignatureDeclarationTypeParameters = 240,
TSCallSignatureDeclarationThisParam = 241,
TSCallSignatureDeclarationParams = 242,
TSCallSignatureDeclarationReturnType = 243,
TSMethodSignatureKey = 244,
TSMethodSignatureTypeParameters = 245,
TSMethodSignatureThisParam = 246,
TSMethodSignatureParams = 247,
TSMethodSignatureReturnType = 248,
TSConstructSignatureDeclarationTypeParameters = 249,
TSConstructSignatureDeclarationParams = 250,
TSConstructSignatureDeclarationReturnType = 251,
TSIndexSignatureNameTypeAnnotation = 252,
TSInterfaceHeritageTypeName = 253,
TSInterfaceHeritageTypeArguments = 254,
TSTypePredicateParameterName = 255,
TSTypePredicateTypeAnnotation = 256,
TSExternalModuleDeclarationId = 257,
TSExternalModuleDeclarationBody = 258,
TSNamespaceDeclarationId = 259,
TSNamespaceDeclarationBody = 260,
TSGlobalDeclarationBody = 261,
TSModuleBlockDirectives = 262,
TSModuleBlockBody = 263,
TSTypeLiteralMembers = 264,
TSInferTypeTypeParameter = 265,
TSTypeQueryExprName = 266,
TSTypeQueryTypeArguments = 267,
TSImportTypeSource = 268,
TSImportTypeOptions = 269,
TSImportTypeQualifier = 270,
TSImportTypeTypeArguments = 271,
TSImportTypeQualifiedNameLeft = 272,
TSImportTypeQualifiedNameRight = 273,
TSFunctionTypeTypeParameters = 274,
TSFunctionTypeThisParam = 275,
TSFunctionTypeParams = 276,
TSFunctionTypeReturnType = 277,
TSConstructorTypeTypeParameters = 278,
TSConstructorTypeParams = 279,
TSConstructorTypeReturnType = 280,
TSMappedTypeKey = 281,
TSMappedTypeConstraint = 282,
TSMappedTypeNameType = 283,
TSMappedTypeTypeAnnotation = 284,
TSTemplateLiteralTypeQuasis = 285,
TSTemplateLiteralTypeTypes = 286,
TSAsExpressionExpression = 287,
TSAsExpressionTypeAnnotation = 288,
TSSatisfiesExpressionExpression = 289,
TSSatisfiesExpressionTypeAnnotation = 290,
TSTypeAssertionTypeAnnotation = 291,
TSTypeAssertionExpression = 292,
TSImportEqualsDeclarationId = 293,
TSImportEqualsDeclarationModuleReference = 294,
TSExternalModuleReferenceExpression = 295,
TSNonNullExpressionExpression = 296,
DecoratorExpression = 297,
TSExportAssignmentExpression = 298,
TSNamespaceExportDeclarationId = 299,
TSInstantiationExpressionExpression = 300,
TSInstantiationExpressionTypeArguments = 301,
JSDocNullableTypeTypeAnnotation = 302,
JSDocNonNullableTypeTypeAnnotation = 303,
}
/// Ancestor type used in AST traversal.
@@ -578,11 +579,13 @@ pub enum Ancestor<'a, 't> {
ClassId(ClassWithoutId<'a, 't>) = AncestorType::ClassId as u16,
ClassTypeParameters(ClassWithoutTypeParameters<'a, 't>) =
AncestorType::ClassTypeParameters as u16,
ClassSuperClass(ClassWithoutSuperClass<'a, 't>) = AncestorType::ClassSuperClass as u16,
ClassSuperTypeArguments(ClassWithoutSuperTypeArguments<'a, 't>) =
AncestorType::ClassSuperTypeArguments as u16,
ClassHeritage(ClassWithoutHeritage<'a, 't>) = AncestorType::ClassHeritage as u16,
ClassImplements(ClassWithoutImplements<'a, 't>) = AncestorType::ClassImplements as u16,
ClassBody(ClassWithoutBody<'a, 't>) = AncestorType::ClassBody as u16,
ClassHeritageExpression(ClassHeritageWithoutExpression<'a, 't>) =
AncestorType::ClassHeritageExpression as u16,
ClassHeritageTypeArguments(ClassHeritageWithoutTypeArguments<'a, 't>) =
AncestorType::ClassHeritageTypeArguments as u16,
ClassBodyBody(ClassBodyWithoutBody<'a, 't>) = AncestorType::ClassBodyBody as u16,
MethodDefinitionDecorators(MethodDefinitionWithoutDecorators<'a, 't>) =
AncestorType::MethodDefinitionDecorators as u16,
@@ -1332,13 +1335,17 @@ impl<'a, 't> Ancestor<'a, 't> {
Self::ClassDecorators(_)
| Self::ClassId(_)
| Self::ClassTypeParameters(_)
| Self::ClassSuperClass(_)
| Self::ClassSuperTypeArguments(_)
| Self::ClassHeritage(_)
| Self::ClassImplements(_)
| Self::ClassBody(_)
)
}
#[inline]
pub fn is_class_heritage(self) -> bool {
matches!(self, Self::ClassHeritageExpression(_) | Self::ClassHeritageTypeArguments(_))
}
#[inline]
pub fn is_class_body(self) -> bool {
matches!(self, Self::ClassBodyBody(_))
@@ -2011,7 +2018,7 @@ impl<'a, 't> Ancestor<'a, 't> {
| Self::AssignmentPatternRight(_)
| Self::FormalParameterInitializer(_)
| Self::YieldExpressionArgument(_)
| Self::ClassSuperClass(_)
| Self::ClassHeritageExpression(_)
| Self::PropertyDefinitionValue(_)
| Self::AccessorPropertyValue(_)
| Self::ImportExpressionSource(_)
@@ -2401,10 +2408,11 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> {
Self::ClassDecorators(a) => a.address(),
Self::ClassId(a) => a.address(),
Self::ClassTypeParameters(a) => a.address(),
Self::ClassSuperClass(a) => a.address(),
Self::ClassSuperTypeArguments(a) => a.address(),
Self::ClassHeritage(a) => a.address(),
Self::ClassImplements(a) => a.address(),
Self::ClassBody(a) => a.address(),
Self::ClassHeritageExpression(a) => a.address(),
Self::ClassHeritageTypeArguments(a) => a.address(),
Self::ClassBodyBody(a) => a.address(),
Self::MethodDefinitionDecorators(a) => a.address(),
Self::MethodDefinitionKey(a) => a.address(),
@@ -9042,8 +9050,7 @@ pub(crate) const OFFSET_CLASS_TYPE: usize = offset_of!(Class, r#type);
pub(crate) const OFFSET_CLASS_DECORATORS: usize = offset_of!(Class, decorators);
pub(crate) const OFFSET_CLASS_ID: usize = offset_of!(Class, id);
pub(crate) const OFFSET_CLASS_TYPE_PARAMETERS: usize = offset_of!(Class, type_parameters);
pub(crate) const OFFSET_CLASS_SUPER_CLASS: usize = offset_of!(Class, super_class);
pub(crate) const OFFSET_CLASS_SUPER_TYPE_ARGUMENTS: usize = offset_of!(Class, super_type_arguments);
pub(crate) const OFFSET_CLASS_HERITAGE: usize = offset_of!(Class, heritage);
pub(crate) const OFFSET_CLASS_IMPLEMENTS: usize = offset_of!(Class, implements);
pub(crate) const OFFSET_CLASS_BODY: usize = offset_of!(Class, body);
pub(crate) const OFFSET_CLASS_ABSTRACT: usize = offset_of!(Class, r#abstract);
@@ -9089,19 +9096,9 @@ impl<'a, 't> ClassWithoutDecorators<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9182,19 +9179,9 @@ impl<'a, 't> ClassWithoutId<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9277,19 +9264,9 @@ impl<'a, 't> ClassWithoutTypeParameters<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9335,12 +9312,12 @@ impl<'a, 't> GetAddress for ClassWithoutTypeParameters<'a, 't> {
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassWithoutSuperClass<'a, 't>(
pub struct ClassWithoutHeritage<'a, 't>(
pub(crate) *const Class<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
impl<'a, 't> ClassWithoutHeritage<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_NODE_ID) as *const Cell<NodeId>) }
@@ -9379,16 +9356,6 @@ impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
}
}
#[inline]
pub fn implements(self) -> &'t ArenaVec<'a, TSClassImplements<'a>> {
unsafe {
@@ -9422,100 +9389,7 @@ impl<'a, 't> ClassWithoutSuperClass<'a, 't> {
}
}
impl<'a, 't> GetAddress for ClassWithoutSuperClass<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassWithoutSuperTypeArguments<'a, 't>(
pub(crate) *const Class<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassWithoutSuperTypeArguments<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_NODE_ID) as *const Cell<NodeId>) }
}
#[inline]
pub fn span(self) -> &'t Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_SPAN) as *const Span) }
}
#[inline]
pub fn r#type(self) -> &'t ClassType {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_TYPE) as *const ClassType) }
}
#[inline]
pub fn decorators(self) -> &'t ArenaVec<'a, Decorator<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_DECORATORS)
as *const ArenaVec<'a, Decorator<'a>>)
}
}
#[inline]
pub fn id(self) -> &'t Option<BindingIdentifier<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_ID) as *const Option<BindingIdentifier<'a>>)
}
}
#[inline]
pub fn type_parameters(self) -> &'t Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_TYPE_PARAMETERS)
as *const Option<ArenaBox<'a, TSTypeParameterDeclaration<'a>>>)
}
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn implements(self) -> &'t ArenaVec<'a, TSClassImplements<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_IMPLEMENTS)
as *const ArenaVec<'a, TSClassImplements<'a>>)
}
}
#[inline]
pub fn body(self) -> &'t ArenaBox<'a, ClassBody<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_BODY) as *const ArenaBox<'a, ClassBody<'a>>)
}
}
#[inline]
pub fn r#abstract(self) -> &'t bool {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) }
}
#[inline]
pub fn declare(self) -> &'t bool {
unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) }
}
#[inline]
pub fn scope_id(self) -> &'t Cell<Option<ScopeId>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SCOPE_ID) as *const Cell<Option<ScopeId>>)
}
}
}
impl<'a, 't> GetAddress for ClassWithoutSuperTypeArguments<'a, 't> {
impl<'a, 't> GetAddress for ClassWithoutHeritage<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
@@ -9569,19 +9443,9 @@ impl<'a, 't> ClassWithoutImplements<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9661,19 +9525,9 @@ impl<'a, 't> ClassWithoutBody<'a, 't> {
}
#[inline]
pub fn super_class(self) -> &'t Option<Expression<'a>> {
pub fn heritage(self) -> &'t Option<ClassHeritage<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_CLASS) as *const Option<Expression<'a>>)
}
}
#[inline]
pub fn super_type_arguments(
self,
) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE) as *const Option<ClassHeritage<'a>>)
}
}
@@ -9710,6 +9564,57 @@ impl<'a, 't> GetAddress for ClassWithoutBody<'a, 't> {
}
}
pub(crate) const OFFSET_CLASS_HERITAGE_EXPRESSION: usize = offset_of!(ClassHeritage, expression);
pub(crate) const OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS: usize =
offset_of!(ClassHeritage, type_arguments);
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassHeritageWithoutExpression<'a, 't>(
pub(crate) *const ClassHeritage<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassHeritageWithoutExpression<'a, 't> {
#[inline]
pub fn type_arguments(self) -> &'t Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS)
as *const Option<ArenaBox<'a, TSTypeParameterInstantiation<'a>>>)
}
}
}
impl<'a, 't> GetAddress for ClassHeritageWithoutExpression<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct ClassHeritageWithoutTypeArguments<'a, 't>(
pub(crate) *const ClassHeritage<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> ClassHeritageWithoutTypeArguments<'a, 't> {
#[inline]
pub fn expression(self) -> &'t Expression<'a> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_CLASS_HERITAGE_EXPRESSION) as *const Expression<'a>)
}
}
}
impl<'a, 't> GetAddress for ClassHeritageWithoutTypeArguments<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
}
}
pub(crate) const OFFSET_CLASS_BODY_NODE_ID: usize = offset_of!(ClassBody, node_id);
pub(crate) const OFFSET_CLASS_BODY_SPAN: usize = offset_of!(ClassBody, span);
pub(crate) const OFFSET_CLASS_BODY_BODY: usize = offset_of!(ClassBody, body);
@@ -1266,6 +1266,21 @@ pub trait Traverse<'a, State> {
#[inline]
fn exit_class(&mut self, node: &mut Class<'a>, ctx: &mut TraverseCtx<'a, State>) {}
#[inline]
fn enter_class_heritage(
&mut self,
node: &mut ClassHeritage<'a>,
ctx: &mut TraverseCtx<'a, State>,
) {
}
#[inline]
fn exit_class_heritage(
&mut self,
node: &mut ClassHeritage<'a>,
ctx: &mut TraverseCtx<'a, State>,
) {
}
#[inline]
fn enter_class_body(&mut self, node: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a, State>) {}
#[inline]
+28 -9
View File
@@ -2607,16 +2607,10 @@ unsafe fn walk_class<'a, State, Tr: Traverse<'a, State>>(
walk_ts_type_parameter_declaration(traverser, (&mut **field) as *mut _, ctx);
}
if let Some(field) =
&mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_SUPER_CLASS) as *mut Option<Expression>)
&mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_HERITAGE) as *mut Option<ClassHeritage>)
{
ctx.retag_stack(AncestorType::ClassSuperClass);
walk_expression(traverser, field as *mut _, ctx);
}
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_SUPER_TYPE_ARGUMENTS)
as *mut Option<ArenaBox<TSTypeParameterInstantiation>>)
{
ctx.retag_stack(AncestorType::ClassSuperTypeArguments);
walk_ts_type_parameter_instantiation(traverser, (&mut **field) as *mut _, ctx);
ctx.retag_stack(AncestorType::ClassHeritage);
walk_class_heritage(traverser, field as *mut _, ctx);
}
ctx.retag_stack(AncestorType::ClassImplements);
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_IMPLEMENTS)
@@ -2636,6 +2630,31 @@ unsafe fn walk_class<'a, State, Tr: Traverse<'a, State>>(
traverser.exit_class(&mut *node, ctx);
}
unsafe fn walk_class_heritage<'a, State, Tr: Traverse<'a, State>>(
traverser: &mut Tr,
node: *mut ClassHeritage<'a>,
ctx: &mut TraverseCtx<'a, State>,
) {
traverser.enter_class_heritage(&mut *node, ctx);
let pop_token = ctx.push_stack(Ancestor::ClassHeritageExpression(
ancestor::ClassHeritageWithoutExpression(node, PhantomData),
));
walk_expression(
traverser,
(node as *mut u8).add(ancestor::OFFSET_CLASS_HERITAGE_EXPRESSION) as *mut Expression,
ctx,
);
if let Some(field) = &mut *((node as *mut u8)
.add(ancestor::OFFSET_CLASS_HERITAGE_TYPE_ARGUMENTS)
as *mut Option<ArenaBox<TSTypeParameterInstantiation>>)
{
ctx.retag_stack(AncestorType::ClassHeritageTypeArguments);
walk_ts_type_parameter_instantiation(traverser, (&mut **field) as *mut _, ctx);
}
ctx.pop_stack(pop_token);
traverser.exit_class_heritage(&mut *node, ctx);
}
unsafe fn walk_class_body<'a, State, Tr: Traverse<'a, State>>(
traverser: &mut Tr,
node: *mut ClassBody<'a>,
+10 -9
View File
@@ -1964,17 +1964,18 @@ function deserializeYieldExpression(pos) {
function deserializeClass(pos) {
let node = {
type: deserializeClassType(pos + 136),
decorators: null,
id: null,
superClass: null,
body: null,
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
};
type: deserializeClassType(pos + 136),
decorators: null,
id: null,
superClass: null,
body: null,
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
},
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.superClass = deserializeOptionExpression(pos + 80);
node.superClass = superClass;
node.body = deserializeBoxClassBody(pos + 128);
return node;
}
@@ -2184,10 +2184,11 @@ function deserializeClass(pos) {
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
parent,
});
}),
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.superClass = deserializeOptionExpression(pos + 80);
node.superClass = superClass;
node.body = deserializeBoxClassBody(pos + 128);
parent = previousParent;
return node;
@@ -2190,10 +2190,11 @@ function deserializeClass(pos) {
start: (start = deserializeI32(pos)),
end: (end = deserializeI32(pos + 4)),
range: [start, end],
};
},
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.superClass = deserializeOptionExpression(pos + 80);
node.superClass = superClass;
node.body = deserializeBoxClassBody(pos + 128);
return node;
}
@@ -2402,10 +2402,11 @@ function deserializeClass(pos) {
end: (end = deserializeI32(pos + 4)),
range: [start, end],
parent,
});
}),
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.superClass = deserializeOptionExpression(pos + 80);
node.superClass = superClass;
node.body = deserializeBoxClassBody(pos + 128);
parent = previousParent;
return node;
+19 -15
View File
@@ -2163,24 +2163,28 @@ function deserializeYieldExpression(pos) {
function deserializeClass(pos) {
let node = {
type: deserializeClassType(pos + 136),
decorators: null,
id: null,
typeParameters: null,
superClass: null,
superTypeArguments: null,
implements: null,
body: null,
abstract: deserializeBool(pos + 137),
declare: deserializeBool(pos + 138),
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
};
type: deserializeClassType(pos + 136),
decorators: null,
id: null,
typeParameters: null,
superClass: null,
superTypeArguments: null,
implements: null,
body: null,
abstract: deserializeBool(pos + 137),
declare: deserializeBool(pos + 138),
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
},
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.typeParameters = deserializeOptionBoxTSTypeParameterDeclaration(pos + 72);
node.superClass = deserializeOptionExpression(pos + 80);
node.superTypeArguments = deserializeOptionBoxTSTypeParameterInstantiation(pos + 96);
node.superClass = superClass;
node.superTypeArguments =
superClass === null
? null
: deserializeOptionBoxTSTypeParameterInstantiation(pos + 80 + (pos + 16 - pos));
node.implements = deserializeVecTSClassImplements(pos + 104);
node.body = deserializeBoxClassBody(pos + 128);
return node;
@@ -2407,12 +2407,16 @@ function deserializeClass(pos) {
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
parent,
});
}),
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.typeParameters = deserializeOptionBoxTSTypeParameterDeclaration(pos + 72);
node.superClass = deserializeOptionExpression(pos + 80);
node.superTypeArguments = deserializeOptionBoxTSTypeParameterInstantiation(pos + 96);
node.superClass = superClass;
node.superTypeArguments =
superClass === null
? null
: deserializeOptionBoxTSTypeParameterInstantiation(pos + 80 + (pos + 16 - pos));
node.implements = deserializeVecTSClassImplements(pos + 104);
node.body = deserializeBoxClassBody(pos + 128);
parent = previousParent;
@@ -2415,12 +2415,16 @@ function deserializeClass(pos) {
start: (start = deserializeI32(pos)),
end: (end = deserializeI32(pos + 4)),
range: [start, end],
};
},
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.typeParameters = deserializeOptionBoxTSTypeParameterDeclaration(pos + 72);
node.superClass = deserializeOptionExpression(pos + 80);
node.superTypeArguments = deserializeOptionBoxTSTypeParameterInstantiation(pos + 96);
node.superClass = superClass;
node.superTypeArguments =
superClass === null
? null
: deserializeOptionBoxTSTypeParameterInstantiation(pos + 80 + (pos + 16 - pos));
node.implements = deserializeVecTSClassImplements(pos + 104);
node.body = deserializeBoxClassBody(pos + 128);
return node;
@@ -2646,12 +2646,16 @@ function deserializeClass(pos) {
end: (end = deserializeI32(pos + 4)),
range: [start, end],
parent,
});
}),
superClass = deserializeOptionExpression(pos + 80);
node.decorators = deserializeVecDecorator(pos + 16);
node.id = deserializeOptionBindingIdentifier(pos + 40);
node.typeParameters = deserializeOptionBoxTSTypeParameterDeclaration(pos + 72);
node.superClass = deserializeOptionExpression(pos + 80);
node.superTypeArguments = deserializeOptionBoxTSTypeParameterInstantiation(pos + 96);
node.superClass = superClass;
node.superTypeArguments =
superClass === null
? null
: deserializeOptionBoxTSTypeParameterInstantiation(pos + 80 + (pos + 16 - pos));
node.implements = deserializeVecTSClassImplements(pos + 104);
node.body = deserializeBoxClassBody(pos + 128);
parent = previousParent;
@@ -5003,16 +5003,6 @@ export class Class {
return constructOptionBoxTSTypeParameterDeclaration(internal.pos + 72, internal.ast);
}
get superClass() {
const internal = this.#internal;
return constructOptionExpression(internal.pos + 80, internal.ast);
}
get superTypeArguments() {
const internal = this.#internal;
return constructOptionBoxTSTypeParameterInstantiation(internal.pos + 96, internal.ast);
}
get implements() {
const internal = this.#internal,
cached = internal.$implements;
@@ -5043,8 +5033,6 @@ export class Class {
decorators: this.decorators,
id: this.id,
typeParameters: this.typeParameters,
superClass: this.superClass,
superTypeArguments: this.superTypeArguments,
implements: this.implements,
body: this.body,
abstract: this.abstract,
@@ -2465,8 +2465,6 @@ function walkClass(pos, ast, visitors) {
walkVecDecorator(pos + 16, ast, visitors);
walkOptionBindingIdentifier(pos + 40, ast, visitors);
walkOptionBoxTSTypeParameterDeclaration(pos + 72, ast, visitors);
walkOptionExpression(pos + 80, ast, visitors);
walkOptionBoxTSTypeParameterInstantiation(pos + 96, ast, visitors);
walkVecTSClassImplements(pos + 104, ast, visitors);
walkBoxClassBody(pos + 128, ast, visitors);
@@ -253,11 +253,14 @@ fn generate_builder_methods_for_struct_impl(
}
let params_docs = generate_doc_comment_for_params(params);
let unused_builder_attr =
(!fields.to_string().contains("builder")).then(|| quote!(#[expect(unused_variables)]));
let new_method = quote! {
///@@line_break
#fn_docs
#params_docs
#unused_builder_attr
#[inline]
pub fn #new_fn_name #lifetime_param (#fn_params, builder: &impl GetAstBuilder<'a>) -> Self {
let builder = builder.builder();
@@ -16,7 +16,7 @@ App.tsx:
sys deallocs: 5190
sys alloc bytes: 1564670 # 1.56 MB
sys peak growth: 435358 # 435.36 kB
arena allocs: 208774
arena allocs: 208775
arena reallocs: 364
arena size: 16832304 # 16.83 MB
@@ -38,9 +38,9 @@ pdf.mjs:
sys deallocs: 9774
sys alloc bytes: 3141552 # 3.14 MB
sys peak growth: 1156432 # 1.16 MB
arena allocs: 427486
arena allocs: 427539
arena reallocs: 428
arena size: 29365912 # 29.37 MB
arena size: 29368032 # 29.37 MB
antd.js:
file size: 6686316 # 6.69 MB
@@ -71,6 +71,6 @@ kitchen-sink.tsx:
sys deallocs: 17086
sys alloc bytes: 4436340 # 4.44 MB
sys peak growth: 1491796 # 1.49 MB
arena allocs: 555504
arena allocs: 555537
arena reallocs: 1041
arena size: 38313232 # 38.31 MB
arena size: 38314984 # 38.31 MB
@@ -73,4 +73,4 @@ kitchen-sink.tsx:
sys peak growth: 3707425 # 3.71 MB
arena allocs: 66806
arena reallocs: 12252
arena size: 9424640 # 9.42 MB
arena size: 9424360 # 9.42 MB
@@ -73,4 +73,4 @@ kitchen-sink.tsx:
sys peak growth: 14644 # 14.64 kB
arena allocs: 136453
arena reallocs: 11898
arena size: 6440384 # 6.44 MB
arena size: 6440104 # 6.44 MB
@@ -73,4 +73,4 @@ kitchen-sink.tsx:
sys peak growth: 1101954 # 1.10 MB
arena allocs: 0
arena reallocs: 0
arena size: 6440384 # 6.44 MB
arena size: 6440104 # 6.44 MB
@@ -73,4 +73,4 @@ kitchen-sink.tsx:
sys peak growth: 3218 # 3.22 kB
arena allocs: 6132
arena reallocs: 280
arena size: 6774480 # 6.77 MB
arena size: 6774200 # 6.77 MB