feat(ast)!: store single parameter in TSIndexSignature::parameter (#25154)

This commit is contained in:
camc314 committed 2026-07-31 20:35:37 +00:00
1 parent d9c288b064
commit 067da8c4e7
35 files changed
+180 -332

No files matched your search

+2 -14
View File
@@ -5022,8 +5022,8 @@ function deserializeTSIndexSignature(pos) {
range: [start, end],
parent,
});
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
parent = previousParent;
return node;
}
@@ -7215,18 +7215,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
+3 -2
View File
@@ -1042,7 +1042,7 @@ pub enum TSSignature<'a> {
/// [playground link](https://oxc-playground.netlify.app/?code=3YCAAIC9gICAgICAgIC6nsrEgtem3AB/pQsrWlLnujiFhkHVtfeFMq5RMD7X5AzJnZ5R/ecQ5KG1FUFjzXvrxFXH0m6HpS+Ob3TC8gQXeRQygA%3D%3D)
/// ```ts
/// type MapOf<T> = {
/// // _________ parameters (vec with 1 element)
/// // _________ parameter
/// [K: string]: T
/// // - type_annotation
/// }
@@ -1055,7 +1055,8 @@ pub enum TSSignature<'a> {
pub struct TSIndexSignature<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub parameters: Vec<'a, TSIndexSignatureName<'a>>,
#[estree(rename = "parameters", via = TSIndexSignatureParameters)]
pub parameter: TSIndexSignatureName<'a>,
pub type_annotation: Box<'a, TSTypeAnnotation<'a>>,
pub readonly: bool,
pub r#static: bool,
@@ -1504,14 +1504,14 @@ const _: () = {
assert!(align_of::<TSSignature>() == 8);
// Padding: 2 bytes
assert!(size_of::<TSIndexSignature>() == 48);
assert!(size_of::<TSIndexSignature>() == 64);
assert!(align_of::<TSIndexSignature>() == 8);
assert!(offset_of!(TSIndexSignature, span) == 0);
assert!(offset_of!(TSIndexSignature, node_id) == 8);
assert!(offset_of!(TSIndexSignature, readonly) == 12);
assert!(offset_of!(TSIndexSignature, r#static) == 13);
assert!(offset_of!(TSIndexSignature, parameters) == 16);
assert!(offset_of!(TSIndexSignature, type_annotation) == 40);
assert!(offset_of!(TSIndexSignature, parameter) == 16);
assert!(offset_of!(TSIndexSignature, type_annotation) == 56);
// Padding: 0 bytes
assert!(size_of::<TSCallSignatureDeclaration>() == 48);
@@ -3335,14 +3335,14 @@ const _: () = if cfg!(target_family = "wasm") || align_of::<u64>() == 8 {
assert!(align_of::<TSSignature>() == 4);
// Padding: 2 bytes
assert!(size_of::<TSIndexSignature>() == 36);
assert!(size_of::<TSIndexSignature>() == 48);
assert!(align_of::<TSIndexSignature>() == 4);
assert!(offset_of!(TSIndexSignature, span) == 0);
assert!(offset_of!(TSIndexSignature, node_id) == 8);
assert!(offset_of!(TSIndexSignature, readonly) == 12);
assert!(offset_of!(TSIndexSignature, r#static) == 13);
assert!(offset_of!(TSIndexSignature, parameters) == 16);
assert!(offset_of!(TSIndexSignature, type_annotation) == 32);
assert!(offset_of!(TSIndexSignature, parameter) == 16);
assert!(offset_of!(TSIndexSignature, type_annotation) == 44);
// Padding: 0 bytes
assert!(size_of::<TSCallSignatureDeclaration>() == 32);
+20 -32
View File
@@ -15827,25 +15827,22 @@ impl<'a> ClassElement<'a> {
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `parameters`
/// * `parameter`
/// * `type_annotation`
/// * `readonly`
/// * `static`
#[inline]
pub fn new_ts_index_signature<B: GetAstBuilder<'a>, V1>(
pub fn new_ts_index_signature<B: GetAstBuilder<'a>>(
span: Span,
parameters: V1,
parameter: TSIndexSignatureName<'a>,
type_annotation: ArenaBox<'a, TSTypeAnnotation<'a>>,
readonly: bool,
r#static: bool,
builder: &B,
) -> Self
where
V1: IntoIn<'a, ArenaVec<'a, TSIndexSignatureName<'a>>>,
{
) -> Self {
Self::TSIndexSignature(TSIndexSignature::boxed(
span,
parameters,
parameter,
type_annotation,
readonly,
r#static,
@@ -25475,25 +25472,22 @@ impl<'a> TSSignature<'a> {
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `parameters`
/// * `parameter`
/// * `type_annotation`
/// * `readonly`
/// * `static`
#[inline]
pub fn new_ts_index_signature<B: GetAstBuilder<'a>, V1>(
pub fn new_ts_index_signature<B: GetAstBuilder<'a>>(
span: Span,
parameters: V1,
parameter: TSIndexSignatureName<'a>,
type_annotation: ArenaBox<'a, TSTypeAnnotation<'a>>,
readonly: bool,
r#static: bool,
builder: &B,
) -> Self
where
V1: IntoIn<'a, ArenaVec<'a, TSIndexSignatureName<'a>>>,
{
) -> Self {
Self::TSIndexSignature(TSIndexSignature::boxed(
span,
parameters,
parameter,
type_annotation,
readonly,
r#static,
@@ -25743,27 +25737,24 @@ impl<'a> TSIndexSignature<'a> {
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `parameters`
/// * `parameter`
/// * `type_annotation`
/// * `readonly`
/// * `static`
#[inline]
pub fn new<B: GetAstBuilder<'a>, V1>(
pub fn new<B: GetAstBuilder<'a>>(
span: Span,
parameters: V1,
parameter: TSIndexSignatureName<'a>,
type_annotation: ArenaBox<'a, TSTypeAnnotation<'a>>,
readonly: bool,
r#static: bool,
builder: &B,
) -> Self
where
V1: IntoIn<'a, ArenaVec<'a, TSIndexSignatureName<'a>>>,
{
) -> Self {
let builder = builder.builder();
TSIndexSignature {
node_id: Cell::new(builder.node_id()),
span,
parameters: parameters.into_in(builder.allocator()),
parameter,
type_annotation,
readonly,
r#static,
@@ -25777,25 +25768,22 @@ impl<'a> TSIndexSignature<'a> {
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `parameters`
/// * `parameter`
/// * `type_annotation`
/// * `readonly`
/// * `static`
#[inline]
pub fn boxed<B: GetAstBuilder<'a>, V1>(
pub fn boxed<B: GetAstBuilder<'a>>(
span: Span,
parameters: V1,
parameter: TSIndexSignatureName<'a>,
type_annotation: ArenaBox<'a, TSTypeAnnotation<'a>>,
readonly: bool,
r#static: bool,
builder: &B,
) -> ArenaBox<'a, Self>
where
V1: IntoIn<'a, ArenaVec<'a, TSIndexSignatureName<'a>>>,
{
) -> ArenaBox<'a, Self> {
let builder = builder.builder();
ArenaBox::new_in(
Self::new(span, parameters, type_annotation, readonly, r#static, builder),
Self::new(span, parameter, type_annotation, readonly, r#static, builder),
&builder.allocator(),
)
}
@@ -4878,7 +4878,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for TSIndexSignature<'_> {
TSIndexSignature {
node_id: CloneIn::clone_in_impl(&self.node_id, with_semantic_ids, allocator),
span: CloneIn::clone_in_impl(&self.span, with_semantic_ids, allocator),
parameters: CloneIn::clone_in_impl(&self.parameters, with_semantic_ids, allocator),
parameter: CloneIn::clone_in_impl(&self.parameter, with_semantic_ids, allocator),
type_annotation: CloneIn::clone_in_impl(
&self.type_annotation,
with_semantic_ids,
@@ -2263,7 +2263,7 @@ impl ContentEq for TSSignature<'_> {
impl ContentEq for TSIndexSignature<'_> {
fn content_eq(&self, other: &Self) -> bool {
ContentEq::content_eq(&self.parameters, &other.parameters)
ContentEq::content_eq(&self.parameter, &other.parameter)
&& ContentEq::content_eq(&self.type_annotation, &other.type_annotation)
&& ContentEq::content_eq(&self.readonly, &other.readonly)
&& ContentEq::content_eq(&self.r#static, &other.r#static)
+2 -2
View File
@@ -2706,12 +2706,12 @@ impl<'a> Dummy<'a> for TSSignature<'a> {
impl<'a> Dummy<'a> for TSIndexSignature<'a> {
/// Create a dummy [`TSIndexSignature`].
///
/// Has cost of making 2 allocations (48 bytes).
/// Has cost of making 4 allocations (96 bytes).
fn dummy(allocator: &'a Allocator) -> Self {
Self {
node_id: Dummy::dummy(allocator),
span: Dummy::dummy(allocator),
parameters: Dummy::dummy(allocator),
parameter: Dummy::dummy(allocator),
type_annotation: Dummy::dummy(allocator),
readonly: Dummy::dummy(allocator),
r#static: Dummy::dummy(allocator),
@@ -2887,7 +2887,8 @@ impl ESTree for TSIndexSignature<'_> {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut state = serializer.serialize_struct();
state.serialize_field("type", &JsonSafeString("TSIndexSignature"));
state.serialize_field("parameters", &self.parameters);
state
.serialize_field("parameters", &crate::serialize::ts::TSIndexSignatureParameters(self));
state.serialize_field("typeAnnotation", &self.type_annotation);
state.serialize_field("readonly", &self.readonly);
state.serialize_field("static", &self.r#static);
+22 -1
View File
@@ -1,7 +1,9 @@
use std::cell::Cell;
use oxc_ast_macros::ast_meta;
use oxc_estree::{Concat2, ESTree, JsonSafeString, Serializer, StructSerializer};
use oxc_estree::{
Concat2, ESTree, JsonSafeString, SequenceSerializer, Serializer, StructSerializer,
};
use oxc_syntax::node::NodeId;
use crate::ast::*;
@@ -404,6 +406,25 @@ impl ESTree for TSTypeNameAsMemberExpression<'_, '_> {
}
}
/// Serializer for `parameters` field of `TSIndexSignature`.
///
/// The Rust AST stores the single parameter required by the TypeScript grammar directly, while
/// TS-ESTree represents it as a one-element array.
#[ast_meta]
#[estree(
ts_type = "Array<TSIndexSignatureName>",
raw_deser = "[DESER[TSIndexSignatureName](POS_OFFSET.parameter)]"
)]
pub struct TSIndexSignatureParameters<'a, 'b>(pub &'b TSIndexSignature<'a>);
impl ESTree for TSIndexSignatureParameters<'_, '_> {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut seq = serializer.serialize_sequence();
seq.serialize_element(&self.0.parameter);
seq.end();
}
}
/// Serializer for `params` field of `TSCallSignatureDeclaration`.
///
/// Add `this_param` to start of the `params` array.
+1 -16
View File
@@ -1360,11 +1360,6 @@ pub trait Visit<'a>: Sized {
walk_ts_signatures(self, it);
}
#[inline]
fn visit_ts_index_signature_names(&mut self, it: &ArenaVec<'a, TSIndexSignatureName<'a>>) {
walk_ts_index_signature_names(self, it);
}
#[inline]
fn visit_spans(&mut self, it: &ArenaVec<'a, Span>) {
walk_spans(self, it);
@@ -3785,7 +3780,7 @@ pub mod walk {
let kind = AstKind::TSIndexSignature(visitor.alloc(it));
visitor.enter_node(kind);
visitor.visit_span(&it.span);
visitor.visit_ts_index_signature_names(&it.parameters);
visitor.visit_ts_index_signature_name(&it.parameter);
visitor.visit_ts_type_annotation(&it.type_annotation);
visitor.leave_node(kind);
}
@@ -4542,16 +4537,6 @@ pub mod walk {
}
}
#[inline]
pub fn walk_ts_index_signature_names<'a, V: Visit<'a>>(
visitor: &mut V,
it: &ArenaVec<'a, TSIndexSignatureName<'a>>,
) {
for el in it {
visitor.visit_ts_index_signature_name(el);
}
}
#[inline]
pub fn walk_spans<'a, V: Visit<'a>>(visitor: &mut V, it: &ArenaVec<'a, Span>) {
for el in it {
@@ -1355,11 +1355,6 @@ pub trait VisitMut<'a>: Sized {
walk_ts_signatures(self, it);
}
#[inline]
fn visit_ts_index_signature_names(&mut self, it: &mut ArenaVec<'a, TSIndexSignatureName<'a>>) {
walk_ts_index_signature_names(self, it);
}
#[inline]
fn visit_spans(&mut self, it: &mut ArenaVec<'a, Span>) {
walk_spans(self, it);
@@ -3996,7 +3991,7 @@ pub mod walk_mut {
let kind = AstType::TSIndexSignature;
visitor.enter_node(kind);
visitor.visit_span(&mut it.span);
visitor.visit_ts_index_signature_names(&mut it.parameters);
visitor.visit_ts_index_signature_name(&mut it.parameter);
visitor.visit_ts_type_annotation(&mut it.type_annotation);
visitor.leave_node(kind);
}
@@ -4798,16 +4793,6 @@ pub mod walk_mut {
}
}
#[inline]
pub fn walk_ts_index_signature_names<'a, V: VisitMut<'a>>(
visitor: &mut V,
it: &mut ArenaVec<'a, TSIndexSignatureName<'a>>,
) {
for el in it {
visitor.visit_ts_index_signature_name(el);
}
}
#[inline]
pub fn walk_spans<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut ArenaVec<'a, Span>) {
for el in it {
+4 -10
View File
@@ -3925,16 +3925,10 @@ impl Gen for TSIndexSignature<'_> {
p.print_str("readonly ");
}
p.print_ascii_byte(b'[');
for (index, parameter) in self.parameters.iter().enumerate() {
if index != 0 {
p.print_ascii_byte(b',');
p.print_soft_space();
}
p.print_str(parameter.name.as_str());
p.print_colon();
p.print_soft_space();
parameter.type_annotation.print(p, ctx);
}
p.print_str(self.parameter.name.as_str());
p.print_colon();
p.print_soft_space();
self.parameter.type_annotation.print(p, ctx);
p.print_ascii_byte(b']');
p.print_colon();
p.print_soft_space();
@@ -9073,10 +9073,10 @@ impl<'a> AstNode<'a, TSIndexSignature<'a>> {
}
#[inline]
pub fn parameters(&self) -> &AstNode<'a, ArenaVec<'a, TSIndexSignatureName<'a>>> {
pub fn parameter(&self) -> &AstNode<'a, TSIndexSignatureName<'a>> {
let following_span_start = self.inner.type_annotation.span().start;
self.allocator.alloc(AstNode {
inner: &self.inner.parameters,
inner: &self.inner.parameter,
allocator: self.allocator,
parent: AstNodes::TSIndexSignature(transmute_self(self)),
following_span_start,
+1 -11
View File
@@ -204,7 +204,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, TSIndexSignature<'a>> {
f,
[
"[",
self.parameters(),
self.parameter(),
"]",
self.type_annotation(),
is_class.then_some(OptionalSemicolon)
@@ -213,16 +213,6 @@ impl<'a> FormatWrite<'a> for AstNode<'a, TSIndexSignature<'a>> {
}
}
impl<'a> Format<'a, JsFormatContext<'a>> for AstNode<'a, ArenaVec<'a, TSIndexSignatureName<'a>>> {
fn fmt(&self, f: &mut JsFormatter<'_, 'a>) {
f.join_with(&soft_line_break_or_space()).entries_with_trailing_separator(
self.iter(),
",",
TrailingSeparator::Disallowed,
);
}
}
impl<'a> FormatWrite<'a> for AstNode<'a, TSIndexSignatureName<'a>> {
fn write(&self, f: &mut JsFormatter<'_, 'a>) {
write!(f, [text_without_whitespace(self.name().as_str()), self.type_annotation()]);
@@ -178,9 +178,8 @@ impl Rule for ConsistentIndexedObjectStyle {
return fixer.noop();
}
let key_type = sig.parameters.first().map_or("string", |p| {
fixer.source_range(p.type_annotation.type_annotation.span())
});
let key_type = fixer
.source_range(sig.parameter.type_annotation.type_annotation.span());
let value_type =
fixer.source_range(sig.type_annotation.type_annotation.span());
let type_params = inf
@@ -294,9 +293,8 @@ impl Rule for ConsistentIndexedObjectStyle {
sig.span,
),
|fixer| {
let key_type = sig.parameters.first().map_or("string", |p| {
fixer.source_range(p.type_annotation.type_annotation.span())
});
let key_type = fixer
.source_range(sig.parameter.type_annotation.type_annotation.span());
let value_type =
fixer.source_range(sig.type_annotation.type_annotation.span());
+13 -16
View File
@@ -258,7 +258,7 @@ pub(crate) enum AncestorType {
TSInterfaceBodyBody = 234,
TSPropertySignatureKey = 235,
TSPropertySignatureTypeAnnotation = 236,
TSIndexSignatureParameters = 237,
TSIndexSignatureParameter = 237,
TSIndexSignatureTypeAnnotation = 238,
TSCallSignatureDeclarationTypeParameters = 239,
TSCallSignatureDeclarationThisParam = 240,
@@ -776,8 +776,8 @@ pub enum Ancestor<'a, 't> {
AncestorType::TSPropertySignatureKey as u16,
TSPropertySignatureTypeAnnotation(TSPropertySignatureWithoutTypeAnnotation<'a, 't>) =
AncestorType::TSPropertySignatureTypeAnnotation as u16,
TSIndexSignatureParameters(TSIndexSignatureWithoutParameters<'a, 't>) =
AncestorType::TSIndexSignatureParameters as u16,
TSIndexSignatureParameter(TSIndexSignatureWithoutParameter<'a, 't>) =
AncestorType::TSIndexSignatureParameter as u16,
TSIndexSignatureTypeAnnotation(TSIndexSignatureWithoutTypeAnnotation<'a, 't>) =
AncestorType::TSIndexSignatureTypeAnnotation as u16,
TSCallSignatureDeclarationTypeParameters(
@@ -1690,10 +1690,7 @@ impl<'a, 't> Ancestor<'a, 't> {
#[inline]
pub fn is_ts_index_signature(self) -> bool {
matches!(
self,
Self::TSIndexSignatureParameters(_) | Self::TSIndexSignatureTypeAnnotation(_)
)
matches!(self, Self::TSIndexSignatureParameter(_) | Self::TSIndexSignatureTypeAnnotation(_))
}
#[inline]
@@ -2501,7 +2498,7 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> {
Self::TSInterfaceBodyBody(a) => a.address(),
Self::TSPropertySignatureKey(a) => a.address(),
Self::TSPropertySignatureTypeAnnotation(a) => a.address(),
Self::TSIndexSignatureParameters(a) => a.address(),
Self::TSIndexSignatureParameter(a) => a.address(),
Self::TSIndexSignatureTypeAnnotation(a) => a.address(),
Self::TSCallSignatureDeclarationTypeParameters(a) => a.address(),
Self::TSCallSignatureDeclarationThisParam(a) => a.address(),
@@ -15040,8 +15037,8 @@ impl<'a, 't> GetAddress for TSPropertySignatureWithoutTypeAnnotation<'a, 't> {
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_NODE_ID: usize = offset_of!(TSIndexSignature, node_id);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_SPAN: usize = offset_of!(TSIndexSignature, span);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_PARAMETERS: usize =
offset_of!(TSIndexSignature, parameters);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_PARAMETER: usize =
offset_of!(TSIndexSignature, parameter);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_TYPE_ANNOTATION: usize =
offset_of!(TSIndexSignature, type_annotation);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_READONLY: usize = offset_of!(TSIndexSignature, readonly);
@@ -15049,12 +15046,12 @@ pub(crate) const OFFSET_TS_INDEX_SIGNATURE_STATIC: usize = offset_of!(TSIndexSig
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct TSIndexSignatureWithoutParameters<'a, 't>(
pub struct TSIndexSignatureWithoutParameter<'a, 't>(
pub(crate) *const TSIndexSignature<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> TSIndexSignatureWithoutParameters<'a, 't> {
impl<'a, 't> TSIndexSignatureWithoutParameter<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe {
@@ -15086,7 +15083,7 @@ impl<'a, 't> TSIndexSignatureWithoutParameters<'a, 't> {
}
}
impl<'a, 't> GetAddress for TSIndexSignatureWithoutParameters<'a, 't> {
impl<'a, 't> GetAddress for TSIndexSignatureWithoutParameter<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
@@ -15114,10 +15111,10 @@ impl<'a, 't> TSIndexSignatureWithoutTypeAnnotation<'a, 't> {
}
#[inline]
pub fn parameters(self) -> &'t ArenaVec<'a, TSIndexSignatureName<'a>> {
pub fn parameter(self) -> &'t TSIndexSignatureName<'a> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_TS_INDEX_SIGNATURE_PARAMETERS)
as *const ArenaVec<'a, TSIndexSignatureName<'a>>)
&*((self.0 as *const u8).add(OFFSET_TS_INDEX_SIGNATURE_PARAMETER)
as *const TSIndexSignatureName<'a>)
}
}
+8 -7
View File
@@ -4853,14 +4853,15 @@ unsafe fn walk_ts_index_signature<'a, Tr: Traverse<'a>>(
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_index_signature(&mut *node, ctx);
let pop_token = ctx.push_stack(Ancestor::TSIndexSignatureParameters(
ancestor::TSIndexSignatureWithoutParameters(node, PhantomData),
let pop_token = ctx.push_stack(Ancestor::TSIndexSignatureParameter(
ancestor::TSIndexSignatureWithoutParameter(node, PhantomData),
));
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_TS_INDEX_SIGNATURE_PARAMETERS)
as *mut ArenaVec<TSIndexSignatureName>)
{
walk_ts_index_signature_name(traverser, item as *mut _, ctx);
}
walk_ts_index_signature_name(
traverser,
(node as *mut u8).add(ancestor::OFFSET_TS_INDEX_SIGNATURE_PARAMETER)
as *mut TSIndexSignatureName,
ctx,
);
ctx.retag_stack(AncestorType::TSIndexSignatureTypeAnnotation);
walk_ts_type_annotation(
traverser,
@@ -1900,7 +1900,7 @@ impl<'a> Visit<'a> for ChildScopeCollector {
#[inline]
fn visit_ts_index_signature(&mut self, it: &TSIndexSignature<'a>) {
self.visit_ts_index_signature_names(&it.parameters);
self.visit_ts_index_signature_name(&it.parameter);
self.visit_ts_type_annotation(&it.type_annotation);
}
+36 -13
View File
@@ -1,4 +1,4 @@
use oxc_allocator::{ArenaBox, ArenaVec};
use oxc_allocator::{ArenaBox, ArenaVec, Dummy, GetAllocator};
use oxc_ast::ast::*;
use oxc_span::GetSpan;
use oxc_syntax::operator::UnaryOperator;
@@ -1536,12 +1536,34 @@ impl<'a, C: Config> ParserImpl<'a, C> {
) -> ArenaBox<'a, TSIndexSignature<'a>> {
let opening_span = self.cur_token().span();
self.expect(Kind::LBrack);
let (params, comma_span) = self.parse_delimited_list(
Kind::RBrack,
Kind::Comma,
opening_span,
Self::parse_ts_index_signature_name,
);
let mut parameter_count = 0;
let mut comma_span = None;
let parameter = if self.at(Kind::RBrack) || self.has_fatal_error() {
TSIndexSignatureName::dummy(self.allocator())
} else {
parameter_count = 1;
let parameter = self.parse_ts_index_signature_name();
while !self.at(Kind::RBrack) && !self.has_fatal_error() {
if !self.at(Kind::Comma) {
self.set_fatal_error(diagnostics::expect_closing_or_separator(
Kind::RBrack.to_str(),
Kind::Comma.to_str(),
self.cur_kind().to_str(),
self.cur_token().span(),
opening_span,
));
break;
}
self.advance(Kind::Comma);
if self.at(Kind::RBrack) {
comma_span = Some(self.prev_token_end - 1);
break;
}
parameter_count += 1;
let _ = self.parse_ts_index_signature_name();
}
parameter
};
if let Some(comma_span) = comma_span {
self.error(diagnostics::unexpected_trailing_comma(
"Index signature declarations",
@@ -1549,8 +1571,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
));
}
self.expect(Kind::RBrack);
match params.as_slice() {
[param] => match &param.type_annotation.type_annotation {
if parameter_count == 1 {
match &parameter.type_annotation.type_annotation {
TSType::TSLiteralType(ty) => {
self.error(diagnostics::index_signature_parameter_literal_type(ty.span));
}
@@ -1559,11 +1581,12 @@ impl<'a, C: Config> ParserImpl<'a, C> {
| TSType::TSSymbolKeyword(_)
| TSType::TSAnyKeyword(_) => {}
ty if ty.is_keyword() => {
self.error(diagnostics::index_signature_parameter_type(param.span));
self.error(diagnostics::index_signature_parameter_type(parameter.span));
}
_ => {}
},
_ => self.error(diagnostics::index_signature_one_parameter(self.end_span(span))),
}
} else {
self.error(diagnostics::index_signature_one_parameter(self.end_span(span)));
}
let Some(type_annotation) = self.parse_ts_type_annotation() else {
return self
@@ -1572,7 +1595,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
self.parse_type_member_semicolon();
TSIndexSignature::boxed(
self.end_span(span),
params,
parameter,
type_annotation,
modifiers.contains(ModifierKind::Readonly),
modifiers.contains(ModifierKind::Static),
@@ -1068,7 +1068,7 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
//
// If it *is* possible, I'm also not sure what correct behavior should be.
// As best guess, treating it like class properties:
// Treat `parameters` like computed key, `type_annotation` like initializer value.
// Treat `parameter` like computed key, `type_annotation` like initializer value.
if sig.type_annotation.address() == previous_node_address {
// In signature's `type_annotation` - `super.foo` is legal here, `super()` is not
if super_call_span.is_some() {
@@ -1076,7 +1076,7 @@ pub fn check_super(sup: &Super, ctx: &SemanticBuilder<'_>) {
}
return;
}
// In `parameters` - treat like computed key
// In `parameter` - treat like computed key
}
_ => {
previous_node_address = ancestor_kind.address();
+13 -16
View File
@@ -258,7 +258,7 @@ pub(crate) enum AncestorType {
TSInterfaceBodyBody = 234,
TSPropertySignatureKey = 235,
TSPropertySignatureTypeAnnotation = 236,
TSIndexSignatureParameters = 237,
TSIndexSignatureParameter = 237,
TSIndexSignatureTypeAnnotation = 238,
TSCallSignatureDeclarationTypeParameters = 239,
TSCallSignatureDeclarationThisParam = 240,
@@ -776,8 +776,8 @@ pub enum Ancestor<'a, 't> {
AncestorType::TSPropertySignatureKey as u16,
TSPropertySignatureTypeAnnotation(TSPropertySignatureWithoutTypeAnnotation<'a, 't>) =
AncestorType::TSPropertySignatureTypeAnnotation as u16,
TSIndexSignatureParameters(TSIndexSignatureWithoutParameters<'a, 't>) =
AncestorType::TSIndexSignatureParameters as u16,
TSIndexSignatureParameter(TSIndexSignatureWithoutParameter<'a, 't>) =
AncestorType::TSIndexSignatureParameter as u16,
TSIndexSignatureTypeAnnotation(TSIndexSignatureWithoutTypeAnnotation<'a, 't>) =
AncestorType::TSIndexSignatureTypeAnnotation as u16,
TSCallSignatureDeclarationTypeParameters(
@@ -1690,10 +1690,7 @@ impl<'a, 't> Ancestor<'a, 't> {
#[inline]
pub fn is_ts_index_signature(self) -> bool {
matches!(
self,
Self::TSIndexSignatureParameters(_) | Self::TSIndexSignatureTypeAnnotation(_)
)
matches!(self, Self::TSIndexSignatureParameter(_) | Self::TSIndexSignatureTypeAnnotation(_))
}
#[inline]
@@ -2501,7 +2498,7 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> {
Self::TSInterfaceBodyBody(a) => a.address(),
Self::TSPropertySignatureKey(a) => a.address(),
Self::TSPropertySignatureTypeAnnotation(a) => a.address(),
Self::TSIndexSignatureParameters(a) => a.address(),
Self::TSIndexSignatureParameter(a) => a.address(),
Self::TSIndexSignatureTypeAnnotation(a) => a.address(),
Self::TSCallSignatureDeclarationTypeParameters(a) => a.address(),
Self::TSCallSignatureDeclarationThisParam(a) => a.address(),
@@ -15040,8 +15037,8 @@ impl<'a, 't> GetAddress for TSPropertySignatureWithoutTypeAnnotation<'a, 't> {
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_NODE_ID: usize = offset_of!(TSIndexSignature, node_id);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_SPAN: usize = offset_of!(TSIndexSignature, span);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_PARAMETERS: usize =
offset_of!(TSIndexSignature, parameters);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_PARAMETER: usize =
offset_of!(TSIndexSignature, parameter);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_TYPE_ANNOTATION: usize =
offset_of!(TSIndexSignature, type_annotation);
pub(crate) const OFFSET_TS_INDEX_SIGNATURE_READONLY: usize = offset_of!(TSIndexSignature, readonly);
@@ -15049,12 +15046,12 @@ pub(crate) const OFFSET_TS_INDEX_SIGNATURE_STATIC: usize = offset_of!(TSIndexSig
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct TSIndexSignatureWithoutParameters<'a, 't>(
pub struct TSIndexSignatureWithoutParameter<'a, 't>(
pub(crate) *const TSIndexSignature<'a>,
pub(crate) PhantomData<&'t ()>,
);
impl<'a, 't> TSIndexSignatureWithoutParameters<'a, 't> {
impl<'a, 't> TSIndexSignatureWithoutParameter<'a, 't> {
#[inline]
pub fn node_id(self) -> &'t Cell<NodeId> {
unsafe {
@@ -15086,7 +15083,7 @@ impl<'a, 't> TSIndexSignatureWithoutParameters<'a, 't> {
}
}
impl<'a, 't> GetAddress for TSIndexSignatureWithoutParameters<'a, 't> {
impl<'a, 't> GetAddress for TSIndexSignatureWithoutParameter<'a, 't> {
#[inline]
fn address(&self) -> Address {
unsafe { Address::from_ptr(self.0) }
@@ -15114,10 +15111,10 @@ impl<'a, 't> TSIndexSignatureWithoutTypeAnnotation<'a, 't> {
}
#[inline]
pub fn parameters(self) -> &'t ArenaVec<'a, TSIndexSignatureName<'a>> {
pub fn parameter(self) -> &'t TSIndexSignatureName<'a> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_TS_INDEX_SIGNATURE_PARAMETERS)
as *const ArenaVec<'a, TSIndexSignatureName<'a>>)
&*((self.0 as *const u8).add(OFFSET_TS_INDEX_SIGNATURE_PARAMETER)
as *const TSIndexSignatureName<'a>)
}
}
@@ -1900,7 +1900,7 @@ impl<'a> Visit<'a> for ChildScopeCollector {
#[inline]
fn visit_ts_index_signature(&mut self, it: &TSIndexSignature<'a>) {
self.visit_ts_index_signature_names(&it.parameters);
self.visit_ts_index_signature_name(&it.parameter);
self.visit_ts_type_annotation(&it.type_annotation);
}
+8 -7
View File
@@ -4853,14 +4853,15 @@ unsafe fn walk_ts_index_signature<'a, State, Tr: Traverse<'a, State>>(
ctx: &mut TraverseCtx<'a, State>,
) {
traverser.enter_ts_index_signature(&mut *node, ctx);
let pop_token = ctx.push_stack(Ancestor::TSIndexSignatureParameters(
ancestor::TSIndexSignatureWithoutParameters(node, PhantomData),
let pop_token = ctx.push_stack(Ancestor::TSIndexSignatureParameter(
ancestor::TSIndexSignatureWithoutParameter(node, PhantomData),
));
for item in &mut *((node as *mut u8).add(ancestor::OFFSET_TS_INDEX_SIGNATURE_PARAMETERS)
as *mut ArenaVec<TSIndexSignatureName>)
{
walk_ts_index_signature_name(traverser, item as *mut _, ctx);
}
walk_ts_index_signature_name(
traverser,
(node as *mut u8).add(ancestor::OFFSET_TS_INDEX_SIGNATURE_PARAMETER)
as *mut TSIndexSignatureName,
ctx,
);
ctx.retag_stack(AncestorType::TSIndexSignatureTypeAnnotation);
walk_ts_type_annotation(
traverser,
+2 -14
View File
@@ -3681,8 +3681,8 @@ function deserializeTSIndexSignature(pos) {
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
};
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
return node;
}
@@ -5893,18 +5893,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4097,8 +4097,8 @@ function deserializeTSIndexSignature(pos) {
end: deserializeI32(pos + 4),
parent,
});
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
parent = previousParent;
return node;
}
@@ -6416,18 +6416,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4115,8 +4115,8 @@ function deserializeTSIndexSignature(pos) {
end: (end = deserializeI32(pos + 4)),
range: [start, end],
};
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
return node;
}
@@ -6451,18 +6451,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4529,8 +4529,8 @@ function deserializeTSIndexSignature(pos) {
range: [start, end],
parent,
});
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
parent = previousParent;
return node;
}
@@ -6973,18 +6973,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
+2 -14
View File
@@ -3975,8 +3975,8 @@ function deserializeTSIndexSignature(pos) {
start: deserializeI32(pos),
end: deserializeI32(pos + 4),
};
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
return node;
}
@@ -6206,18 +6206,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4421,8 +4421,8 @@ function deserializeTSIndexSignature(pos) {
end: deserializeI32(pos + 4),
parent,
});
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
parent = previousParent;
return node;
}
@@ -6759,18 +6759,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4437,8 +4437,8 @@ function deserializeTSIndexSignature(pos) {
end: (end = deserializeI32(pos + 4)),
range: [start, end],
};
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
return node;
}
@@ -6792,18 +6792,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -4881,8 +4881,8 @@ function deserializeTSIndexSignature(pos) {
range: [start, end],
parent,
});
node.parameters = deserializeVecTSIndexSignatureName(pos + 16);
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 40);
node.parameters = [deserializeTSIndexSignatureName(pos + 16)];
node.typeAnnotation = deserializeBoxTSTypeAnnotation(pos + 56);
parent = previousParent;
return node;
}
@@ -7344,18 +7344,6 @@ function deserializeBoxTSMethodSignature(pos) {
return deserializeTSMethodSignature(int32[pos >> 2]);
}
function deserializeVecTSIndexSignatureName(pos) {
let arr = [],
pos32 = pos >> 2;
pos = int32[pos32];
let endPos = pos + int32[pos32 + 2] * 40;
for (; pos !== endPos;) {
arr.push(deserializeTSIndexSignatureName(pos));
pos += 40;
}
return arr;
}
function deserializeOptionTSModuleDeclarationBody(pos) {
return uint8[pos] === 2 ? null : deserializeTSModuleDeclarationBody(pos);
}
@@ -10118,7 +10118,7 @@ export class TSIndexSignature {
const cached = nodes.get(pos);
if (cached !== void 0) return cached;
this.#internal = { pos, ast, $parameters: void 0 };
this.#internal = { pos, ast };
nodes.set(pos, this);
}
@@ -10133,18 +10133,13 @@ export class TSIndexSignature {
}
get parameters() {
const internal = this.#internal,
cached = internal.$parameters;
if (cached !== void 0) return cached;
return (internal.$parameters = constructVecTSIndexSignatureName(
internal.pos + 16,
internal.ast,
));
const internal = this.#internal;
return new TSIndexSignatureName(internal.pos + 16, internal.ast);
}
get typeAnnotation() {
const internal = this.#internal;
return constructBoxTSTypeAnnotation(internal.pos + 40, internal.ast);
return constructBoxTSTypeAnnotation(internal.pos + 56, internal.ast);
}
get readonly() {
@@ -13961,16 +13956,6 @@ function constructBoxTSMethodSignature(pos, ast) {
return new TSMethodSignature(ast.buffer.int32[pos >> 2], ast);
}
function constructVecTSIndexSignatureName(pos, ast) {
const { int32 } = ast.buffer,
pos32 = pos >> 2;
return new NodeArray(int32[pos32], int32[pos32 + 2], 40, constructTSIndexSignatureName, ast);
}
function constructTSIndexSignatureName(pos, ast) {
return new TSIndexSignatureName(pos, ast);
}
function constructOptionTSModuleDeclarationBody(pos, ast) {
if (ast.buffer[pos] === 2) return null;
return constructTSModuleDeclarationBody(pos, ast);
+2 -13
View File
@@ -4309,8 +4309,8 @@ function walkTSIndexSignature(pos, ast, visitors) {
if (enter !== null) enter(node);
}
walkVecTSIndexSignatureName(pos + 16, ast, visitors);
walkBoxTSTypeAnnotation(pos + 40, ast, visitors);
walkTSIndexSignatureName(pos + 16, ast, visitors);
walkBoxTSTypeAnnotation(pos + 56, ast, visitors);
if (exit !== null) exit(node);
}
@@ -5969,17 +5969,6 @@ function walkBoxTSMethodSignature(pos, ast, visitors) {
return walkTSMethodSignature(ast.buffer.int32[pos >> 2], ast, visitors);
}
function walkVecTSIndexSignatureName(pos, ast, visitors) {
const { int32 } = ast.buffer,
pos32 = pos >> 2;
pos = int32[pos32];
const endPos = pos + int32[pos32 + 2] * 40;
while (pos < endPos) {
walkTSIndexSignatureName(pos, ast, visitors);
pos += 40;
}
}
function walkOptionTSModuleDeclarationBody(pos, ast, visitors) {
if (!(ast.buffer[pos] === 2)) walkTSModuleDeclarationBody(pos, ast, visitors);
}
@@ -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: 208786
arena allocs: 208774
arena reallocs: 364
arena size: 16832880 # 16.83 MB
@@ -71,7 +71,7 @@ kitchen-sink.tsx:
sys deallocs: 17086
sys alloc bytes: 4436340 # 4.44 MB
sys peak growth: 1491796 # 1.49 MB
arena allocs: 555532
arena allocs: 555511
arena reallocs: 1041
arena size: 38314608 # 38.31 MB
@@ -16,7 +16,7 @@ App.tsx:
sys deallocs: 23
sys alloc bytes: 38116 # 38.12 kB
sys peak growth: 26404 # 26.40 kB
arena allocs: 44041
arena allocs: 44037
arena reallocs: 3537
arena size: 2230856 # 2.23 MB
@@ -71,7 +71,7 @@ kitchen-sink.tsx:
sys deallocs: 190
sys alloc bytes: 51381 # 51.38 kB
sys peak growth: 14644 # 14.64 kB
arena allocs: 136460
arena allocs: 136453
arena reallocs: 11898
arena size: 6440384 # 6.44 MB