diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 0e47722e01fd3..dd070af137228 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -313,6 +313,31 @@ impl<'a> AstBuilder<'a> { Expression::Identifier(self.alloc_identifier_reference(span, name)) } + /// Build an [`Expression::Identifier`] with `reference_id`. + /// + /// This node contains an [`IdentifierReference`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn expression_identifier_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> Expression<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + Expression::Identifier(self.alloc_identifier_reference_with_reference_id( + span, + name, + reference_id, + )) + } + /// Build an [`Expression::MetaProperty`]. /// /// This node contains a [`MetaProperty`] that will be stored in the memory arena. @@ -400,6 +425,54 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`Expression::ArrowFunctionExpression`] with `scope_id` and `pure`. + /// + /// This node contains an [`ArrowFunctionExpression`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `expression`: Is the function body an arrow expression? i.e. `() => expr` instead of `() => {}` + /// * `async` + /// * `type_parameters` + /// * `params` + /// * `return_type` + /// * `body`: See `expression` for whether this arrow expression returns an expression. + /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment + #[inline] + pub fn expression_arrow_function_with_scope_id_and_pure( + self, + span: Span, + expression: bool, + r#async: bool, + type_parameters: T1, + params: T2, + return_type: T3, + body: T4, + scope_id: ScopeId, + pure: bool, + ) -> Expression<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T3: IntoIn<'a, Option>>>, + T4: IntoIn<'a, Box<'a, FunctionBody<'a>>>, + { + Expression::ArrowFunctionExpression( + self.alloc_arrow_function_expression_with_scope_id_and_pure( + span, + expression, + r#async, + type_parameters, + params, + return_type, + body, + scope_id, + pure, + ), + ) + } + /// Build an [`Expression::AssignmentExpression`]. /// /// This node contains an [`AssignmentExpression`] that will be stored in the memory arena. @@ -485,6 +558,40 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`Expression::CallExpression`] with `pure`. + /// + /// This node contains a [`CallExpression`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `type_parameters` + /// * `arguments` + /// * `optional` + /// * `pure`: `true` if the call expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn expression_call_with_pure( + self, + span: Span, + callee: Expression<'a>, + type_parameters: T1, + arguments: Vec<'a, Argument<'a>>, + optional: bool, + pure: bool, + ) -> Expression<'a> + where + T1: IntoIn<'a, Option>>>, + { + Expression::CallExpression(self.alloc_call_expression_with_pure( + span, + callee, + type_parameters, + arguments, + optional, + pure, + )) + } + /// Build an [`Expression::ChainExpression`]. /// /// This node contains a [`ChainExpression`] that will be stored in the memory arena. @@ -548,6 +655,60 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`Expression::ClassExpression`] with `scope_id`. + /// + /// This node contains a [`Class`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `decorators`: Decorators applied to the class. + /// * `id`: Class identifier, AKA the name + /// * `type_parameters` + /// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`]. + /// * `super_type_parameters`: Type parameters passed to super class. + /// * `implements`: Interface implementation clause for TypeScript classes. + /// * `body` + /// * `abstract`: Whether the class is abstract + /// * `declare`: Whether the class was `declare`ed + /// * `scope_id`: Id of the scope created by the [`Class`], including type parameters and + #[inline] + pub fn expression_class_with_scope_id( + self, + span: Span, + r#type: ClassType, + decorators: Vec<'a, Decorator<'a>>, + id: Option>, + type_parameters: T1, + super_class: Option>, + super_type_parameters: T2, + implements: Option>>, + body: T3, + r#abstract: bool, + declare: bool, + scope_id: ScopeId, + ) -> Expression<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, ClassBody<'a>>>, + { + Expression::ClassExpression(self.alloc_class_with_scope_id( + span, + r#type, + decorators, + id, + type_parameters, + super_class, + super_type_parameters, + implements, + body, + r#abstract, + declare, + scope_id, + )) + } + /// Build an [`Expression::ConditionalExpression`]. /// /// This node contains a [`ConditionalExpression`] that will be stored in the memory arena. @@ -623,6 +784,65 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`Expression::FunctionExpression`] with `scope_id` and `pure`. + /// + /// This node contains a [`Function`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `id`: The function identifier. [`None`] for anonymous function expressions. + /// * `generator`: Is this a generator function? + /// * `async` + /// * `declare` + /// * `type_parameters` + /// * `this_param`: Declaring `this` in a Function + /// * `params`: Function parameters. + /// * `return_type`: The TypeScript return type annotation. + /// * `body`: The function body. + /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment + #[inline] + pub fn expression_function_with_scope_id_and_pure( + self, + span: Span, + r#type: FunctionType, + id: Option>, + generator: bool, + r#async: bool, + declare: bool, + type_parameters: T1, + this_param: T2, + params: T3, + return_type: T4, + body: T5, + scope_id: ScopeId, + pure: bool, + ) -> Expression<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T4: IntoIn<'a, Option>>>, + T5: IntoIn<'a, Option>>>, + { + Expression::FunctionExpression(self.alloc_function_with_scope_id_and_pure( + span, + r#type, + id, + generator, + r#async, + declare, + type_parameters, + this_param, + params, + return_type, + body, + scope_id, + pure, + )) + } + /// Build an [`Expression::ImportExpression`]. /// /// This node contains an [`ImportExpression`] that will be stored in the memory arena. @@ -691,6 +911,37 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`Expression::NewExpression`] with `pure`. + /// + /// This node contains a [`NewExpression`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `callee` + /// * `arguments` + /// * `type_parameters` + /// * `pure`: `true` if the new expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn expression_new_with_pure( + self, + span: Span, + callee: Expression<'a>, + arguments: Vec<'a, Argument<'a>>, + type_parameters: T1, + pure: bool, + ) -> Expression<'a> + where + T1: IntoIn<'a, Option>>>, + { + Expression::NewExpression(self.alloc_new_expression_with_pure( + span, + callee, + arguments, + type_parameters, + pure, + )) + } + /// Build an [`Expression::ObjectExpression`]. /// /// This node contains an [`ObjectExpression`] that will be stored in the memory arena. @@ -2446,6 +2697,29 @@ impl<'a> AstBuilder<'a> { ) } + /// Build a [`SimpleAssignmentTarget::AssignmentTargetIdentifier`] with `reference_id`. + /// + /// This node contains an [`IdentifierReference`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn simple_assignment_target_assignment_target_identifier_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> SimpleAssignmentTarget<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + SimpleAssignmentTarget::AssignmentTargetIdentifier( + self.alloc_identifier_reference_with_reference_id(span, name, reference_id), + ) + } + /// Build a [`SimpleAssignmentTarget::TSAsExpression`]. /// /// This node contains a [`TSAsExpression`] that will be stored in the memory arena. @@ -3029,16 +3303,50 @@ impl<'a> AstBuilder<'a> { )) } - /// Build a [`ChainElement::TSNonNullExpression`]. + /// Build a [`ChainElement::CallExpression`] with `pure`. /// - /// This node contains a [`TSNonNullExpression`] that will be stored in the memory arena. + /// This node contains a [`CallExpression`] that will be stored in the memory arena. /// /// ## Parameters /// * `span`: The [`Span`] covering this node - /// * `expression` - #[inline] - pub fn chain_element_ts_non_null_expression( - self, + /// * `callee` + /// * `type_parameters` + /// * `arguments` + /// * `optional` + /// * `pure`: `true` if the call expression is marked with a `/* @__PURE__ */` comment + #[inline] + pub fn chain_element_call_expression_with_pure( + self, + span: Span, + callee: Expression<'a>, + type_parameters: T1, + arguments: Vec<'a, Argument<'a>>, + optional: bool, + pure: bool, + ) -> ChainElement<'a> + where + T1: IntoIn<'a, Option>>>, + { + ChainElement::CallExpression(self.alloc_call_expression_with_pure( + span, + callee, + type_parameters, + arguments, + optional, + pure, + )) + } + + /// Build a [`ChainElement::TSNonNullExpression`]. + /// + /// This node contains a [`TSNonNullExpression`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `expression` + #[inline] + pub fn chain_element_ts_non_null_expression( + self, span: Span, expression: Expression<'a>, ) -> ChainElement<'a> { @@ -3089,6 +3397,24 @@ impl<'a> AstBuilder<'a> { Statement::BlockStatement(self.alloc_block_statement(span, body)) } + /// Build a [`Statement::BlockStatement`] with `scope_id`. + /// + /// This node contains a [`BlockStatement`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `body` + /// * `scope_id` + #[inline] + pub fn statement_block_with_scope_id( + self, + span: Span, + body: Vec<'a, Statement<'a>>, + scope_id: ScopeId, + ) -> Statement<'a> { + Statement::BlockStatement(self.alloc_block_statement_with_scope_id(span, body, scope_id)) + } + /// Build a [`Statement::BreakStatement`]. /// /// This node contains a [`BreakStatement`] that will be stored in the memory arena. @@ -3189,6 +3515,30 @@ impl<'a> AstBuilder<'a> { Statement::ForInStatement(self.alloc_for_in_statement(span, left, right, body)) } + /// Build a [`Statement::ForInStatement`] with `scope_id`. + /// + /// This node contains a [`ForInStatement`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `left` + /// * `right` + /// * `body` + /// * `scope_id` + #[inline] + pub fn statement_for_in_with_scope_id( + self, + span: Span, + left: ForStatementLeft<'a>, + right: Expression<'a>, + body: Statement<'a>, + scope_id: ScopeId, + ) -> Statement<'a> { + Statement::ForInStatement( + self.alloc_for_in_statement_with_scope_id(span, left, right, body, scope_id), + ) + } + /// Build a [`Statement::ForOfStatement`]. /// /// This node contains a [`ForOfStatement`] that will be stored in the memory arena. @@ -3211,6 +3561,32 @@ impl<'a> AstBuilder<'a> { Statement::ForOfStatement(self.alloc_for_of_statement(span, r#await, left, right, body)) } + /// Build a [`Statement::ForOfStatement`] with `scope_id`. + /// + /// This node contains a [`ForOfStatement`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `await` + /// * `left` + /// * `right` + /// * `body` + /// * `scope_id` + #[inline] + pub fn statement_for_of_with_scope_id( + self, + span: Span, + r#await: bool, + left: ForStatementLeft<'a>, + right: Expression<'a>, + body: Statement<'a>, + scope_id: ScopeId, + ) -> Statement<'a> { + Statement::ForOfStatement( + self.alloc_for_of_statement_with_scope_id(span, r#await, left, right, body, scope_id), + ) + } + /// Build a [`Statement::ForStatement`]. /// /// This node contains a [`ForStatement`] that will be stored in the memory arena. @@ -3233,6 +3609,32 @@ impl<'a> AstBuilder<'a> { Statement::ForStatement(self.alloc_for_statement(span, init, test, update, body)) } + /// Build a [`Statement::ForStatement`] with `scope_id`. + /// + /// This node contains a [`ForStatement`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `init` + /// * `test` + /// * `update` + /// * `body` + /// * `scope_id` + #[inline] + pub fn statement_for_with_scope_id( + self, + span: Span, + init: Option>, + test: Option>, + update: Option>, + body: Statement<'a>, + scope_id: ScopeId, + ) -> Statement<'a> { + Statement::ForStatement( + self.alloc_for_statement_with_scope_id(span, init, test, update, body, scope_id), + ) + } + /// Build a [`Statement::IfStatement`]. /// /// This node contains an [`IfStatement`] that will be stored in the memory arena. @@ -3301,6 +3703,31 @@ impl<'a> AstBuilder<'a> { Statement::SwitchStatement(self.alloc_switch_statement(span, discriminant, cases)) } + /// Build a [`Statement::SwitchStatement`] with `scope_id`. + /// + /// This node contains a [`SwitchStatement`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `discriminant` + /// * `cases` + /// * `scope_id` + #[inline] + pub fn statement_switch_with_scope_id( + self, + span: Span, + discriminant: Expression<'a>, + cases: Vec<'a, SwitchCase<'a>>, + scope_id: ScopeId, + ) -> Statement<'a> { + Statement::SwitchStatement(self.alloc_switch_statement_with_scope_id( + span, + discriminant, + cases, + scope_id, + )) + } + /// Build a [`Statement::ThrowStatement`]. /// /// This node contains a [`ThrowStatement`] that will be stored in the memory arena. @@ -3588,6 +4015,65 @@ impl<'a> AstBuilder<'a> { )) } + /// Build a [`Declaration::FunctionDeclaration`] with `scope_id` and `pure`. + /// + /// This node contains a [`Function`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `id`: The function identifier. [`None`] for anonymous function expressions. + /// * `generator`: Is this a generator function? + /// * `async` + /// * `declare` + /// * `type_parameters` + /// * `this_param`: Declaring `this` in a Function + /// * `params`: Function parameters. + /// * `return_type`: The TypeScript return type annotation. + /// * `body`: The function body. + /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment + #[inline] + pub fn declaration_function_with_scope_id_and_pure( + self, + span: Span, + r#type: FunctionType, + id: Option>, + generator: bool, + r#async: bool, + declare: bool, + type_parameters: T1, + this_param: T2, + params: T3, + return_type: T4, + body: T5, + scope_id: ScopeId, + pure: bool, + ) -> Declaration<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T4: IntoIn<'a, Option>>>, + T5: IntoIn<'a, Option>>>, + { + Declaration::FunctionDeclaration(self.alloc_function_with_scope_id_and_pure( + span, + r#type, + id, + generator, + r#async, + declare, + type_parameters, + this_param, + params, + return_type, + body, + scope_id, + pure, + )) + } + /// Build a [`Declaration::ClassDeclaration`]. /// /// This node contains a [`Class`] that will be stored in the memory arena. @@ -3639,38 +4125,161 @@ impl<'a> AstBuilder<'a> { )) } - /// Build a [`Declaration::TSTypeAliasDeclaration`]. + /// Build a [`Declaration::ClassDeclaration`] with `scope_id`. + /// + /// This node contains a [`Class`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `decorators`: Decorators applied to the class. + /// * `id`: Class identifier, AKA the name + /// * `type_parameters` + /// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`]. + /// * `super_type_parameters`: Type parameters passed to super class. + /// * `implements`: Interface implementation clause for TypeScript classes. + /// * `body` + /// * `abstract`: Whether the class is abstract + /// * `declare`: Whether the class was `declare`ed + /// * `scope_id`: Id of the scope created by the [`Class`], including type parameters and + #[inline] + pub fn declaration_class_with_scope_id( + self, + span: Span, + r#type: ClassType, + decorators: Vec<'a, Decorator<'a>>, + id: Option>, + type_parameters: T1, + super_class: Option>, + super_type_parameters: T2, + implements: Option>>, + body: T3, + r#abstract: bool, + declare: bool, + scope_id: ScopeId, + ) -> Declaration<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, ClassBody<'a>>>, + { + Declaration::ClassDeclaration(self.alloc_class_with_scope_id( + span, + r#type, + decorators, + id, + type_parameters, + super_class, + super_type_parameters, + implements, + body, + r#abstract, + declare, + scope_id, + )) + } + + /// Build a [`Declaration::TSTypeAliasDeclaration`]. + /// + /// This node contains a [`TSTypeAliasDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id`: Type alias's identifier, e.g. `Foo` in `type Foo = number`. + /// * `type_parameters` + /// * `type_annotation` + /// * `declare` + #[inline] + pub fn declaration_ts_type_alias( + self, + span: Span, + id: BindingIdentifier<'a>, + type_parameters: T1, + type_annotation: TSType<'a>, + declare: bool, + ) -> Declaration<'a> + where + T1: IntoIn<'a, Option>>>, + { + Declaration::TSTypeAliasDeclaration(self.alloc_ts_type_alias_declaration( + span, + id, + type_parameters, + type_annotation, + declare, + )) + } + + /// Build a [`Declaration::TSTypeAliasDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSTypeAliasDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id`: Type alias's identifier, e.g. `Foo` in `type Foo = number`. + /// * `type_parameters` + /// * `type_annotation` + /// * `declare` + /// * `scope_id` + #[inline] + pub fn declaration_ts_type_alias_with_scope_id( + self, + span: Span, + id: BindingIdentifier<'a>, + type_parameters: T1, + type_annotation: TSType<'a>, + declare: bool, + scope_id: ScopeId, + ) -> Declaration<'a> + where + T1: IntoIn<'a, Option>>>, + { + Declaration::TSTypeAliasDeclaration(self.alloc_ts_type_alias_declaration_with_scope_id( + span, + id, + type_parameters, + type_annotation, + declare, + scope_id, + )) + } + + /// Build a [`Declaration::TSInterfaceDeclaration`]. /// - /// This node contains a [`TSTypeAliasDeclaration`] that will be stored in the memory arena. + /// This node contains a [`TSInterfaceDeclaration`] that will be stored in the memory arena. /// /// ## Parameters /// * `span`: The [`Span`] covering this node - /// * `id`: Type alias's identifier, e.g. `Foo` in `type Foo = number`. - /// * `type_parameters` - /// * `type_annotation` - /// * `declare` + /// * `id`: The identifier (name) of the interface. + /// * `extends`: Other interfaces/types this interface extends. + /// * `type_parameters`: Type parameters that get bound to the interface. + /// * `body` + /// * `declare`: `true` for `declare interface Foo {}` #[inline] - pub fn declaration_ts_type_alias( + pub fn declaration_ts_interface( self, span: Span, id: BindingIdentifier<'a>, + extends: Option>>, type_parameters: T1, - type_annotation: TSType<'a>, + body: T2, declare: bool, ) -> Declaration<'a> where T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Box<'a, TSInterfaceBody<'a>>>, { - Declaration::TSTypeAliasDeclaration(self.alloc_ts_type_alias_declaration( + Declaration::TSInterfaceDeclaration(self.alloc_ts_interface_declaration( span, id, + extends, type_parameters, - type_annotation, + body, declare, )) } - /// Build a [`Declaration::TSInterfaceDeclaration`]. + /// Build a [`Declaration::TSInterfaceDeclaration`] with `scope_id`. /// /// This node contains a [`TSInterfaceDeclaration`] that will be stored in the memory arena. /// @@ -3681,8 +4290,9 @@ impl<'a> AstBuilder<'a> { /// * `type_parameters`: Type parameters that get bound to the interface. /// * `body` /// * `declare`: `true` for `declare interface Foo {}` + /// * `scope_id` #[inline] - pub fn declaration_ts_interface( + pub fn declaration_ts_interface_with_scope_id( self, span: Span, id: BindingIdentifier<'a>, @@ -3690,18 +4300,20 @@ impl<'a> AstBuilder<'a> { type_parameters: T1, body: T2, declare: bool, + scope_id: ScopeId, ) -> Declaration<'a> where T1: IntoIn<'a, Option>>>, T2: IntoIn<'a, Box<'a, TSInterfaceBody<'a>>>, { - Declaration::TSInterfaceDeclaration(self.alloc_ts_interface_declaration( + Declaration::TSInterfaceDeclaration(self.alloc_ts_interface_declaration_with_scope_id( span, id, extends, type_parameters, body, declare, + scope_id, )) } @@ -3729,6 +4341,34 @@ impl<'a> AstBuilder<'a> { ) } + /// Build a [`Declaration::TSEnumDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSEnumDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id` + /// * `members` + /// * `const`: `true` for const enums + /// * `declare` + /// * `scope_id` + #[inline] + pub fn declaration_ts_enum_with_scope_id( + self, + span: Span, + id: BindingIdentifier<'a>, + members: Vec<'a, TSEnumMember<'a>>, + r#const: bool, + declare: bool, + scope_id: ScopeId, + ) -> Declaration<'a> { + Declaration::TSEnumDeclaration( + self.alloc_ts_enum_declaration_with_scope_id( + span, id, members, r#const, declare, scope_id, + ), + ) + } + /// Build a [`Declaration::TSModuleDeclaration`]. /// /// This node contains a [`TSModuleDeclaration`] that will be stored in the memory arena. @@ -3753,6 +4393,32 @@ impl<'a> AstBuilder<'a> { ) } + /// Build a [`Declaration::TSModuleDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSModuleDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id`: The name of the module/namespace being declared. + /// * `body` + /// * `kind`: The keyword used to define this module declaration. + /// * `declare` + /// * `scope_id` + #[inline] + pub fn declaration_ts_module_with_scope_id( + self, + span: Span, + id: TSModuleDeclarationName<'a>, + body: Option>, + kind: TSModuleDeclarationKind, + declare: bool, + scope_id: ScopeId, + ) -> Declaration<'a> { + Declaration::TSModuleDeclaration( + self.alloc_ts_module_declaration_with_scope_id(span, id, body, kind, declare, scope_id), + ) + } + /// Build a [`Declaration::TSImportEqualsDeclaration`]. /// /// This node contains a [`TSImportEqualsDeclaration`] that will be stored in the memory arena. @@ -4930,6 +5596,29 @@ impl<'a> AstBuilder<'a> { BindingPatternKind::BindingIdentifier(self.alloc_binding_identifier(span, name)) } + /// Build a [`BindingPatternKind::BindingIdentifier`] with `symbol_id`. + /// + /// This node contains a [`BindingIdentifier`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The identifier name being bound. + /// * `symbol_id`: Unique identifier for this binding. + #[inline] + pub fn binding_pattern_kind_binding_identifier_with_symbol_id( + self, + span: Span, + name: A, + symbol_id: SymbolId, + ) -> BindingPatternKind<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + BindingPatternKind::BindingIdentifier( + self.alloc_binding_identifier_with_symbol_id(span, name, symbol_id), + ) + } + /// Build a [`BindingPatternKind::ObjectPattern`]. /// /// This node contains an [`ObjectPattern`] that will be stored in the memory arena. @@ -6028,6 +6717,24 @@ impl<'a> AstBuilder<'a> { ClassElement::StaticBlock(self.alloc_static_block(span, body)) } + /// Build a [`ClassElement::StaticBlock`] with `scope_id`. + /// + /// This node contains a [`StaticBlock`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `body` + /// * `scope_id` + #[inline] + pub fn class_element_static_block_with_scope_id( + self, + span: Span, + body: Vec<'a, Statement<'a>>, + scope_id: ScopeId, + ) -> ClassElement<'a> { + ClassElement::StaticBlock(self.alloc_static_block_with_scope_id(span, body, scope_id)) + } + /// Build a [`ClassElement::MethodDefinition`]. /// /// This node contains a [`MethodDefinition`] that will be stored in the memory arena. @@ -7408,6 +8115,73 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`ExportDefaultDeclarationKind::FunctionDeclaration`] with `scope_id` and `pure`. + /// + /// This node contains a [`Function`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `id`: The function identifier. [`None`] for anonymous function expressions. + /// * `generator`: Is this a generator function? + /// * `async` + /// * `declare` + /// * `type_parameters` + /// * `this_param`: Declaring `this` in a Function + /// * `params`: Function parameters. + /// * `return_type`: The TypeScript return type annotation. + /// * `body`: The function body. + /// * `scope_id` + /// * `pure`: `true` if the function is marked with a `/*#__NO_SIDE_EFFECTS__*/` comment + #[inline] + pub fn export_default_declaration_kind_function_declaration_with_scope_id_and_pure< + T1, + T2, + T3, + T4, + T5, + >( + self, + span: Span, + r#type: FunctionType, + id: Option>, + generator: bool, + r#async: bool, + declare: bool, + type_parameters: T1, + this_param: T2, + params: T3, + return_type: T4, + body: T5, + scope_id: ScopeId, + pure: bool, + ) -> ExportDefaultDeclarationKind<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T4: IntoIn<'a, Option>>>, + T5: IntoIn<'a, Option>>>, + { + ExportDefaultDeclarationKind::FunctionDeclaration( + self.alloc_function_with_scope_id_and_pure( + span, + r#type, + id, + generator, + r#async, + declare, + type_parameters, + this_param, + params, + return_type, + body, + scope_id, + pure, + ), + ) + } + /// Build an [`ExportDefaultDeclarationKind::ClassDeclaration`]. /// /// This node contains a [`Class`] that will be stored in the memory arena. @@ -7459,6 +8233,60 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`ExportDefaultDeclarationKind::ClassDeclaration`] with `scope_id`. + /// + /// This node contains a [`Class`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type` + /// * `decorators`: Decorators applied to the class. + /// * `id`: Class identifier, AKA the name + /// * `type_parameters` + /// * `super_class`: Super class. When present, this will usually be an [`IdentifierReference`]. + /// * `super_type_parameters`: Type parameters passed to super class. + /// * `implements`: Interface implementation clause for TypeScript classes. + /// * `body` + /// * `abstract`: Whether the class is abstract + /// * `declare`: Whether the class was `declare`ed + /// * `scope_id`: Id of the scope created by the [`Class`], including type parameters and + #[inline] + pub fn export_default_declaration_kind_class_declaration_with_scope_id( + self, + span: Span, + r#type: ClassType, + decorators: Vec<'a, Decorator<'a>>, + id: Option>, + type_parameters: T1, + super_class: Option>, + super_type_parameters: T2, + implements: Option>>, + body: T3, + r#abstract: bool, + declare: bool, + scope_id: ScopeId, + ) -> ExportDefaultDeclarationKind<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, ClassBody<'a>>>, + { + ExportDefaultDeclarationKind::ClassDeclaration(self.alloc_class_with_scope_id( + span, + r#type, + decorators, + id, + type_parameters, + super_class, + super_type_parameters, + implements, + body, + r#abstract, + declare, + scope_id, + )) + } + /// Build an [`ExportDefaultDeclarationKind::TSInterfaceDeclaration`]. /// /// This node contains a [`TSInterfaceDeclaration`] that will be stored in the memory arena. @@ -7494,6 +8322,46 @@ impl<'a> AstBuilder<'a> { )) } + /// Build an [`ExportDefaultDeclarationKind::TSInterfaceDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSInterfaceDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id`: The identifier (name) of the interface. + /// * `extends`: Other interfaces/types this interface extends. + /// * `type_parameters`: Type parameters that get bound to the interface. + /// * `body` + /// * `declare`: `true` for `declare interface Foo {}` + /// * `scope_id` + #[inline] + pub fn export_default_declaration_kind_ts_interface_declaration_with_scope_id( + self, + span: Span, + id: BindingIdentifier<'a>, + extends: Option>>, + type_parameters: T1, + body: T2, + declare: bool, + scope_id: ScopeId, + ) -> ExportDefaultDeclarationKind<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Box<'a, TSInterfaceBody<'a>>>, + { + ExportDefaultDeclarationKind::TSInterfaceDeclaration( + self.alloc_ts_interface_declaration_with_scope_id( + span, + id, + extends, + type_parameters, + body, + declare, + scope_id, + ), + ) + } + /// Build a [`ModuleExportName::IdentifierName`]. /// /// ## Parameters @@ -7524,6 +8392,29 @@ impl<'a> AstBuilder<'a> { ModuleExportName::IdentifierReference(self.identifier_reference(span, name)) } + /// Build a [`ModuleExportName::IdentifierReference`] with `reference_id`. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn module_export_name_identifier_reference_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> ModuleExportName<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + ModuleExportName::IdentifierReference(self.identifier_reference_with_reference_id( + span, + name, + reference_id, + )) + } + /// Build a [`ModuleExportName::StringLiteral`]. /// /// ## Parameters @@ -8039,6 +8930,31 @@ impl<'a> AstBuilder<'a> { JSXElementName::IdentifierReference(self.alloc_identifier_reference(span, name)) } + /// Build a [`JSXElementName::IdentifierReference`] with `reference_id`. + /// + /// This node contains an [`IdentifierReference`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn jsx_element_name_identifier_reference_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> JSXElementName<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + JSXElementName::IdentifierReference(self.alloc_identifier_reference_with_reference_id( + span, + name, + reference_id, + )) + } + /// Build a [`JSXElementName::NamespacedName`]. /// /// This node contains a [`JSXNamespacedName`] that will be stored in the memory arena. @@ -8177,6 +9093,29 @@ impl<'a> AstBuilder<'a> { JSXMemberExpressionObject::IdentifierReference(self.alloc_identifier_reference(span, name)) } + /// Build a [`JSXMemberExpressionObject::IdentifierReference`] with `reference_id`. + /// + /// This node contains an [`IdentifierReference`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn jsx_member_expression_object_identifier_reference_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> JSXMemberExpressionObject<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + JSXMemberExpressionObject::IdentifierReference( + self.alloc_identifier_reference_with_reference_id(span, name, reference_id), + ) + } + /// Build a [`JSXMemberExpressionObject::MemberExpression`]. /// /// This node contains a [`JSXMemberExpression`] that will be stored in the memory arena. @@ -9255,6 +10194,37 @@ impl<'a> AstBuilder<'a> { )) } + /// Build a [`TSType::TSConditionalType`] with `scope_id`. + /// + /// This node contains a [`TSConditionalType`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `check_type`: The type before `extends` in the test expression. + /// * `extends_type`: The type `check_type` is being tested against. + /// * `true_type`: The type evaluated to if the test is true. + /// * `false_type`: The type evaluated to if the test is false. + /// * `scope_id` + #[inline] + pub fn ts_type_conditional_type_with_scope_id( + self, + span: Span, + check_type: TSType<'a>, + extends_type: TSType<'a>, + true_type: TSType<'a>, + false_type: TSType<'a>, + scope_id: ScopeId, + ) -> TSType<'a> { + TSType::TSConditionalType(self.alloc_ts_conditional_type_with_scope_id( + span, + check_type, + extends_type, + true_type, + false_type, + scope_id, + )) + } + /// Build a [`TSType::TSConstructorType`]. /// /// This node contains a [`TSConstructorType`] that will be stored in the memory arena. @@ -9452,6 +10422,43 @@ impl<'a> AstBuilder<'a> { )) } + /// Build a [`TSType::TSMappedType`] with `scope_id`. + /// + /// This node contains a [`TSMappedType`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type_parameter`: Key type parameter, e.g. `P` in `[P in keyof T]`. + /// * `name_type` + /// * `type_annotation` + /// * `optional`: Optional modifier on type annotation + /// * `readonly`: Readonly modifier before keyed index signature + /// * `scope_id` + #[inline] + pub fn ts_type_mapped_type_with_scope_id( + self, + span: Span, + type_parameter: T1, + name_type: Option>, + type_annotation: Option>, + optional: TSMappedTypeModifierOperator, + readonly: TSMappedTypeModifierOperator, + scope_id: ScopeId, + ) -> TSType<'a> + where + T1: IntoIn<'a, Box<'a, TSTypeParameter<'a>>>, + { + TSType::TSMappedType(self.alloc_ts_mapped_type_with_scope_id( + span, + type_parameter, + name_type, + type_annotation, + optional, + readonly, + scope_id, + )) + } + /// Build a [`TSType::TSNamedTupleMember`]. /// /// This node contains a [`TSNamedTupleMember`] that will be stored in the memory arena. @@ -10537,6 +11544,31 @@ impl<'a> AstBuilder<'a> { TSTypeName::IdentifierReference(self.alloc_identifier_reference(span, name)) } + /// Build a [`TSTypeName::IdentifierReference`] with `reference_id`. + /// + /// This node contains an [`IdentifierReference`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The name of the identifier being referenced. + /// * `reference_id`: Reference ID + #[inline] + pub fn ts_type_name_identifier_reference_with_reference_id( + self, + span: Span, + name: A, + reference_id: ReferenceId, + ) -> TSTypeName<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + TSTypeName::IdentifierReference(self.alloc_identifier_reference_with_reference_id( + span, + name, + reference_id, + )) + } + /// Build a [`TSTypeName::QualifiedName`]. /// /// This node contains a [`TSQualifiedName`] that will be stored in the memory arena. @@ -11257,6 +12289,41 @@ impl<'a> AstBuilder<'a> { )) } + /// Build a [`TSSignature::TSConstructSignatureDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSConstructSignatureDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `type_parameters` + /// * `params` + /// * `return_type` + /// * `scope_id` + #[inline] + pub fn ts_signature_construct_signature_declaration_with_scope_id( + self, + span: Span, + type_parameters: T1, + params: T2, + return_type: T3, + scope_id: ScopeId, + ) -> TSSignature<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T3: IntoIn<'a, Option>>>, + { + TSSignature::TSConstructSignatureDeclaration( + self.alloc_ts_construct_signature_declaration_with_scope_id( + span, + type_parameters, + params, + return_type, + scope_id, + ), + ) + } + /// Build a [`TSSignature::TSMethodSignature`]. /// /// This node contains a [`TSMethodSignature`] that will be stored in the memory arena. @@ -11303,6 +12370,55 @@ impl<'a> AstBuilder<'a> { )) } + /// Build a [`TSSignature::TSMethodSignature`] with `scope_id`. + /// + /// This node contains a [`TSMethodSignature`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `key` + /// * `computed` + /// * `optional` + /// * `kind` + /// * `type_parameters` + /// * `this_param` + /// * `params` + /// * `return_type` + /// * `scope_id` + #[inline] + pub fn ts_signature_method_signature_with_scope_id( + self, + span: Span, + key: PropertyKey<'a>, + computed: bool, + optional: bool, + kind: TSMethodSignatureKind, + type_parameters: T1, + this_param: T2, + params: T3, + return_type: T4, + scope_id: ScopeId, + ) -> TSSignature<'a> + where + T1: IntoIn<'a, Option>>>, + T2: IntoIn<'a, Option>>>, + T3: IntoIn<'a, Box<'a, FormalParameters<'a>>>, + T4: IntoIn<'a, Option>>>, + { + TSSignature::TSMethodSignature(self.alloc_ts_method_signature_with_scope_id( + span, + key, + computed, + optional, + kind, + type_parameters, + this_param, + params, + return_type, + scope_id, + )) + } + /// Build a [`TSIndexSignature`]. /// /// If you want the built node to be allocated in the memory arena, use [`AstBuilder::alloc_ts_index_signature`] instead. @@ -12044,6 +13160,27 @@ impl<'a> AstBuilder<'a> { TSModuleDeclarationName::Identifier(self.binding_identifier(span, name)) } + /// Build a [`TSModuleDeclarationName::Identifier`] with `symbol_id`. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `name`: The identifier name being bound. + /// * `symbol_id`: Unique identifier for this binding. + #[inline] + pub fn ts_module_declaration_name_identifier_with_symbol_id( + self, + span: Span, + name: A, + symbol_id: SymbolId, + ) -> TSModuleDeclarationName<'a> + where + A: IntoIn<'a, Atom<'a>>, + { + TSModuleDeclarationName::Identifier( + self.binding_identifier_with_symbol_id(span, name, symbol_id), + ) + } + /// Build a [`TSModuleDeclarationName::StringLiteral`]. /// /// ## Parameters @@ -12087,6 +13224,32 @@ impl<'a> AstBuilder<'a> { ) } + /// Build a [`TSModuleDeclarationBody::TSModuleDeclaration`] with `scope_id`. + /// + /// This node contains a [`TSModuleDeclaration`] that will be stored in the memory arena. + /// + /// ## Parameters + /// * `span`: The [`Span`] covering this node + /// * `id`: The name of the module/namespace being declared. + /// * `body` + /// * `kind`: The keyword used to define this module declaration. + /// * `declare` + /// * `scope_id` + #[inline] + pub fn ts_module_declaration_body_module_declaration_with_scope_id( + self, + span: Span, + id: TSModuleDeclarationName<'a>, + body: Option>, + kind: TSModuleDeclarationKind, + declare: bool, + scope_id: ScopeId, + ) -> TSModuleDeclarationBody<'a> { + TSModuleDeclarationBody::TSModuleDeclaration( + self.alloc_ts_module_declaration_with_scope_id(span, id, body, kind, declare, scope_id), + ) + } + /// Build a [`TSModuleDeclarationBody::TSModuleBlock`]. /// /// This node contains a [`TSModuleBlock`] that will be stored in the memory arena. diff --git a/tasks/ast_tools/src/generators/ast_builder.rs b/tasks/ast_tools/src/generators/ast_builder.rs index 520559604df76..67c4e8932f177 100644 --- a/tasks/ast_tools/src/generators/ast_builder.rs +++ b/tasks/ast_tools/src/generators/ast_builder.rs @@ -421,7 +421,6 @@ fn generate_builder_methods_for_enum(enum_def: &EnumDef, schema: &Schema) -> Tok } /// Generate builder method for an enum variant. -#[expect(clippy::similar_names)] fn generate_builder_method_for_enum_variant( enum_def: &EnumDef, variant: &VariantDef, @@ -433,38 +432,96 @@ fn generate_builder_method_for_enum_variant( variant_type = box_def.inner_type(schema); is_boxed = true; } - let TypeDef::Struct(variant_type) = variant_type else { panic!("Unsupported!") }; + let TypeDef::Struct(struct_def) = variant_type else { panic!("Unsupported!") }; let (mut params, generic_params, where_clause, has_default_fields) = - get_struct_params(variant_type, schema); - if has_default_fields { - params.retain(|param| !param.is_default); + get_struct_params(struct_def, schema); + + let fn_name = enum_variant_builder_name(enum_def, variant); + let variant_ident = variant.ident(); + + let output = has_default_fields.then(|| { + let default_params = params.iter().filter(|param| param.is_default); + let fn_name_postfix = format!( + "_with_{}", + default_params.clone().map(|param| param.field.name()).join("_and_") + ); + let doc_postfix = + format!(" with `{}`", default_params.map(|param| param.field.name()).join("` and `")); + generate_builder_method_for_enum_variant_impl( + enum_def, + struct_def, + &variant_ident, + ¶ms, + &fn_name, + &generic_params, + &where_clause, + &fn_name_postfix, + &doc_postfix, + schema, + is_boxed, + ) + }); + + params.retain(|param| !param.is_default); + let mut output2 = generate_builder_method_for_enum_variant_impl( + enum_def, + struct_def, + &variant_ident, + ¶ms, + &fn_name, + &generic_params, + &where_clause, + "", + "", + schema, + is_boxed, + ); + + if let Some(output) = output { + output2.extend(output); } + output2 +} + +#[expect(clippy::too_many_arguments, clippy::similar_names)] +fn generate_builder_method_for_enum_variant_impl( + enum_def: &EnumDef, + struct_def: &StructDef, + variant_ident: &Ident, + params: &[Param], + fn_name: &str, + generic_params: &TokenStream, + where_clause: &TokenStream, + fn_name_postfix: &str, + doc_postfix: &str, + schema: &Schema, + is_boxed: bool, +) -> TokenStream { + let fn_name = format_ident!("{}{}", fn_name, fn_name_postfix); let fn_params = params.iter().map(|param| ¶m.fn_param); let args = params.iter().map(|param| ¶m.ident); let enum_ident = enum_def.ident(); let enum_ty = enum_def.ty(schema); - let fn_name = enum_variant_builder_name(enum_def, variant); - let variant_ident = variant.ident(); - let inner_builder_name = struct_builder_name(&variant_type.snake_name(), is_boxed); + let inner_builder_name = format!("{}{fn_name_postfix}", struct_def.snake_name()); + let inner_builder_name = struct_builder_name(&inner_builder_name, is_boxed); // Generate doc comments let enum_name = enum_def.name(); let article_enum = article_for(enum_name); - let variant_name = variant.ident(); - let fn_doc1 = format!(" Build {article_enum} [`{enum_name}::{variant_name}`]."); + let fn_doc1 = format!(" Build {article_enum} [`{enum_name}::{variant_ident}`]{doc_postfix}."); let mut fn_docs = quote!( #[doc = #fn_doc1] ); if is_boxed { - let variant_type_name = variant_type.name(); + let variant_type_name = struct_def.name(); let article_variant = article_for(variant_type_name); let fn_doc2 = format!( " This node contains {article_variant} [`{variant_type_name}`] that will be stored in the memory arena." ); fn_docs.extend(quote!( #[doc = ""] #[doc = #fn_doc2] )); } - let params_docs = generate_doc_comment_for_params(¶ms); + let params_docs = generate_doc_comment_for_params(params); quote! { ///@@line_break @@ -492,7 +549,7 @@ fn struct_builder_name(snake_name: &str, does_alloc: bool) -> Ident { } /// Get name of enum variant builder method. -fn enum_variant_builder_name(enum_def: &EnumDef, variant: &VariantDef) -> Ident { +fn enum_variant_builder_name(enum_def: &EnumDef, variant: &VariantDef) -> String { let enum_name = enum_def.snake_name(); let variant_name = variant.snake_name(); @@ -509,7 +566,7 @@ fn enum_variant_builder_name(enum_def: &EnumDef, variant: &VariantDef) -> Ident &variant_name }; - format_ident!("{enum_name}_{variant_name}") + format!("{enum_name}_{variant_name}") } /// Wrap the value of a default field in `Cell::new(...)` or `Some(...)` if necessary.