diff --git a/apps/oxlint/src-js/generated/deserialize.js b/apps/oxlint/src-js/generated/deserialize.js index 2b403976f3fc2..8d06971613a5a 100644 --- a/apps/oxlint/src-js/generated/deserialize.js +++ b/apps/oxlint/src-js/generated/deserialize.js @@ -2367,13 +2367,13 @@ function deserializeFormalParameters(pos) { optional: false, typeAnnotation: null, value: null, - start: (start = deserializeU32(pos + 8)), - end: (end = deserializeU32(pos + 12)), + start: (start = deserializeU32(pos + 32)), + end: (end = deserializeU32(pos + 36)), range: [start, end], parent: previousParent, }); - rest.argument = deserializeBindingPattern(pos + 16); - rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 32); + rest.argument = deserializeBindingPattern(pos + 40); + rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 56); if (rest.typeAnnotation !== null) { end = rest.typeAnnotation.end; rest.end = end; diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 9c7b51b6f3da0..ddb0c5f175816 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1919,6 +1919,7 @@ pub enum FormalParameterKind { #[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, ContentEq, UnstableAddress)] pub struct FormalParameterRest<'a> { pub span: Span, + pub decorators: Vec<'a, Decorator<'a>>, pub rest: BindingRestElement<'a>, pub type_annotation: Option>>, } diff --git a/crates/oxc_ast/src/generated/assert_layouts.rs b/crates/oxc_ast/src/generated/assert_layouts.rs index c93ca939f9d5a..9fbae87f8c691 100644 --- a/crates/oxc_ast/src/generated/assert_layouts.rs +++ b/crates/oxc_ast/src/generated/assert_layouts.rs @@ -611,11 +611,12 @@ const _: () = { assert!(align_of::() == 1); // Padding: 0 bytes - assert!(size_of::() == 40); + assert!(size_of::() == 64); assert!(align_of::() == 8); assert!(offset_of!(FormalParameterRest, span) == 0); - assert!(offset_of!(FormalParameterRest, rest) == 8); - assert!(offset_of!(FormalParameterRest, type_annotation) == 32); + assert!(offset_of!(FormalParameterRest, decorators) == 8); + assert!(offset_of!(FormalParameterRest, rest) == 32); + assert!(offset_of!(FormalParameterRest, type_annotation) == 56); // Padding: 0 bytes assert!(size_of::() == 56); @@ -2233,11 +2234,12 @@ const _: () = if cfg!(target_family = "wasm") || align_of::() == 8 { assert!(align_of::() == 1); // Padding: 0 bytes - assert!(size_of::() == 28); + assert!(size_of::() == 44); assert!(align_of::() == 4); assert!(offset_of!(FormalParameterRest, span) == 0); - assert!(offset_of!(FormalParameterRest, rest) == 8); - assert!(offset_of!(FormalParameterRest, type_annotation) == 24); + assert!(offset_of!(FormalParameterRest, decorators) == 8); + assert!(offset_of!(FormalParameterRest, rest) == 24); + assert!(offset_of!(FormalParameterRest, type_annotation) == 40); // Padding: 0 bytes assert!(size_of::() == 40); diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 40b13195bf698..74078b33700a0 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -6177,19 +6177,26 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// * `span`: The [`Span`] covering this node + /// * `decorators` /// * `rest` /// * `type_annotation` #[inline] pub fn formal_parameter_rest( self, span: Span, + decorators: Vec<'a, Decorator<'a>>, rest: BindingRestElement<'a>, type_annotation: T1, ) -> FormalParameterRest<'a> where T1: IntoIn<'a, Option>>>, { - FormalParameterRest { span, rest, type_annotation: type_annotation.into_in(self.allocator) } + FormalParameterRest { + span, + decorators, + rest, + type_annotation: type_annotation.into_in(self.allocator), + } } /// Build a [`FormalParameterRest`], and store it in the memory arena. @@ -6199,19 +6206,24 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// * `span`: The [`Span`] covering this node + /// * `decorators` /// * `rest` /// * `type_annotation` #[inline] pub fn alloc_formal_parameter_rest( self, span: Span, + decorators: Vec<'a, Decorator<'a>>, rest: BindingRestElement<'a>, type_annotation: T1, ) -> Box<'a, FormalParameterRest<'a>> where T1: IntoIn<'a, Option>>>, { - Box::new_in(self.formal_parameter_rest(span, rest, type_annotation), self.allocator) + Box::new_in( + self.formal_parameter_rest(span, decorators, rest, type_annotation), + self.allocator, + ) } /// Build a [`FunctionBody`]. diff --git a/crates/oxc_ast/src/generated/derive_clone_in.rs b/crates/oxc_ast/src/generated/derive_clone_in.rs index cb978aac8dcf5..15d8be9a1133d 100644 --- a/crates/oxc_ast/src/generated/derive_clone_in.rs +++ b/crates/oxc_ast/src/generated/derive_clone_in.rs @@ -3655,6 +3655,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for FormalParameterRest<'_> { fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { FormalParameterRest { span: CloneIn::clone_in(&self.span, allocator), + decorators: CloneIn::clone_in(&self.decorators, allocator), rest: CloneIn::clone_in(&self.rest, allocator), type_annotation: CloneIn::clone_in(&self.type_annotation, allocator), } @@ -3663,6 +3664,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for FormalParameterRest<'_> { fn clone_in_with_semantic_ids(&self, allocator: &'new_alloc Allocator) -> Self::Cloned { FormalParameterRest { span: CloneIn::clone_in_with_semantic_ids(&self.span, allocator), + decorators: CloneIn::clone_in_with_semantic_ids(&self.decorators, allocator), rest: CloneIn::clone_in_with_semantic_ids(&self.rest, allocator), type_annotation: CloneIn::clone_in_with_semantic_ids(&self.type_annotation, allocator), } diff --git a/crates/oxc_ast/src/generated/derive_content_eq.rs b/crates/oxc_ast/src/generated/derive_content_eq.rs index 753c00634a7ff..e71c86ca6ec42 100644 --- a/crates/oxc_ast/src/generated/derive_content_eq.rs +++ b/crates/oxc_ast/src/generated/derive_content_eq.rs @@ -1091,7 +1091,8 @@ impl ContentEq for FormalParameterKind { impl ContentEq for FormalParameterRest<'_> { fn content_eq(&self, other: &Self) -> bool { - ContentEq::content_eq(&self.rest, &other.rest) + ContentEq::content_eq(&self.decorators, &other.decorators) + && ContentEq::content_eq(&self.rest, &other.rest) && ContentEq::content_eq(&self.type_annotation, &other.type_annotation) } } diff --git a/crates/oxc_ast/src/generated/derive_dummy.rs b/crates/oxc_ast/src/generated/derive_dummy.rs index 636f9f939ed28..1606976c42eca 100644 --- a/crates/oxc_ast/src/generated/derive_dummy.rs +++ b/crates/oxc_ast/src/generated/derive_dummy.rs @@ -1116,6 +1116,7 @@ impl<'a> Dummy<'a> for FormalParameterRest<'a> { fn dummy(allocator: &'a Allocator) -> Self { Self { span: Dummy::dummy(allocator), + decorators: Dummy::dummy(allocator), rest: Dummy::dummy(allocator), type_annotation: Dummy::dummy(allocator), } diff --git a/crates/oxc_ast_visit/src/generated/visit.rs b/crates/oxc_ast_visit/src/generated/visit.rs index 72ba0a8e66a77..eb227ba8f61dd 100644 --- a/crates/oxc_ast_visit/src/generated/visit.rs +++ b/crates/oxc_ast_visit/src/generated/visit.rs @@ -2500,6 +2500,7 @@ pub mod walk { let kind = AstKind::FormalParameterRest(visitor.alloc(it)); visitor.enter_node(kind); visitor.visit_span(&it.span); + visitor.visit_decorators(&it.decorators); visitor.visit_binding_rest_element(&it.rest); if let Some(type_annotation) = &it.type_annotation { visitor.visit_ts_type_annotation(type_annotation); diff --git a/crates/oxc_ast_visit/src/generated/visit_mut.rs b/crates/oxc_ast_visit/src/generated/visit_mut.rs index 2d3139e0388eb..94ad75cf09cb5 100644 --- a/crates/oxc_ast_visit/src/generated/visit_mut.rs +++ b/crates/oxc_ast_visit/src/generated/visit_mut.rs @@ -2583,6 +2583,7 @@ pub mod walk_mut { let kind = AstType::FormalParameterRest; visitor.enter_node(kind); visitor.visit_span(&mut it.span); + visitor.visit_decorators(&mut it.decorators); visitor.visit_binding_rest_element(&mut it.rest); if let Some(type_annotation) = &mut it.type_annotation { visitor.visit_ts_type_annotation(type_annotation); diff --git a/crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs b/crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs index e53a1dc565382..af671a8ee3d97 100644 --- a/crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs +++ b/crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs @@ -4375,6 +4375,17 @@ impl<'a> AstNode<'a, FormalParameter<'a>> { } impl<'a> AstNode<'a, FormalParameterRest<'a>> { + #[inline] + pub fn decorators(&self) -> &AstNode<'a, Vec<'a, Decorator<'a>>> { + let following_span_start = self.inner.rest.span().start; + self.allocator.alloc(AstNode { + inner: &self.inner.decorators, + allocator: self.allocator, + parent: AstNodes::FormalParameterRest(transmute_self(self)), + following_span_start, + }) + } + #[inline] pub fn rest(&self) -> &AstNode<'a, BindingRestElement<'a>> { let following_span_start = self diff --git a/crates/oxc_parser/src/js/function.rs b/crates/oxc_parser/src/js/function.rs index ee7f27c569627..940014f4a41c6 100644 --- a/crates/oxc_parser/src/js/function.rs +++ b/crates/oxc_parser/src/js/function.rs @@ -1,4 +1,4 @@ -use oxc_allocator::Box; +use oxc_allocator::{Box, Vec}; use oxc_ast::ast::*; use oxc_span::{GetSpan, Span}; @@ -118,27 +118,43 @@ impl<'a> ParserImpl<'a> { break; } + let span = self.start_span(); + let decorators = self.parse_decorators(); + if self.at(Kind::Dot3) { let rest_element = self.parse_rest_element_for_formal_parameter(); - let rest_span = rest_element.span; let type_annotation = if self.is_ts { self.parse_ts_type_annotation() } else { None }; + + let are_decorators_allowed = + matches!(func_kind, FunctionKind::ClassMethod | FunctionKind::Constructor) + && self.is_ts; + if !are_decorators_allowed { + for decorator in &decorators { + self.error(diagnostics::decorators_are_not_valid_here(decorator.span)); + } + } + rest = Some(self.ast.alloc_formal_parameter_rest( - rest_span, + self.end_span(span), + decorators, rest_element, type_annotation, )); } else { - list.push(self.parse_formal_parameter(func_kind)); + list.push(self.parse_formal_parameter_with_decorators(func_kind, span, decorators)); } } (list, rest) } - fn parse_formal_parameter(&mut self, func_kind: FunctionKind) -> FormalParameter<'a> { - let span = self.start_span(); - let decorators = self.parse_decorators(); + fn parse_formal_parameter_with_decorators( + &mut self, + func_kind: FunctionKind, + span: u32, + decorators: Vec<'a, Decorator<'a>>, + ) -> FormalParameter<'a> { let modifiers = self.parse_modifiers(false, false); if self.is_ts { let allowed_modifiers = if func_kind == FunctionKind::Constructor { diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 3de7ae8e950e1..cf9a19a6cfbaf 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -2258,6 +2258,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { self.enter_node(kind); param.bind(self); self.visit_span(¶m.span); + self.visit_decorators(¶m.decorators); self.visit_binding_rest_element(¶m.rest); if let Some(type_annotation) = ¶m.type_annotation { self.visit_ts_type_annotation(type_annotation); diff --git a/crates/oxc_transformer/src/es2022/class_properties/constructor.rs b/crates/oxc_transformer/src/es2022/class_properties/constructor.rs index 6e4305f4cc4d4..7ce751e54f79e 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/constructor.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/constructor.rs @@ -236,7 +236,8 @@ impl<'a> ClassProperties<'a, '_> { ctx.generate_uid("args", constructor_scope_id, SymbolFlags::FunctionScopedVariable); let rest_element = ctx.ast.binding_rest_element(SPAN, args_binding.create_binding_pattern(ctx)); - params_rest = Some(ctx.ast.alloc_formal_parameter_rest(SPAN, rest_element, NONE)); + params_rest = + Some(ctx.ast.alloc_formal_parameter_rest(SPAN, ctx.ast.vec(), rest_element, NONE)); stmts.push(ctx.ast.statement_expression(SPAN, create_super_call(&args_binding, ctx))); } // TODO: Should these have the span of the original `PropertyDefinition`s? @@ -311,7 +312,8 @@ impl<'a> ClassProperties<'a, '_> { { let rest_element = ctx.ast.binding_rest_element(SPAN, args_binding.create_binding_pattern(ctx)); - let rest = ctx.ast.alloc_formal_parameter_rest(SPAN, rest_element, NONE); + let rest = + ctx.ast.alloc_formal_parameter_rest(SPAN, ctx.ast.vec(), rest_element, NONE); ctx.ast.alloc_formal_parameters( SPAN, FormalParameterKind::ArrowFormalParameters, diff --git a/crates/oxc_transformer/src/utils/ast_builder.rs b/crates/oxc_transformer/src/utils/ast_builder.rs index a7b51f479dcef..f59ac808ecde0 100644 --- a/crates/oxc_transformer/src/utils/ast_builder.rs +++ b/crates/oxc_transformer/src/utils/ast_builder.rs @@ -165,7 +165,8 @@ pub fn create_class_constructor<'a, 'c>( let args_binding = ctx.generate_uid("args", scope_id, SymbolFlags::FunctionScopedVariable); let rest_element = ctx.ast.binding_rest_element(SPAN, args_binding.create_binding_pattern(ctx)); - params_rest = Some(ctx.ast.alloc_formal_parameter_rest(SPAN, rest_element, NONE)); + params_rest = + Some(ctx.ast.alloc_formal_parameter_rest(SPAN, ctx.ast.vec(), rest_element, NONE)); ctx.ast.vec_from_iter( iter::once(ctx.ast.statement_expression(SPAN, create_super_call(&args_binding, ctx))) .chain(stmts_iter), diff --git a/crates/oxc_traverse/src/generated/ancestor.rs b/crates/oxc_traverse/src/generated/ancestor.rs index 956c7980abfa8..cd628c151db84 100644 --- a/crates/oxc_traverse/src/generated/ancestor.rs +++ b/crates/oxc_traverse/src/generated/ancestor.rs @@ -141,187 +141,188 @@ pub(crate) enum AncestorType { FormalParameterPattern = 117, FormalParameterTypeAnnotation = 118, FormalParameterInitializer = 119, - FormalParameterRestRest = 120, - FormalParameterRestTypeAnnotation = 121, - FunctionBodyDirectives = 122, - FunctionBodyStatements = 123, - ArrowFunctionExpressionTypeParameters = 124, - ArrowFunctionExpressionParams = 125, - ArrowFunctionExpressionReturnType = 126, - ArrowFunctionExpressionBody = 127, - YieldExpressionArgument = 128, - ClassDecorators = 129, - ClassId = 130, - ClassTypeParameters = 131, - ClassSuperClass = 132, - ClassSuperTypeArguments = 133, - ClassImplements = 134, - ClassBody = 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, - ExportNamedDeclarationDeclaration = 161, - ExportNamedDeclarationSpecifiers = 162, - ExportNamedDeclarationSource = 163, - ExportNamedDeclarationWithClause = 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, - TSIndexSignatureParameters = 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, - TSInterfaceHeritageExpression = 252, - TSInterfaceHeritageTypeArguments = 253, - TSTypePredicateParameterName = 254, - TSTypePredicateTypeAnnotation = 255, - TSModuleDeclarationId = 256, - TSModuleDeclarationBody = 257, - TSGlobalDeclarationBody = 258, - TSModuleBlockDirectives = 259, - TSModuleBlockBody = 260, - TSTypeLiteralMembers = 261, - TSInferTypeTypeParameter = 262, - TSTypeQueryExprName = 263, - TSTypeQueryTypeArguments = 264, - TSImportTypeSource = 265, - TSImportTypeOptions = 266, - TSImportTypeQualifier = 267, - TSImportTypeTypeArguments = 268, - TSImportTypeQualifiedNameLeft = 269, - TSImportTypeQualifiedNameRight = 270, - TSFunctionTypeTypeParameters = 271, - TSFunctionTypeThisParam = 272, - TSFunctionTypeParams = 273, - TSFunctionTypeReturnType = 274, - TSConstructorTypeTypeParameters = 275, - TSConstructorTypeParams = 276, - TSConstructorTypeReturnType = 277, - TSMappedTypeKey = 278, - TSMappedTypeConstraint = 279, - TSMappedTypeNameType = 280, - TSMappedTypeTypeAnnotation = 281, - TSTemplateLiteralTypeQuasis = 282, - TSTemplateLiteralTypeTypes = 283, - TSAsExpressionExpression = 284, - TSAsExpressionTypeAnnotation = 285, - TSSatisfiesExpressionExpression = 286, - TSSatisfiesExpressionTypeAnnotation = 287, - TSTypeAssertionTypeAnnotation = 288, - TSTypeAssertionExpression = 289, - TSImportEqualsDeclarationId = 290, - TSImportEqualsDeclarationModuleReference = 291, - TSExternalModuleReferenceExpression = 292, - TSNonNullExpressionExpression = 293, - DecoratorExpression = 294, - TSExportAssignmentExpression = 295, - TSNamespaceExportDeclarationId = 296, - TSInstantiationExpressionExpression = 297, - TSInstantiationExpressionTypeArguments = 298, - JSDocNullableTypeTypeAnnotation = 299, - JSDocNonNullableTypeTypeAnnotation = 300, + FormalParameterRestDecorators = 120, + FormalParameterRestRest = 121, + FormalParameterRestTypeAnnotation = 122, + FunctionBodyDirectives = 123, + FunctionBodyStatements = 124, + ArrowFunctionExpressionTypeParameters = 125, + ArrowFunctionExpressionParams = 126, + ArrowFunctionExpressionReturnType = 127, + ArrowFunctionExpressionBody = 128, + YieldExpressionArgument = 129, + ClassDecorators = 130, + ClassId = 131, + ClassTypeParameters = 132, + ClassSuperClass = 133, + ClassSuperTypeArguments = 134, + ClassImplements = 135, + ClassBody = 136, + ClassBodyBody = 137, + MethodDefinitionDecorators = 138, + MethodDefinitionKey = 139, + MethodDefinitionValue = 140, + PropertyDefinitionDecorators = 141, + PropertyDefinitionKey = 142, + PropertyDefinitionTypeAnnotation = 143, + PropertyDefinitionValue = 144, + StaticBlockBody = 145, + AccessorPropertyDecorators = 146, + AccessorPropertyKey = 147, + AccessorPropertyTypeAnnotation = 148, + AccessorPropertyValue = 149, + ImportExpressionSource = 150, + ImportExpressionOptions = 151, + ImportDeclarationSpecifiers = 152, + ImportDeclarationSource = 153, + ImportDeclarationWithClause = 154, + ImportSpecifierImported = 155, + ImportSpecifierLocal = 156, + ImportDefaultSpecifierLocal = 157, + ImportNamespaceSpecifierLocal = 158, + WithClauseWithEntries = 159, + ImportAttributeKey = 160, + ImportAttributeValue = 161, + ExportNamedDeclarationDeclaration = 162, + ExportNamedDeclarationSpecifiers = 163, + ExportNamedDeclarationSource = 164, + ExportNamedDeclarationWithClause = 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, + TSIndexSignatureParameters = 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, + TSInterfaceHeritageExpression = 253, + TSInterfaceHeritageTypeArguments = 254, + TSTypePredicateParameterName = 255, + TSTypePredicateTypeAnnotation = 256, + TSModuleDeclarationId = 257, + TSModuleDeclarationBody = 258, + TSGlobalDeclarationBody = 259, + TSModuleBlockDirectives = 260, + TSModuleBlockBody = 261, + TSTypeLiteralMembers = 262, + TSInferTypeTypeParameter = 263, + TSTypeQueryExprName = 264, + TSTypeQueryTypeArguments = 265, + TSImportTypeSource = 266, + TSImportTypeOptions = 267, + TSImportTypeQualifier = 268, + TSImportTypeTypeArguments = 269, + TSImportTypeQualifiedNameLeft = 270, + TSImportTypeQualifiedNameRight = 271, + TSFunctionTypeTypeParameters = 272, + TSFunctionTypeThisParam = 273, + TSFunctionTypeParams = 274, + TSFunctionTypeReturnType = 275, + TSConstructorTypeTypeParameters = 276, + TSConstructorTypeParams = 277, + TSConstructorTypeReturnType = 278, + TSMappedTypeKey = 279, + TSMappedTypeConstraint = 280, + TSMappedTypeNameType = 281, + TSMappedTypeTypeAnnotation = 282, + TSTemplateLiteralTypeQuasis = 283, + TSTemplateLiteralTypeTypes = 284, + TSAsExpressionExpression = 285, + TSAsExpressionTypeAnnotation = 286, + TSSatisfiesExpressionExpression = 287, + TSSatisfiesExpressionTypeAnnotation = 288, + TSTypeAssertionTypeAnnotation = 289, + TSTypeAssertionExpression = 290, + TSImportEqualsDeclarationId = 291, + TSImportEqualsDeclarationModuleReference = 292, + TSExternalModuleReferenceExpression = 293, + TSNonNullExpressionExpression = 294, + DecoratorExpression = 295, + TSExportAssignmentExpression = 296, + TSNamespaceExportDeclarationId = 297, + TSInstantiationExpressionExpression = 298, + TSInstantiationExpressionTypeArguments = 299, + JSDocNullableTypeTypeAnnotation = 300, + JSDocNonNullableTypeTypeAnnotation = 301, } /// Ancestor type used in AST traversal. @@ -555,6 +556,8 @@ pub enum Ancestor<'a, 't> { AncestorType::FormalParameterTypeAnnotation as u16, FormalParameterInitializer(FormalParameterWithoutInitializer<'a, 't>) = AncestorType::FormalParameterInitializer as u16, + FormalParameterRestDecorators(FormalParameterRestWithoutDecorators<'a, 't>) = + AncestorType::FormalParameterRestDecorators as u16, FormalParameterRestRest(FormalParameterRestWithoutRest<'a, 't>) = AncestorType::FormalParameterRestRest as u16, FormalParameterRestTypeAnnotation(FormalParameterRestWithoutTypeAnnotation<'a, 't>) = @@ -1296,7 +1299,9 @@ impl<'a, 't> Ancestor<'a, 't> { pub fn is_formal_parameter_rest(self) -> bool { matches!( self, - Self::FormalParameterRestRest(_) | Self::FormalParameterRestTypeAnnotation(_) + Self::FormalParameterRestDecorators(_) + | Self::FormalParameterRestRest(_) + | Self::FormalParameterRestTypeAnnotation(_) ) } @@ -2372,6 +2377,7 @@ impl<'a, 't> GetAddress for Ancestor<'a, 't> { Self::FormalParameterPattern(a) => a.address(), Self::FormalParameterTypeAnnotation(a) => a.address(), Self::FormalParameterInitializer(a) => a.address(), + Self::FormalParameterRestDecorators(a) => a.address(), Self::FormalParameterRestRest(a) => a.address(), Self::FormalParameterRestTypeAnnotation(a) => a.address(), Self::FunctionBodyDirectives(a) => a.address(), @@ -7587,10 +7593,49 @@ impl<'a, 't> GetAddress for FormalParameterWithoutInitializer<'a, 't> { } pub(crate) const OFFSET_FORMAL_PARAMETER_REST_SPAN: usize = offset_of!(FormalParameterRest, span); +pub(crate) const OFFSET_FORMAL_PARAMETER_REST_DECORATORS: usize = + offset_of!(FormalParameterRest, decorators); pub(crate) const OFFSET_FORMAL_PARAMETER_REST_REST: usize = offset_of!(FormalParameterRest, rest); pub(crate) const OFFSET_FORMAL_PARAMETER_REST_TYPE_ANNOTATION: usize = offset_of!(FormalParameterRest, type_annotation); +#[repr(transparent)] +#[derive(Clone, Copy, Debug)] +pub struct FormalParameterRestWithoutDecorators<'a, 't>( + pub(crate) *const FormalParameterRest<'a>, + pub(crate) PhantomData<&'t ()>, +); + +impl<'a, 't> FormalParameterRestWithoutDecorators<'a, 't> { + #[inline] + pub fn span(self) -> &'t Span { + unsafe { &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_SPAN) as *const Span) } + } + + #[inline] + pub fn rest(self) -> &'t BindingRestElement<'a> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_REST) + as *const BindingRestElement<'a>) + } + } + + #[inline] + pub fn type_annotation(self) -> &'t Option>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_TYPE_ANNOTATION) + as *const Option>>) + } + } +} + +impl<'a, 't> GetAddress for FormalParameterRestWithoutDecorators<'a, 't> { + #[inline] + fn address(&self) -> Address { + unsafe { Address::from_ptr(self.0) } + } +} + #[repr(transparent)] #[derive(Clone, Copy, Debug)] pub struct FormalParameterRestWithoutRest<'a, 't>( @@ -7604,6 +7649,14 @@ impl<'a, 't> FormalParameterRestWithoutRest<'a, 't> { unsafe { &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_SPAN) as *const Span) } } + #[inline] + pub fn decorators(self) -> &'t Vec<'a, Decorator<'a>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_DECORATORS) + as *const Vec<'a, Decorator<'a>>) + } + } + #[inline] pub fn type_annotation(self) -> &'t Option>> { unsafe { @@ -7633,6 +7686,14 @@ impl<'a, 't> FormalParameterRestWithoutTypeAnnotation<'a, 't> { unsafe { &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_SPAN) as *const Span) } } + #[inline] + pub fn decorators(self) -> &'t Vec<'a, Decorator<'a>> { + unsafe { + &*((self.0 as *const u8).add(OFFSET_FORMAL_PARAMETER_REST_DECORATORS) + as *const Vec<'a, Decorator<'a>>) + } + } + #[inline] pub fn rest(self) -> &'t BindingRestElement<'a> { unsafe { diff --git a/crates/oxc_traverse/src/generated/scopes_collector.rs b/crates/oxc_traverse/src/generated/scopes_collector.rs index 2365d7a9205eb..d06ba31428568 100644 --- a/crates/oxc_traverse/src/generated/scopes_collector.rs +++ b/crates/oxc_traverse/src/generated/scopes_collector.rs @@ -967,6 +967,7 @@ impl<'a> Visit<'a> for ChildScopeCollector { #[inline] fn visit_formal_parameter_rest(&mut self, it: &FormalParameterRest<'a>) { + self.visit_decorators(&it.decorators); self.visit_binding_rest_element(&it.rest); if let Some(type_annotation) = &it.type_annotation { self.visit_ts_type_annotation(type_annotation); diff --git a/crates/oxc_traverse/src/generated/walk.rs b/crates/oxc_traverse/src/generated/walk.rs index 9ccdc0cf98d7a..6c548e7aa481b 100644 --- a/crates/oxc_traverse/src/generated/walk.rs +++ b/crates/oxc_traverse/src/generated/walk.rs @@ -2389,9 +2389,15 @@ unsafe fn walk_formal_parameter_rest<'a, State, Tr: Traverse<'a, State>>( ctx: &mut TraverseCtx<'a, State>, ) { traverser.enter_formal_parameter_rest(&mut *node, ctx); - let pop_token = ctx.push_stack(Ancestor::FormalParameterRestRest( - ancestor::FormalParameterRestWithoutRest(node, PhantomData), + let pop_token = ctx.push_stack(Ancestor::FormalParameterRestDecorators( + ancestor::FormalParameterRestWithoutDecorators(node, PhantomData), )); + for item in &mut *((node as *mut u8).add(ancestor::OFFSET_FORMAL_PARAMETER_REST_DECORATORS) + as *mut Vec) + { + walk_decorator(traverser, item as *mut _, ctx); + } + ctx.retag_stack(AncestorType::FormalParameterRestRest); walk_binding_rest_element( traverser, (node as *mut u8).add(ancestor::OFFSET_FORMAL_PARAMETER_REST_REST) diff --git a/napi/parser/src-js/generated/deserialize/js.js b/napi/parser/src-js/generated/deserialize/js.js index 70fa40ce1abb7..9a5443264bd54 100644 --- a/napi/parser/src-js/generated/deserialize/js.js +++ b/napi/parser/src-js/generated/deserialize/js.js @@ -1726,10 +1726,10 @@ function deserializeFormalParameters(pos) { let rest = { type: "RestElement", argument: null, - start: deserializeU32(pos + 8), - end: deserializeU32(pos + 12), + start: deserializeU32(pos + 32), + end: deserializeU32(pos + 36), }; - rest.argument = deserializeBindingPattern(pos + 16); + rest.argument = deserializeBindingPattern(pos + 40); params.push(rest); } return params; diff --git a/napi/parser/src-js/generated/deserialize/js_parent.js b/napi/parser/src-js/generated/deserialize/js_parent.js index bfae6949c21c6..12a3dc9fb5cee 100644 --- a/napi/parser/src-js/generated/deserialize/js_parent.js +++ b/napi/parser/src-js/generated/deserialize/js_parent.js @@ -1933,11 +1933,11 @@ function deserializeFormalParameters(pos) { rest = (parent = { type: "RestElement", argument: null, - start: deserializeU32(pos + 8), - end: deserializeU32(pos + 12), + start: deserializeU32(pos + 32), + end: deserializeU32(pos + 36), parent: previousParent, }); - rest.argument = deserializeBindingPattern(pos + 16); + rest.argument = deserializeBindingPattern(pos + 40); params.push(rest); parent = previousParent; } diff --git a/napi/parser/src-js/generated/deserialize/js_range.js b/napi/parser/src-js/generated/deserialize/js_range.js index bbd2bf4ba0b57..7414b44d4ff45 100644 --- a/napi/parser/src-js/generated/deserialize/js_range.js +++ b/napi/parser/src-js/generated/deserialize/js_range.js @@ -1917,11 +1917,11 @@ function deserializeFormalParameters(pos) { rest = { type: "RestElement", argument: null, - start: (start = deserializeU32(pos + 8)), - end: (end = deserializeU32(pos + 12)), + start: (start = deserializeU32(pos + 32)), + end: (end = deserializeU32(pos + 36)), range: [start, end], }; - rest.argument = deserializeBindingPattern(pos + 16); + rest.argument = deserializeBindingPattern(pos + 40); params.push(rest); } return params; diff --git a/napi/parser/src-js/generated/deserialize/js_range_parent.js b/napi/parser/src-js/generated/deserialize/js_range_parent.js index 8a9521bc997b2..ecfcbdadca6c9 100644 --- a/napi/parser/src-js/generated/deserialize/js_range_parent.js +++ b/napi/parser/src-js/generated/deserialize/js_range_parent.js @@ -2127,12 +2127,12 @@ function deserializeFormalParameters(pos) { rest = (parent = { type: "RestElement", argument: null, - start: (start = deserializeU32(pos + 8)), - end: (end = deserializeU32(pos + 12)), + start: (start = deserializeU32(pos + 32)), + end: (end = deserializeU32(pos + 36)), range: [start, end], parent: previousParent, }); - rest.argument = deserializeBindingPattern(pos + 16); + rest.argument = deserializeBindingPattern(pos + 40); params.push(rest); parent = previousParent; } diff --git a/napi/parser/src-js/generated/deserialize/ts.js b/napi/parser/src-js/generated/deserialize/ts.js index 177e4138454ae..d5053d09c3aeb 100644 --- a/napi/parser/src-js/generated/deserialize/ts.js +++ b/napi/parser/src-js/generated/deserialize/ts.js @@ -1860,11 +1860,11 @@ function deserializeFormalParameters(pos) { optional: false, typeAnnotation: null, value: null, - start: deserializeU32(pos + 8), - end: (end = deserializeU32(pos + 12)), + start: deserializeU32(pos + 32), + end: (end = deserializeU32(pos + 36)), }; - rest.argument = deserializeBindingPattern(pos + 16); - rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 32); + rest.argument = deserializeBindingPattern(pos + 40); + rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 56); if (rest.typeAnnotation !== null) { end = rest.typeAnnotation.end; rest.end = end; diff --git a/napi/parser/src-js/generated/deserialize/ts_parent.js b/napi/parser/src-js/generated/deserialize/ts_parent.js index 48c6f7bc5dd86..19ffbd5938683 100644 --- a/napi/parser/src-js/generated/deserialize/ts_parent.js +++ b/napi/parser/src-js/generated/deserialize/ts_parent.js @@ -2068,12 +2068,12 @@ function deserializeFormalParameters(pos) { optional: false, typeAnnotation: null, value: null, - start: deserializeU32(pos + 8), - end: (end = deserializeU32(pos + 12)), + start: deserializeU32(pos + 32), + end: (end = deserializeU32(pos + 36)), parent: previousParent, }); - rest.argument = deserializeBindingPattern(pos + 16); - rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 32); + rest.argument = deserializeBindingPattern(pos + 40); + rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 56); if (rest.typeAnnotation !== null) { end = rest.typeAnnotation.end; rest.end = end; diff --git a/napi/parser/src-js/generated/deserialize/ts_range.js b/napi/parser/src-js/generated/deserialize/ts_range.js index 233ad87a3f756..4910f1d611c74 100644 --- a/napi/parser/src-js/generated/deserialize/ts_range.js +++ b/napi/parser/src-js/generated/deserialize/ts_range.js @@ -2060,12 +2060,12 @@ function deserializeFormalParameters(pos) { optional: false, typeAnnotation: null, value: null, - start: (start = deserializeU32(pos + 8)), - end: (end = deserializeU32(pos + 12)), + start: (start = deserializeU32(pos + 32)), + end: (end = deserializeU32(pos + 36)), range: [start, end], }; - rest.argument = deserializeBindingPattern(pos + 16); - rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 32); + rest.argument = deserializeBindingPattern(pos + 40); + rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 56); if (rest.typeAnnotation !== null) { end = rest.typeAnnotation.end; rest.end = end; diff --git a/napi/parser/src-js/generated/deserialize/ts_range_parent.js b/napi/parser/src-js/generated/deserialize/ts_range_parent.js index b34079aa2da53..5a175ca2ac34c 100644 --- a/napi/parser/src-js/generated/deserialize/ts_range_parent.js +++ b/napi/parser/src-js/generated/deserialize/ts_range_parent.js @@ -2267,13 +2267,13 @@ function deserializeFormalParameters(pos) { optional: false, typeAnnotation: null, value: null, - start: (start = deserializeU32(pos + 8)), - end: (end = deserializeU32(pos + 12)), + start: (start = deserializeU32(pos + 32)), + end: (end = deserializeU32(pos + 36)), range: [start, end], parent: previousParent, }); - rest.argument = deserializeBindingPattern(pos + 16); - rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 32); + rest.argument = deserializeBindingPattern(pos + 40); + rest.typeAnnotation = deserializeOptionBoxTSTypeAnnotation(pos + 56); if (rest.typeAnnotation !== null) { end = rest.typeAnnotation.end; rest.end = end; diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 9de5882760d1f..b8cf0f262b5b3 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -1,8 +1,8 @@ commit: 95e3aaa9 parser_typescript Summary: -AST Parsed : 9842/9843 (99.99%) -Positive Passed: 9838/9843 (99.95%) +AST Parsed : 9843/9843 (100.00%) +Positive Passed: 9839/9843 (99.96%) Negative Passed: 1515/2557 (59.25%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts @@ -2088,16 +2088,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/uni Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/witness/witness.ts -Panicked: tasks/coverage/typescript/tests/cases/compiler/sourceMapValidationDecorators.ts - - × Unexpected token - ╭─[typescript/tests/cases/compiler/sourceMapValidationDecorators.ts:18:7] - 17 │ @ParameterDecorator2(30) - 18 │ ...b: string[]) { - · ─── - 19 │ } - ╰──── - Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts × Identifier `x` has already been declared