feat(ast,codegen): add TSParenthesizedType and print type parentheses correctly (#3979)

closes #3916
This commit is contained in:
Boshen 2024-06-30 07:57:47 +00:00
parent 5845057bff
commit dc6d45e2e6
18 changed files with 233 additions and 119 deletions

View file

@ -616,14 +616,16 @@ macro_rules! inherit_variants {
TSTypeReference(Box<'a, TSTypeReference<'a>>) = 32,
/// Inherited from [`TSType`]
TSUnionType(Box<'a, TSUnionType<'a>>) = 33,
/// Inherited from [`TSType`]
TSParenthesizedType(Box<'a, TSParenthesizedType<'a>>) = 34,
// JSDoc
/// Inherited from [`TSType`]
JSDocNullableType(Box<'a, JSDocNullableType<'a>>) = 34,
JSDocNullableType(Box<'a, JSDocNullableType<'a>>) = 35,
/// Inherited from [`TSType`]
JSDocNonNullableType(Box<'a, JSDocNonNullableType<'a>>) = 35,
JSDocNonNullableType(Box<'a, JSDocNonNullableType<'a>>) = 36,
/// Inherited from [`TSType`]
JSDocUnknownType(Box<'a, JSDocUnknownType>) = 36,
JSDocUnknownType(Box<'a, JSDocUnknownType>) = 37,
$($rest)*
}
@ -672,6 +674,7 @@ macro_rules! inherit_variants {
TSTypeQuery,
TSTypeReference,
TSUnionType,
TSParenthesizedType,
JSDocNullableType,
JSDocNonNullableType,
JSDocUnknownType,

View file

@ -172,10 +172,11 @@ pub enum TSType<'a> {
TSTypeQuery(Box<'a, TSTypeQuery<'a>>) = 31,
TSTypeReference(Box<'a, TSTypeReference<'a>>) = 32,
TSUnionType(Box<'a, TSUnionType<'a>>) = 33,
TSParenthesizedType(Box<'a, TSParenthesizedType<'a>>) = 34,
// JSDoc
JSDocNullableType(Box<'a, JSDocNullableType<'a>>) = 34,
JSDocNonNullableType(Box<'a, JSDocNonNullableType<'a>>) = 35,
JSDocUnknownType(Box<'a, JSDocUnknownType>) = 36,
JSDocNullableType(Box<'a, JSDocNullableType<'a>>) = 35,
JSDocNonNullableType(Box<'a, JSDocNonNullableType<'a>>) = 36,
JSDocUnknownType(Box<'a, JSDocUnknownType>) = 37,
}
/// Macro for matching `TSType`'s variants.
@ -216,6 +217,7 @@ macro_rules! match_ts_type {
| $ty::TSTypeQuery(_)
| $ty::TSTypeReference(_)
| $ty::TSUnionType(_)
| $ty::TSParenthesizedType(_)
| $ty::JSDocNullableType(_)
| $ty::JSDocNonNullableType(_)
| $ty::JSDocUnknownType(_)
@ -265,6 +267,16 @@ pub struct TSIntersectionType<'a> {
pub types: Vec<'a, TSType<'a>>,
}
#[visited_node]
#[derive(Debug, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(tag = "type"))]
pub struct TSParenthesizedType<'a> {
#[cfg_attr(feature = "serialize", serde(flatten))]
pub span: Span,
pub type_annotation: TSType<'a>,
}
/// keyof unique readonly
///
/// <https://www.typescriptlang.org/docs/handbook/2/keyof-types.html>

View file

@ -1539,6 +1539,11 @@ impl<'a> AstBuilder<'a> {
TSType::TSUnionType(self.alloc(TSUnionType { span, types }))
}
#[inline]
pub fn ts_parenthesized_type(self, span: Span, ty: TSType<'a>) -> TSType<'a> {
TSType::TSParenthesizedType(self.alloc(TSParenthesizedType { span, type_annotation: ty }))
}
#[inline]
pub fn ts_intersection_type(self, span: Span, types: Vec<'a, TSType<'a>>) -> TSType<'a> {
TSType::TSIntersectionType(self.alloc(TSIntersectionType { span, types }))

View file

@ -128,6 +128,16 @@ impl<'a> Hash for TSTypeParameter<'a> {
}
}
impl<'a> TSType<'a> {
/// Remove nested parentheses from this type.
pub fn without_parenthesized(&self) -> &Self {
match self {
Self::TSParenthesizedType(expr) => expr.type_annotation.without_parenthesized(),
_ => self,
}
}
}
impl TSAccessibility {
pub fn is_private(&self) -> bool {
matches!(self, TSAccessibility::Private)

View file

@ -299,6 +299,7 @@ impl<'a> AstKind<'a> {
Self::TSTypeLiteral(_) => "TSTypeLiteral".into(),
Self::TSTypeReference(_) => "TSTypeReference".into(),
Self::TSUnionType(_) => "TSUnionType".into(),
Self::TSParenthesizedType(_) => "TSParenthesizedType".into(),
Self::TSVoidKeyword(_) => "TSVoidKeyword".into(),
Self::TSBigIntKeyword(_) => "TSBigIntKeyword".into(),
Self::TSBooleanKeyword(_) => "TSBooleanKeyword".into(),

View file

@ -107,6 +107,7 @@ pub enum AstType {
TSLiteralType,
TSUnionType,
TSIntersectionType,
TSParenthesizedType,
TSIndexedAccessType,
TSNamedTupleMember,
TSAnyKeyword,
@ -272,6 +273,7 @@ pub enum AstKind<'a> {
TSLiteralType(&'a TSLiteralType<'a>),
TSUnionType(&'a TSUnionType<'a>),
TSIntersectionType(&'a TSIntersectionType<'a>),
TSParenthesizedType(&'a TSParenthesizedType<'a>),
TSIndexedAccessType(&'a TSIndexedAccessType<'a>),
TSNamedTupleMember(&'a TSNamedTupleMember<'a>),
TSAnyKeyword(&'a TSAnyKeyword),
@ -438,6 +440,7 @@ impl<'a> GetSpan for AstKind<'a> {
Self::TSLiteralType(it) => it.span(),
Self::TSUnionType(it) => it.span(),
Self::TSIntersectionType(it) => it.span(),
Self::TSParenthesizedType(it) => it.span(),
Self::TSIndexedAccessType(it) => it.span(),
Self::TSNamedTupleMember(it) => it.span(),
Self::TSAnyKeyword(it) => it.span(),

View file

@ -1384,6 +1384,7 @@ impl<'a> GetSpan for TSType<'a> {
Self::TSTypeQuery(it) => it.span(),
Self::TSTypeReference(it) => it.span(),
Self::TSUnionType(it) => it.span(),
Self::TSParenthesizedType(it) => it.span(),
Self::JSDocNullableType(it) => it.span(),
Self::JSDocNonNullableType(it) => it.span(),
Self::JSDocUnknownType(it) => it.span(),
@ -1412,6 +1413,13 @@ impl<'a> GetSpan for TSIntersectionType<'a> {
}
}
impl<'a> GetSpan for TSParenthesizedType<'a> {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl<'a> GetSpan for TSTypeOperator<'a> {
#[inline]
fn span(&self) -> Span {
@ -1500,6 +1508,7 @@ impl<'a> GetSpan for TSTupleElement<'a> {
Self::TSTypeQuery(it) => it.span(),
Self::TSTypeReference(it) => it.span(),
Self::TSUnionType(it) => it.span(),
Self::TSParenthesizedType(it) => it.span(),
Self::JSDocNullableType(it) => it.span(),
Self::JSDocNonNullableType(it) => it.span(),
Self::JSDocUnknownType(it) => it.span(),

View file

@ -2815,6 +2815,7 @@ pub mod walk {
TSType::TSTypeQuery(ty) => visitor.visit_ts_type_query(ty),
TSType::TSTypeReference(ty) => visitor.visit_ts_type_reference(ty),
TSType::TSUnionType(ty) => visitor.visit_ts_union_type(ty),
TSType::TSParenthesizedType(ty) => visitor.visit_ts_type(&ty.type_annotation),
// JSDoc
TSType::JSDocNullableType(_)
| TSType::JSDocNonNullableType(_)

View file

@ -2670,6 +2670,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSType<'a> {
Self::TSArrayType(ty) => ty.gen(p, ctx),
Self::TSTupleType(ty) => ty.gen(p, ctx),
Self::TSUnionType(ty) => ty.gen(p, ctx),
Self::TSParenthesizedType(ty) => ty.gen(p, ctx),
Self::TSIntersectionType(ty) => ty.gen(p, ctx),
Self::TSConditionalType(ty) => ty.gen(p, ctx),
Self::TSInferType(ty) => ty.gen(p, ctx),
@ -2708,9 +2709,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSType<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSArrayType<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.print_str(b"(");
self.element_type.gen(p, ctx);
p.print_str(b")[]");
p.print_str(b"[]");
}
}
@ -2728,18 +2728,22 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSUnionType<'a> {
self.types[0].gen(p, ctx);
return;
}
p.print_str(b"(");
for (index, item) in self.types.iter().enumerate() {
if index != 0 {
p.print_soft_space();
p.print_str(b"|");
p.print_soft_space();
}
p.print_str(b"(");
item.gen(p, ctx);
p.print_str(b")");
}
p.print_str(b")");
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSParenthesizedType<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.print(b'(');
self.type_annotation.gen(p, ctx);
p.print(b')');
}
}
@ -2749,28 +2753,23 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSIntersectionType<'a> {
self.types[0].gen(p, ctx);
return;
}
p.print_str(b"(");
for (index, item) in self.types.iter().enumerate() {
if index != 0 {
p.print_soft_space();
p.print_str(b"&");
p.print_soft_space();
}
p.print_str(b"(");
item.gen(p, ctx);
p.print_str(b")");
}
p.print_str(b")");
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSConditionalType<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.check_type.gen(p, ctx);
p.print_str(b" extends (");
p.print_str(b" extends ");
self.extends_type.gen(p, ctx);
p.print_str(b") ? ");
p.print_str(b" ? ");
self.true_type.gen(p, ctx);
p.print_str(b" : ");
self.false_type.gen(p, ctx);

View file

@ -147,7 +147,7 @@ fn typescript() {
test_ts(
"let x: string[] = ['abc', 'def', 'ghi'];",
"let x: (string)[] = ['abc', 'def', 'ghi'];\n",
"let x: string[] = ['abc', 'def', 'ghi'];\n",
false,
);
test_ts(
@ -160,8 +160,8 @@ fn typescript() {
"let x: [string, number] = ['abc', 123];\n",
false,
);
test_ts("let x: string | number = 'abc';", "let x: ((string) | (number)) = 'abc';\n", false);
test_ts("let x: string & number = 'abc';", "let x: ((string) & (number)) = 'abc';\n", false);
test_ts("let x: string | number = 'abc';", "let x: string | number = 'abc';\n", false);
test_ts("let x: string & number = 'abc';", "let x: string & number = 'abc';\n", false);
test_ts("let x: typeof String = 'string';", "let x: typeof String = 'string';\n", false);
test_ts("let x: keyof string = 'length';", "let x: keyof string = 'length';\n", false);
test_ts(

View file

@ -5,7 +5,7 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/infer-return-type.ts
==================== .D.TS ====================
declare function foo(): number;
declare function bar(): ((number) | (undefined));
declare function bar(): number | undefined;
declare function baz();
declare function qux(): string;

View file

@ -5,4 +5,4 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly.ts
==================== .D.TS ====================
export declare const EMPTY_OBJ: {readonly [key: string]: any};
export declare const EMPTY_ARR: readonly (never)[];
export declare const EMPTY_ARR: readonly never[];

View file

@ -182,6 +182,7 @@ fn check_and_report_error_generic(
if matches!(config, ArrayOption::Array) {
return;
}
let type_param = type_param.without_parenthesized();
if matches!(config, ArrayOption::ArraySimple) && is_simple_type(type_param) {
return;
}

View file

@ -889,10 +889,11 @@ impl<'a> ParserImpl<'a> {
}
fn parse_parenthesized_type(&mut self) -> Result<TSType<'a>> {
let span = self.start_span();
self.bump_any(); // bump `(`
let result = self.parse_ts_type()?;
let ty = self.parse_ts_type()?;
self.expect(Kind::RParen)?;
Ok(result)
Ok(self.ast.ts_parenthesized_type(self.end_span(span), ty))
}
fn parse_literal_type_node(&mut self, negative: bool) -> Result<TSType<'a>> {

View file

@ -686,6 +686,7 @@ impl<'a> Format<'a> for TSType<'a> {
TSType::TSTypeQuery(v) => v.format(p),
TSType::TSTypeReference(v) => v.format(p),
TSType::TSUnionType(v) => v.format(p),
TSType::TSParenthesizedType(v) => v.format(p),
TSType::JSDocNullableType(v) => v.format(p),
TSType::JSDocNonNullableType(v) => v.format(p),
TSType::JSDocUnknownType(v) => v.format(p),
@ -920,6 +921,12 @@ impl<'a> Format<'a> for TSTypeReference<'a> {
}
}
impl<'a> Format<'a> for TSParenthesizedType<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
wrap!(p, self, TSParenthesizedType, { self.type_annotation.format(p) })
}
}
impl<'a> Format<'a> for TSUnionType<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()

View file

@ -230,99 +230,100 @@ pub(crate) enum AncestorType {
TSConditionalTypeFalseType = 198,
TSUnionTypeTypes = 199,
TSIntersectionTypeTypes = 200,
TSTypeOperatorTypeAnnotation = 201,
TSArrayTypeElementType = 202,
TSIndexedAccessTypeObjectType = 203,
TSIndexedAccessTypeIndexType = 204,
TSTupleTypeElementTypes = 205,
TSNamedTupleMemberElementType = 206,
TSNamedTupleMemberLabel = 207,
TSOptionalTypeTypeAnnotation = 208,
TSRestTypeTypeAnnotation = 209,
TSTypeReferenceTypeName = 210,
TSTypeReferenceTypeParameters = 211,
TSQualifiedNameLeft = 212,
TSQualifiedNameRight = 213,
TSTypeParameterInstantiationParams = 214,
TSTypeParameterName = 215,
TSTypeParameterConstraint = 216,
TSTypeParameterDefault = 217,
TSTypeParameterDeclarationParams = 218,
TSTypeAliasDeclarationId = 219,
TSTypeAliasDeclarationTypeAnnotation = 220,
TSTypeAliasDeclarationTypeParameters = 221,
TSClassImplementsExpression = 222,
TSClassImplementsTypeParameters = 223,
TSInterfaceDeclarationId = 224,
TSInterfaceDeclarationBody = 225,
TSInterfaceDeclarationTypeParameters = 226,
TSInterfaceDeclarationExtends = 227,
TSInterfaceBodyBody = 228,
TSPropertySignatureKey = 229,
TSPropertySignatureTypeAnnotation = 230,
TSIndexSignatureParameters = 231,
TSIndexSignatureTypeAnnotation = 232,
TSCallSignatureDeclarationThisParam = 233,
TSCallSignatureDeclarationParams = 234,
TSCallSignatureDeclarationReturnType = 235,
TSCallSignatureDeclarationTypeParameters = 236,
TSMethodSignatureKey = 237,
TSMethodSignatureThisParam = 238,
TSMethodSignatureParams = 239,
TSMethodSignatureReturnType = 240,
TSMethodSignatureTypeParameters = 241,
TSConstructSignatureDeclarationParams = 242,
TSConstructSignatureDeclarationReturnType = 243,
TSConstructSignatureDeclarationTypeParameters = 244,
TSIndexSignatureNameTypeAnnotation = 245,
TSInterfaceHeritageExpression = 246,
TSInterfaceHeritageTypeParameters = 247,
TSTypePredicateParameterName = 248,
TSTypePredicateTypeAnnotation = 249,
TSModuleDeclarationId = 250,
TSModuleDeclarationBody = 251,
TSModuleBlockDirectives = 252,
TSModuleBlockBody = 253,
TSTypeLiteralMembers = 254,
TSInferTypeTypeParameter = 255,
TSTypeQueryExprName = 256,
TSTypeQueryTypeParameters = 257,
TSImportTypeParameter = 258,
TSImportTypeQualifier = 259,
TSImportTypeAttributes = 260,
TSImportTypeTypeParameters = 261,
TSImportAttributesElements = 262,
TSImportAttributeName = 263,
TSImportAttributeValue = 264,
TSFunctionTypeThisParam = 265,
TSFunctionTypeParams = 266,
TSFunctionTypeReturnType = 267,
TSFunctionTypeTypeParameters = 268,
TSConstructorTypeParams = 269,
TSConstructorTypeReturnType = 270,
TSConstructorTypeTypeParameters = 271,
TSMappedTypeTypeParameter = 272,
TSMappedTypeNameType = 273,
TSMappedTypeTypeAnnotation = 274,
TSTemplateLiteralTypeQuasis = 275,
TSTemplateLiteralTypeTypes = 276,
TSAsExpressionExpression = 277,
TSAsExpressionTypeAnnotation = 278,
TSSatisfiesExpressionExpression = 279,
TSSatisfiesExpressionTypeAnnotation = 280,
TSTypeAssertionExpression = 281,
TSTypeAssertionTypeAnnotation = 282,
TSImportEqualsDeclarationId = 283,
TSImportEqualsDeclarationModuleReference = 284,
TSExternalModuleReferenceExpression = 285,
TSNonNullExpressionExpression = 286,
DecoratorExpression = 287,
TSExportAssignmentExpression = 288,
TSNamespaceExportDeclarationId = 289,
TSInstantiationExpressionExpression = 290,
TSInstantiationExpressionTypeParameters = 291,
JSDocNullableTypeTypeAnnotation = 292,
JSDocNonNullableTypeTypeAnnotation = 293,
TSParenthesizedTypeTypeAnnotation = 201,
TSTypeOperatorTypeAnnotation = 202,
TSArrayTypeElementType = 203,
TSIndexedAccessTypeObjectType = 204,
TSIndexedAccessTypeIndexType = 205,
TSTupleTypeElementTypes = 206,
TSNamedTupleMemberElementType = 207,
TSNamedTupleMemberLabel = 208,
TSOptionalTypeTypeAnnotation = 209,
TSRestTypeTypeAnnotation = 210,
TSTypeReferenceTypeName = 211,
TSTypeReferenceTypeParameters = 212,
TSQualifiedNameLeft = 213,
TSQualifiedNameRight = 214,
TSTypeParameterInstantiationParams = 215,
TSTypeParameterName = 216,
TSTypeParameterConstraint = 217,
TSTypeParameterDefault = 218,
TSTypeParameterDeclarationParams = 219,
TSTypeAliasDeclarationId = 220,
TSTypeAliasDeclarationTypeAnnotation = 221,
TSTypeAliasDeclarationTypeParameters = 222,
TSClassImplementsExpression = 223,
TSClassImplementsTypeParameters = 224,
TSInterfaceDeclarationId = 225,
TSInterfaceDeclarationBody = 226,
TSInterfaceDeclarationTypeParameters = 227,
TSInterfaceDeclarationExtends = 228,
TSInterfaceBodyBody = 229,
TSPropertySignatureKey = 230,
TSPropertySignatureTypeAnnotation = 231,
TSIndexSignatureParameters = 232,
TSIndexSignatureTypeAnnotation = 233,
TSCallSignatureDeclarationThisParam = 234,
TSCallSignatureDeclarationParams = 235,
TSCallSignatureDeclarationReturnType = 236,
TSCallSignatureDeclarationTypeParameters = 237,
TSMethodSignatureKey = 238,
TSMethodSignatureThisParam = 239,
TSMethodSignatureParams = 240,
TSMethodSignatureReturnType = 241,
TSMethodSignatureTypeParameters = 242,
TSConstructSignatureDeclarationParams = 243,
TSConstructSignatureDeclarationReturnType = 244,
TSConstructSignatureDeclarationTypeParameters = 245,
TSIndexSignatureNameTypeAnnotation = 246,
TSInterfaceHeritageExpression = 247,
TSInterfaceHeritageTypeParameters = 248,
TSTypePredicateParameterName = 249,
TSTypePredicateTypeAnnotation = 250,
TSModuleDeclarationId = 251,
TSModuleDeclarationBody = 252,
TSModuleBlockDirectives = 253,
TSModuleBlockBody = 254,
TSTypeLiteralMembers = 255,
TSInferTypeTypeParameter = 256,
TSTypeQueryExprName = 257,
TSTypeQueryTypeParameters = 258,
TSImportTypeParameter = 259,
TSImportTypeQualifier = 260,
TSImportTypeAttributes = 261,
TSImportTypeTypeParameters = 262,
TSImportAttributesElements = 263,
TSImportAttributeName = 264,
TSImportAttributeValue = 265,
TSFunctionTypeThisParam = 266,
TSFunctionTypeParams = 267,
TSFunctionTypeReturnType = 268,
TSFunctionTypeTypeParameters = 269,
TSConstructorTypeParams = 270,
TSConstructorTypeReturnType = 271,
TSConstructorTypeTypeParameters = 272,
TSMappedTypeTypeParameter = 273,
TSMappedTypeNameType = 274,
TSMappedTypeTypeAnnotation = 275,
TSTemplateLiteralTypeQuasis = 276,
TSTemplateLiteralTypeTypes = 277,
TSAsExpressionExpression = 278,
TSAsExpressionTypeAnnotation = 279,
TSSatisfiesExpressionExpression = 280,
TSSatisfiesExpressionTypeAnnotation = 281,
TSTypeAssertionExpression = 282,
TSTypeAssertionTypeAnnotation = 283,
TSImportEqualsDeclarationId = 284,
TSImportEqualsDeclarationModuleReference = 285,
TSExternalModuleReferenceExpression = 286,
TSNonNullExpressionExpression = 287,
DecoratorExpression = 288,
TSExportAssignmentExpression = 289,
TSNamespaceExportDeclarationId = 290,
TSInstantiationExpressionExpression = 291,
TSInstantiationExpressionTypeParameters = 292,
JSDocNullableTypeTypeAnnotation = 293,
JSDocNonNullableTypeTypeAnnotation = 294,
}
/// Ancestor type used in AST traversal.
@ -683,6 +684,8 @@ pub enum Ancestor<'a> {
TSUnionTypeTypes(TSUnionTypeWithoutTypes<'a>) = AncestorType::TSUnionTypeTypes as u16,
TSIntersectionTypeTypes(TSIntersectionTypeWithoutTypes<'a>) =
AncestorType::TSIntersectionTypeTypes as u16,
TSParenthesizedTypeTypeAnnotation(TSParenthesizedTypeWithoutTypeAnnotation<'a>) =
AncestorType::TSParenthesizedTypeTypeAnnotation as u16,
TSTypeOperatorTypeAnnotation(TSTypeOperatorWithoutTypeAnnotation<'a>) =
AncestorType::TSTypeOperatorTypeAnnotation as u16,
TSArrayTypeElementType(TSArrayTypeWithoutElementType<'a>) =
@ -1511,6 +1514,11 @@ impl<'a> Ancestor<'a> {
matches!(self, Self::TSIntersectionTypeTypes(_))
}
#[inline]
pub fn is_ts_parenthesized_type(&self) -> bool {
matches!(self, Self::TSParenthesizedTypeTypeAnnotation(_))
}
#[inline]
pub fn is_ts_type_operator(&self) -> bool {
matches!(self, Self::TSTypeOperatorTypeAnnotation(_))
@ -2088,6 +2096,7 @@ impl<'a> Ancestor<'a> {
| Self::TSConditionalTypeFalseType(_)
| Self::TSUnionTypeTypes(_)
| Self::TSIntersectionTypeTypes(_)
| Self::TSParenthesizedTypeTypeAnnotation(_)
| Self::TSTypeOperatorTypeAnnotation(_)
| Self::TSArrayTypeElementType(_)
| Self::TSIndexedAccessTypeObjectType(_)
@ -8996,6 +9005,21 @@ impl<'a> TSIntersectionTypeWithoutTypes<'a> {
}
}
pub(crate) const OFFSET_TS_PARENTHESIZED_TYPE_SPAN: usize = offset_of!(TSParenthesizedType, span);
pub(crate) const OFFSET_TS_PARENTHESIZED_TYPE_TYPE_ANNOTATION: usize =
offset_of!(TSParenthesizedType, type_annotation);
#[repr(transparent)]
#[derive(Debug)]
pub struct TSParenthesizedTypeWithoutTypeAnnotation<'a>(pub(crate) *const TSParenthesizedType<'a>);
impl<'a> TSParenthesizedTypeWithoutTypeAnnotation<'a> {
#[inline]
pub fn span(&self) -> &Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_TS_PARENTHESIZED_TYPE_SPAN) as *const Span) }
}
}
pub(crate) const OFFSET_TS_TYPE_OPERATOR_SPAN: usize = offset_of!(TSTypeOperator, span);
pub(crate) const OFFSET_TS_TYPE_OPERATOR_OPERATOR: usize = offset_of!(TSTypeOperator, operator);
pub(crate) const OFFSET_TS_TYPE_OPERATOR_TYPE_ANNOTATION: usize =

View file

@ -1638,6 +1638,21 @@ pub trait Traverse<'a> {
) {
}
#[inline]
fn enter_ts_parenthesized_type(
&mut self,
node: &mut TSParenthesizedType<'a>,
ctx: &mut TraverseCtx<'a>,
) {
}
#[inline]
fn exit_ts_parenthesized_type(
&mut self,
node: &mut TSParenthesizedType<'a>,
ctx: &mut TraverseCtx<'a>,
) {
}
#[inline]
fn enter_ts_type_operator(&mut self, node: &mut TSTypeOperator<'a>, ctx: &mut TraverseCtx<'a>) {
}

View file

@ -3896,6 +3896,9 @@ pub(crate) unsafe fn walk_ts_type<'a, Tr: Traverse<'a>>(
walk_ts_type_reference(traverser, (&mut **node) as *mut _, ctx)
}
TSType::TSUnionType(node) => walk_ts_union_type(traverser, (&mut **node) as *mut _, ctx),
TSType::TSParenthesizedType(node) => {
walk_ts_parenthesized_type(traverser, (&mut **node) as *mut _, ctx)
}
TSType::JSDocNullableType(node) => {
walk_js_doc_nullable_type(traverser, (&mut **node) as *mut _, ctx)
}
@ -3980,6 +3983,25 @@ pub(crate) unsafe fn walk_ts_intersection_type<'a, Tr: Traverse<'a>>(
traverser.exit_ts_intersection_type(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_parenthesized_type<'a, Tr: Traverse<'a>>(
traverser: &mut Tr,
node: *mut TSParenthesizedType<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_parenthesized_type(&mut *node, ctx);
ctx.push_stack(Ancestor::TSParenthesizedTypeTypeAnnotation(
ancestor::TSParenthesizedTypeWithoutTypeAnnotation(node),
));
walk_ts_type(
traverser,
(node as *mut u8).add(ancestor::OFFSET_TS_PARENTHESIZED_TYPE_TYPE_ANNOTATION)
as *mut TSType,
ctx,
);
ctx.pop_stack();
traverser.exit_ts_parenthesized_type(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_type_operator<'a, Tr: Traverse<'a>>(
traverser: &mut Tr,
node: *mut TSTypeOperator<'a>,
@ -4165,6 +4187,7 @@ pub(crate) unsafe fn walk_ts_tuple_element<'a, Tr: Traverse<'a>>(
| TSTupleElement::TSTypeQuery(_)
| TSTupleElement::TSTypeReference(_)
| TSTupleElement::TSUnionType(_)
| TSTupleElement::TSParenthesizedType(_)
| TSTupleElement::JSDocNullableType(_)
| TSTupleElement::JSDocNonNullableType(_)
| TSTupleElement::JSDocUnknownType(_) => walk_ts_type(traverser, node as *mut _, ctx),