diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 5811da2d9c72b..d18389f538439 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -2277,8 +2277,14 @@ pub struct AccessorProperty<'a> { pub key: PropertyKey<'a>, /// Initialized value in the declaration, if present. pub value: Option>, + /// Property was declared with a computed key pub computed: bool, + /// Property was declared with a `static` modifier pub r#static: bool, + /// Type annotation on the property. + /// + /// Will only ever be [`Some`] for TypeScript files. + pub type_annotation: Option>>, } #[ast(visit)] diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index e80b81e2f8f20..e689ef636c567 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -687,7 +687,7 @@ const _: () = { assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); - assert!(size_of::() == 88usize); + assert!(size_of::() == 96usize); assert!(align_of::() == 8usize); assert!(offset_of!(AccessorProperty, r#type) == 0usize); assert!(offset_of!(AccessorProperty, span) == 4usize); @@ -696,6 +696,7 @@ const _: () = { assert!(offset_of!(AccessorProperty, value) == 64usize); assert!(offset_of!(AccessorProperty, computed) == 80usize); assert!(offset_of!(AccessorProperty, r#static) == 81usize); + assert!(offset_of!(AccessorProperty, type_annotation) == 88usize); assert!(size_of::() == 56usize); assert!(align_of::() == 8usize); @@ -2091,7 +2092,7 @@ const _: () = { assert!(size_of::() == 1usize); assert!(align_of::() == 1usize); - assert!(size_of::() == 48usize); + assert!(size_of::() == 52usize); assert!(align_of::() == 4usize); assert!(offset_of!(AccessorProperty, r#type) == 0usize); assert!(offset_of!(AccessorProperty, span) == 4usize); @@ -2100,6 +2101,7 @@ const _: () = { assert!(offset_of!(AccessorProperty, value) == 36usize); assert!(offset_of!(AccessorProperty, computed) == 44usize); assert!(offset_of!(AccessorProperty, r#static) == 45usize); + assert!(offset_of!(AccessorProperty, type_annotation) == 48usize); assert!(size_of::() == 32usize); assert!(align_of::() == 4usize); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 2af319881ae15..6b5c325ea0cb2 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -6494,10 +6494,11 @@ impl<'a> AstBuilder<'a> { /// - decorators: Decorators applied to the accessor property. /// - key: The expression used to declare the property. /// - value: Initialized value in the declaration, if present. - /// - computed - /// - r#static + /// - computed: Property was declared with a computed key + /// - r#static: Property was declared with a `static` modifier + /// - type_annotation: Type annotation on the property. #[inline] - pub fn class_element_accessor_property( + pub fn class_element_accessor_property( self, r#type: AccessorPropertyType, span: Span, @@ -6506,10 +6507,21 @@ impl<'a> AstBuilder<'a> { value: Option>, computed: bool, r#static: bool, - ) -> ClassElement<'a> { - ClassElement::AccessorProperty(self.alloc( - self.accessor_property(r#type, span, decorators, key, value, computed, r#static), - )) + type_annotation: T1, + ) -> ClassElement<'a> + where + T1: IntoIn<'a, Option>>>, + { + ClassElement::AccessorProperty(self.alloc(self.accessor_property( + r#type, + span, + decorators, + key, + value, + computed, + r#static, + type_annotation, + ))) } /// Convert a [`AccessorProperty`] into a [`ClassElement::AccessorProperty`] @@ -7057,10 +7069,11 @@ impl<'a> AstBuilder<'a> { /// - decorators: Decorators applied to the accessor property. /// - key: The expression used to declare the property. /// - value: Initialized value in the declaration, if present. - /// - computed - /// - r#static + /// - computed: Property was declared with a computed key + /// - r#static: Property was declared with a `static` modifier + /// - type_annotation: Type annotation on the property. #[inline] - pub fn accessor_property( + pub fn accessor_property( self, r#type: AccessorPropertyType, span: Span, @@ -7069,8 +7082,21 @@ impl<'a> AstBuilder<'a> { value: Option>, computed: bool, r#static: bool, - ) -> AccessorProperty<'a> { - AccessorProperty { r#type, span, decorators, key, value, computed, r#static } + type_annotation: T1, + ) -> AccessorProperty<'a> + where + T1: IntoIn<'a, Option>>>, + { + AccessorProperty { + r#type, + span, + decorators, + key, + value, + computed, + r#static, + type_annotation: type_annotation.into_in(self.allocator), + } } /// Builds a [`AccessorProperty`] and stores it in the memory arena. @@ -7083,10 +7109,11 @@ impl<'a> AstBuilder<'a> { /// - decorators: Decorators applied to the accessor property. /// - key: The expression used to declare the property. /// - value: Initialized value in the declaration, if present. - /// - computed - /// - r#static + /// - computed: Property was declared with a computed key + /// - r#static: Property was declared with a `static` modifier + /// - type_annotation: Type annotation on the property. #[inline] - pub fn alloc_accessor_property( + pub fn alloc_accessor_property( self, r#type: AccessorPropertyType, span: Span, @@ -7095,9 +7122,22 @@ impl<'a> AstBuilder<'a> { value: Option>, computed: bool, r#static: bool, - ) -> Box<'a, AccessorProperty<'a>> { + type_annotation: T1, + ) -> Box<'a, AccessorProperty<'a>> + where + T1: IntoIn<'a, Option>>>, + { Box::new_in( - self.accessor_property(r#type, span, decorators, key, value, computed, r#static), + self.accessor_property( + r#type, + span, + decorators, + key, + value, + computed, + r#static, + type_annotation, + ), self.allocator, ) } diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs index ae8baed266eae..fc5b279277869 100644 --- a/crates/oxc_ast/src/generated/derive_clone_in.rs +++ b/crates/oxc_ast/src/generated/derive_clone_in.rs @@ -1954,6 +1954,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for AccessorProperty<'old_alloc value: self.value.clone_in(allocator), computed: self.computed.clone_in(allocator), r#static: self.r#static.clone_in(allocator), + type_annotation: self.type_annotation.clone_in(allocator), } } } diff --git a/crates/oxc_ast/src/generated/visit.rs b/crates/oxc_ast/src/generated/visit.rs index 9c0268a716677..f919444596d4e 100644 --- a/crates/oxc_ast/src/generated/visit.rs +++ b/crates/oxc_ast/src/generated/visit.rs @@ -3110,6 +3110,9 @@ pub mod walk { if let Some(value) = &it.value { visitor.visit_expression(value); } + if let Some(type_annotation) = &it.type_annotation { + visitor.visit_ts_type_annotation(type_annotation); + } } #[inline] diff --git a/crates/oxc_ast/src/generated/visit_mut.rs b/crates/oxc_ast/src/generated/visit_mut.rs index 6dd5f3d985b7f..a39595fde8f80 100644 --- a/crates/oxc_ast/src/generated/visit_mut.rs +++ b/crates/oxc_ast/src/generated/visit_mut.rs @@ -3253,6 +3253,9 @@ pub mod walk_mut { if let Some(value) = &mut it.value { visitor.visit_expression(value); } + if let Some(type_annotation) = &mut it.type_annotation { + visitor.visit_ts_type_annotation(type_annotation); + } } #[inline] diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index 319477913d21c..58bffaa898afd 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -469,6 +469,8 @@ impl<'a> IsolatedDeclarations<'a> { None, property.computed, property.r#static, + // SAFETY: `ast.copy` is unsound! We need to fix. + unsafe { self.ast.copy(&property.type_annotation) }, ); elements.push(new_element); } diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index 363a3b3475cb9..427cd51ef2f5f 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -281,7 +281,6 @@ impl<'a> ParserImpl<'a> { } if accessor { - self.parse_ts_type_annotation()?; self.parse_class_accessor_property(span, key, computed, r#static, r#abstract).map(Some) } else if self.at(Kind::LParen) || self.at(Kind::LAngle) || r#async || generator { // LAngle for start of type parameters `foo` @@ -479,6 +478,8 @@ impl<'a> ParserImpl<'a> { r#static: bool, r#abstract: bool, ) -> Result> { + let type_annotation = + if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None }; let value = self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()).transpose()?; let r#type = if r#abstract { @@ -496,6 +497,7 @@ impl<'a> ParserImpl<'a> { value, computed, r#static, + type_annotation, )) } } diff --git a/crates/oxc_semantic/tests/integration/symbols.rs b/crates/oxc_semantic/tests/integration/symbols.rs index 64c6382238f1f..baef2aa92d7f7 100644 --- a/crates/oxc_semantic/tests/integration/symbols.rs +++ b/crates/oxc_semantic/tests/integration/symbols.rs @@ -230,6 +230,23 @@ fn test_class_with_type_parameter() { tester.has_symbol("B").has_number_of_references(0).test(); } +#[test] +fn test_class_with_accessor() { + SemanticTester::ts( + " + type T = 1; + + abstract class Foo { + accessor prop: T; + } + ", + ) + .has_some_symbol("T") + .has_number_of_references(1) + .has_number_of_references_where(1, Reference::is_type) + .test(); +} + #[test] fn test_ts_mapped_type() { let tester = SemanticTester::ts( diff --git a/crates/oxc_traverse/src/generated/ancestor.rs b/crates/oxc_traverse/src/generated/ancestor.rs index 244d803976593..5f91d1e5ca78d 100644 --- a/crates/oxc_traverse/src/generated/ancestor.rs +++ b/crates/oxc_traverse/src/generated/ancestor.rs @@ -171,156 +171,157 @@ pub(crate) enum AncestorType { AccessorPropertyDecorators = 143, AccessorPropertyKey = 144, AccessorPropertyValue = 145, - ImportExpressionSource = 146, - ImportExpressionArguments = 147, - ImportDeclarationSpecifiers = 148, - ImportDeclarationSource = 149, - ImportDeclarationWithClause = 150, - ImportSpecifierImported = 151, - ImportSpecifierLocal = 152, - ImportDefaultSpecifierLocal = 153, - ImportNamespaceSpecifierLocal = 154, - WithClauseAttributesKeyword = 155, - WithClauseWithEntries = 156, - ImportAttributeKey = 157, - ImportAttributeValue = 158, - ExportNamedDeclarationDeclaration = 159, - ExportNamedDeclarationSpecifiers = 160, - ExportNamedDeclarationSource = 161, - ExportNamedDeclarationWithClause = 162, - ExportDefaultDeclarationDeclaration = 163, - ExportDefaultDeclarationExported = 164, - ExportAllDeclarationExported = 165, - ExportAllDeclarationSource = 166, - ExportAllDeclarationWithClause = 167, - ExportSpecifierLocal = 168, - ExportSpecifierExported = 169, - JSXElementOpeningElement = 170, - JSXElementClosingElement = 171, - JSXElementChildren = 172, - JSXOpeningElementName = 173, - JSXOpeningElementAttributes = 174, - JSXOpeningElementTypeParameters = 175, - JSXClosingElementName = 176, - JSXFragmentChildren = 177, - JSXNamespacedNameNamespace = 178, - JSXNamespacedNameProperty = 179, - JSXMemberExpressionObject = 180, - JSXMemberExpressionProperty = 181, - JSXExpressionContainerExpression = 182, - JSXAttributeName = 183, - JSXAttributeValue = 184, - JSXSpreadAttributeArgument = 185, - JSXSpreadChildExpression = 186, - TSThisParameterThis = 187, - TSThisParameterTypeAnnotation = 188, - TSEnumDeclarationId = 189, - TSEnumDeclarationMembers = 190, - TSEnumMemberId = 191, - TSEnumMemberInitializer = 192, - TSTypeAnnotationTypeAnnotation = 193, - TSLiteralTypeLiteral = 194, - TSConditionalTypeCheckType = 195, - TSConditionalTypeExtendsType = 196, - TSConditionalTypeTrueType = 197, - TSConditionalTypeFalseType = 198, - TSUnionTypeTypes = 199, - TSIntersectionTypeTypes = 200, - 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, - TSTypeAliasDeclarationTypeParameters = 221, - TSTypeAliasDeclarationTypeAnnotation = 222, - TSClassImplementsExpression = 223, - TSClassImplementsTypeParameters = 224, - TSInterfaceDeclarationId = 225, - TSInterfaceDeclarationExtends = 226, - TSInterfaceDeclarationTypeParameters = 227, - TSInterfaceDeclarationBody = 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, - TSImportAttributesAttributesKeyword = 263, - TSImportAttributesElements = 264, - TSImportAttributeName = 265, - TSImportAttributeValue = 266, - TSFunctionTypeThisParam = 267, - TSFunctionTypeParams = 268, - TSFunctionTypeReturnType = 269, - TSFunctionTypeTypeParameters = 270, - TSConstructorTypeParams = 271, - TSConstructorTypeReturnType = 272, - TSConstructorTypeTypeParameters = 273, - TSMappedTypeTypeParameter = 274, - TSMappedTypeNameType = 275, - TSMappedTypeTypeAnnotation = 276, - TSTemplateLiteralTypeQuasis = 277, - TSTemplateLiteralTypeTypes = 278, - TSAsExpressionExpression = 279, - TSAsExpressionTypeAnnotation = 280, - TSSatisfiesExpressionExpression = 281, - TSSatisfiesExpressionTypeAnnotation = 282, - TSTypeAssertionExpression = 283, - TSTypeAssertionTypeAnnotation = 284, - TSImportEqualsDeclarationId = 285, - TSImportEqualsDeclarationModuleReference = 286, - TSExternalModuleReferenceExpression = 287, - TSNonNullExpressionExpression = 288, - DecoratorExpression = 289, - TSExportAssignmentExpression = 290, - TSNamespaceExportDeclarationId = 291, - TSInstantiationExpressionExpression = 292, - TSInstantiationExpressionTypeParameters = 293, - JSDocNullableTypeTypeAnnotation = 294, - JSDocNonNullableTypeTypeAnnotation = 295, + AccessorPropertyTypeAnnotation = 146, + ImportExpressionSource = 147, + ImportExpressionArguments = 148, + ImportDeclarationSpecifiers = 149, + ImportDeclarationSource = 150, + ImportDeclarationWithClause = 151, + ImportSpecifierImported = 152, + ImportSpecifierLocal = 153, + ImportDefaultSpecifierLocal = 154, + ImportNamespaceSpecifierLocal = 155, + WithClauseAttributesKeyword = 156, + WithClauseWithEntries = 157, + ImportAttributeKey = 158, + ImportAttributeValue = 159, + ExportNamedDeclarationDeclaration = 160, + ExportNamedDeclarationSpecifiers = 161, + ExportNamedDeclarationSource = 162, + ExportNamedDeclarationWithClause = 163, + ExportDefaultDeclarationDeclaration = 164, + ExportDefaultDeclarationExported = 165, + ExportAllDeclarationExported = 166, + ExportAllDeclarationSource = 167, + ExportAllDeclarationWithClause = 168, + ExportSpecifierLocal = 169, + ExportSpecifierExported = 170, + JSXElementOpeningElement = 171, + JSXElementClosingElement = 172, + JSXElementChildren = 173, + JSXOpeningElementName = 174, + JSXOpeningElementAttributes = 175, + JSXOpeningElementTypeParameters = 176, + JSXClosingElementName = 177, + JSXFragmentChildren = 178, + JSXNamespacedNameNamespace = 179, + JSXNamespacedNameProperty = 180, + JSXMemberExpressionObject = 181, + JSXMemberExpressionProperty = 182, + JSXExpressionContainerExpression = 183, + JSXAttributeName = 184, + JSXAttributeValue = 185, + JSXSpreadAttributeArgument = 186, + JSXSpreadChildExpression = 187, + TSThisParameterThis = 188, + TSThisParameterTypeAnnotation = 189, + TSEnumDeclarationId = 190, + TSEnumDeclarationMembers = 191, + TSEnumMemberId = 192, + TSEnumMemberInitializer = 193, + TSTypeAnnotationTypeAnnotation = 194, + TSLiteralTypeLiteral = 195, + TSConditionalTypeCheckType = 196, + TSConditionalTypeExtendsType = 197, + TSConditionalTypeTrueType = 198, + TSConditionalTypeFalseType = 199, + TSUnionTypeTypes = 200, + TSIntersectionTypeTypes = 201, + TSParenthesizedTypeTypeAnnotation = 202, + TSTypeOperatorTypeAnnotation = 203, + TSArrayTypeElementType = 204, + TSIndexedAccessTypeObjectType = 205, + TSIndexedAccessTypeIndexType = 206, + TSTupleTypeElementTypes = 207, + TSNamedTupleMemberElementType = 208, + TSNamedTupleMemberLabel = 209, + TSOptionalTypeTypeAnnotation = 210, + TSRestTypeTypeAnnotation = 211, + TSTypeReferenceTypeName = 212, + TSTypeReferenceTypeParameters = 213, + TSQualifiedNameLeft = 214, + TSQualifiedNameRight = 215, + TSTypeParameterInstantiationParams = 216, + TSTypeParameterName = 217, + TSTypeParameterConstraint = 218, + TSTypeParameterDefault = 219, + TSTypeParameterDeclarationParams = 220, + TSTypeAliasDeclarationId = 221, + TSTypeAliasDeclarationTypeParameters = 222, + TSTypeAliasDeclarationTypeAnnotation = 223, + TSClassImplementsExpression = 224, + TSClassImplementsTypeParameters = 225, + TSInterfaceDeclarationId = 226, + TSInterfaceDeclarationExtends = 227, + TSInterfaceDeclarationTypeParameters = 228, + TSInterfaceDeclarationBody = 229, + TSInterfaceBodyBody = 230, + TSPropertySignatureKey = 231, + TSPropertySignatureTypeAnnotation = 232, + TSIndexSignatureParameters = 233, + TSIndexSignatureTypeAnnotation = 234, + TSCallSignatureDeclarationThisParam = 235, + TSCallSignatureDeclarationParams = 236, + TSCallSignatureDeclarationReturnType = 237, + TSCallSignatureDeclarationTypeParameters = 238, + TSMethodSignatureKey = 239, + TSMethodSignatureThisParam = 240, + TSMethodSignatureParams = 241, + TSMethodSignatureReturnType = 242, + TSMethodSignatureTypeParameters = 243, + TSConstructSignatureDeclarationParams = 244, + TSConstructSignatureDeclarationReturnType = 245, + TSConstructSignatureDeclarationTypeParameters = 246, + TSIndexSignatureNameTypeAnnotation = 247, + TSInterfaceHeritageExpression = 248, + TSInterfaceHeritageTypeParameters = 249, + TSTypePredicateParameterName = 250, + TSTypePredicateTypeAnnotation = 251, + TSModuleDeclarationId = 252, + TSModuleDeclarationBody = 253, + TSModuleBlockDirectives = 254, + TSModuleBlockBody = 255, + TSTypeLiteralMembers = 256, + TSInferTypeTypeParameter = 257, + TSTypeQueryExprName = 258, + TSTypeQueryTypeParameters = 259, + TSImportTypeParameter = 260, + TSImportTypeQualifier = 261, + TSImportTypeAttributes = 262, + TSImportTypeTypeParameters = 263, + TSImportAttributesAttributesKeyword = 264, + TSImportAttributesElements = 265, + TSImportAttributeName = 266, + TSImportAttributeValue = 267, + TSFunctionTypeThisParam = 268, + TSFunctionTypeParams = 269, + TSFunctionTypeReturnType = 270, + TSFunctionTypeTypeParameters = 271, + TSConstructorTypeParams = 272, + TSConstructorTypeReturnType = 273, + TSConstructorTypeTypeParameters = 274, + TSMappedTypeTypeParameter = 275, + TSMappedTypeNameType = 276, + TSMappedTypeTypeAnnotation = 277, + TSTemplateLiteralTypeQuasis = 278, + TSTemplateLiteralTypeTypes = 279, + TSAsExpressionExpression = 280, + TSAsExpressionTypeAnnotation = 281, + TSSatisfiesExpressionExpression = 282, + TSSatisfiesExpressionTypeAnnotation = 283, + TSTypeAssertionExpression = 284, + TSTypeAssertionTypeAnnotation = 285, + TSImportEqualsDeclarationId = 286, + TSImportEqualsDeclarationModuleReference = 287, + TSExternalModuleReferenceExpression = 288, + TSNonNullExpressionExpression = 289, + DecoratorExpression = 290, + TSExportAssignmentExpression = 291, + TSNamespaceExportDeclarationId = 292, + TSInstantiationExpressionExpression = 293, + TSInstantiationExpressionTypeParameters = 294, + JSDocNullableTypeTypeAnnotation = 295, + JSDocNonNullableTypeTypeAnnotation = 296, } /// Ancestor type used in AST traversal. @@ -580,6 +581,8 @@ pub enum Ancestor<'a> { AccessorPropertyKey(AccessorPropertyWithoutKey<'a>) = AncestorType::AccessorPropertyKey as u16, AccessorPropertyValue(AccessorPropertyWithoutValue<'a>) = AncestorType::AccessorPropertyValue as u16, + AccessorPropertyTypeAnnotation(AccessorPropertyWithoutTypeAnnotation<'a>) = + AncestorType::AccessorPropertyTypeAnnotation as u16, ImportExpressionSource(ImportExpressionWithoutSource<'a>) = AncestorType::ImportExpressionSource as u16, ImportExpressionArguments(ImportExpressionWithoutArguments<'a>) = @@ -1329,6 +1332,7 @@ impl<'a> Ancestor<'a> { Self::AccessorPropertyDecorators(_) | Self::AccessorPropertyKey(_) | Self::AccessorPropertyValue(_) + | Self::AccessorPropertyTypeAnnotation(_) ) } @@ -7315,6 +7319,8 @@ pub(crate) const OFFSET_ACCESSOR_PROPERTY_KEY: usize = offset_of!(AccessorProper pub(crate) const OFFSET_ACCESSOR_PROPERTY_VALUE: usize = offset_of!(AccessorProperty, value); pub(crate) const OFFSET_ACCESSOR_PROPERTY_COMPUTED: usize = offset_of!(AccessorProperty, computed); pub(crate) const OFFSET_ACCESSOR_PROPERTY_STATIC: usize = offset_of!(AccessorProperty, r#static); +pub(crate) const OFFSET_ACCESSOR_PROPERTY_TYPE_ANNOTATION: usize = + offset_of!(AccessorProperty, type_annotation); #[repr(transparent)] #[derive(Debug)] @@ -7358,6 +7364,14 @@ impl<'a> AccessorPropertyWithoutDecorators<'a> { pub fn r#static(&self) -> &bool { unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_STATIC) as *const bool) } } + + #[inline] + pub fn type_annotation(&self) -> &Option>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_TYPE_ANNOTATION) + as *const Option>>) + } + } } #[repr(transparent)] @@ -7403,6 +7417,14 @@ impl<'a> AccessorPropertyWithoutKey<'a> { pub fn r#static(&self) -> &bool { unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_STATIC) as *const bool) } } + + #[inline] + pub fn type_annotation(&self) -> &Option>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_TYPE_ANNOTATION) + as *const Option>>) + } + } } #[repr(transparent)] @@ -7447,6 +7469,66 @@ impl<'a> AccessorPropertyWithoutValue<'a> { pub fn r#static(&self) -> &bool { unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_STATIC) as *const bool) } } + + #[inline] + pub fn type_annotation(&self) -> &Option>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_TYPE_ANNOTATION) + as *const Option>>) + } + } +} + +#[repr(transparent)] +#[derive(Debug)] +pub struct AccessorPropertyWithoutTypeAnnotation<'a>(pub(crate) *const AccessorProperty<'a>); + +impl<'a> AccessorPropertyWithoutTypeAnnotation<'a> { + #[inline] + pub fn r#type(&self) -> &AccessorPropertyType { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_TYPE) + as *const AccessorPropertyType) + } + } + + #[inline] + pub fn span(&self) -> &Span { + unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_SPAN) as *const Span) } + } + + #[inline] + pub fn decorators(&self) -> &Vec<'a, Decorator<'a>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_DECORATORS) + as *const Vec<'a, Decorator<'a>>) + } + } + + #[inline] + pub fn key(&self) -> &PropertyKey<'a> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_KEY) as *const PropertyKey<'a>) + } + } + + #[inline] + pub fn value(&self) -> &Option> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_VALUE) + as *const Option>) + } + } + + #[inline] + pub fn computed(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_COMPUTED) as *const bool) } + } + + #[inline] + pub fn r#static(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_ACCESSOR_PROPERTY_STATIC) as *const bool) } + } } pub(crate) const OFFSET_IMPORT_EXPRESSION_SPAN: usize = offset_of!(ImportExpression, span); diff --git a/crates/oxc_traverse/src/generated/walk.rs b/crates/oxc_traverse/src/generated/walk.rs index f90f4bcc9a54c..22b5f2b5d28bd 100644 --- a/crates/oxc_traverse/src/generated/walk.rs +++ b/crates/oxc_traverse/src/generated/walk.rs @@ -2682,6 +2682,13 @@ pub(crate) unsafe fn walk_accessor_property<'a, Tr: Traverse<'a>>( ctx.retag_stack(AncestorType::AccessorPropertyValue); walk_expression(traverser, field as *mut _, ctx); } + if let Some(field) = &mut *((node as *mut u8) + .add(ancestor::OFFSET_ACCESSOR_PROPERTY_TYPE_ANNOTATION) + as *mut Option>) + { + ctx.retag_stack(AncestorType::AccessorPropertyTypeAnnotation); + walk_ts_type_annotation(traverser, (&mut **field) as *mut _, ctx); + } ctx.pop_stack(); traverser.exit_accessor_property(&mut *node, ctx); } diff --git a/tasks/coverage/codegen_misc.snap b/tasks/coverage/codegen_misc.snap index f560e60a4b440..68945daf9caea 100644 --- a/tasks/coverage/codegen_misc.snap +++ b/tasks/coverage/codegen_misc.snap @@ -1,3 +1,3 @@ codegen_misc Summary: -AST Parsed : 26/26 (100.00%) -Positive Passed: 26/26 (100.00%) +AST Parsed : 27/27 (100.00%) +Positive Passed: 27/27 (100.00%) diff --git a/tasks/coverage/misc/fail/oxc-5177.ts b/tasks/coverage/misc/fail/oxc-5177.ts new file mode 100644 index 0000000000000..8677b03af7a04 --- /dev/null +++ b/tasks/coverage/misc/fail/oxc-5177.ts @@ -0,0 +1,5 @@ +// https://github.com/oxc-project/oxc/issues/5177 +type Foo = 'foo' | 'bar' +export class Bang { + accessor x?: Foo +} diff --git a/tasks/coverage/misc/pass/oxc-5177.ts b/tasks/coverage/misc/pass/oxc-5177.ts new file mode 100644 index 0000000000000..9ca88af7fa9ff --- /dev/null +++ b/tasks/coverage/misc/pass/oxc-5177.ts @@ -0,0 +1,6 @@ +// https://github.com/oxc-project/oxc/issues/5177 +type Foo = 'foo' | 'bar' +export class Bang { + accessor x: Foo + accessor y!: string +} diff --git a/tasks/coverage/parser_misc.snap b/tasks/coverage/parser_misc.snap index cd01bf1e4823c..79f3a915d44c8 100644 --- a/tasks/coverage/parser_misc.snap +++ b/tasks/coverage/parser_misc.snap @@ -1,7 +1,8 @@ parser_misc Summary: -AST Parsed : 26/26 (100.00%) -Positive Passed: 26/26 (100.00%) -Negative Passed: 15/15 (100.00%) +AST Parsed : 27/27 (100.00%) +Positive Passed: 27/27 (100.00%) +Negative Passed: 15/16 (93.75%) +Expect Syntax Error: tasks/coverage/misc/fail/oxc-5177.ts × Unexpected token ╭─[misc/fail/oxc-169.js:2:1] diff --git a/tasks/coverage/semantic_misc.snap b/tasks/coverage/semantic_misc.snap index a0d5eb313675f..a2349d7a71a4a 100644 --- a/tasks/coverage/semantic_misc.snap +++ b/tasks/coverage/semantic_misc.snap @@ -1,6 +1,6 @@ semantic_misc Summary: -AST Parsed : 26/26 (100.00%) -Positive Passed: 14/26 (53.85%) +AST Parsed : 27/27 (100.00%) +Positive Passed: 14/27 (51.85%) tasks/coverage/misc/pass/oxc-1288.ts semantic error: Bindings mismatch: after transform: ScopeId(0): ["from"] @@ -168,6 +168,17 @@ Symbol flags mismatch: after transform: SymbolId(10): SymbolFlags(RegularEnum) rebuilt : SymbolId(14): SymbolFlags(FunctionScopedVariable) +tasks/coverage/misc/pass/oxc-5177.ts +semantic error: Bindings mismatch: +after transform: ScopeId(0): ["Bang", "Foo"] +rebuilt : ScopeId(0): ["Bang"] +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1), ScopeId(2)] +rebuilt : ScopeId(0): [ScopeId(1)] +Unresolved references mismatch: +after transform: [] +rebuilt : ["Foo"] + tasks/coverage/misc/pass/swc-7187.ts semantic error: Bindings mismatch: after transform: ScopeId(0): ["K"] diff --git a/tasks/coverage/transformer_misc.snap b/tasks/coverage/transformer_misc.snap index f605ae970bcb9..2c1b78963439e 100644 --- a/tasks/coverage/transformer_misc.snap +++ b/tasks/coverage/transformer_misc.snap @@ -1,3 +1,3 @@ transformer_misc Summary: -AST Parsed : 26/26 (100.00%) -Positive Passed: 26/26 (100.00%) +AST Parsed : 27/27 (100.00%) +Positive Passed: 27/27 (100.00%)