docs(ast): enforce doc comments on generated ASTBuilder methods (#6713)

Part of https://github.com/oxc-project/backlog/issues/130
This commit is contained in:
DonIsaac 2024-10-21 05:28:54 +00:00
parent 661dfd2026
commit 8d27e2daab
4 changed files with 82 additions and 1 deletions

View file

@ -4,6 +4,7 @@
clippy::too_many_arguments, clippy::too_many_arguments,
clippy::unused_self, clippy::unused_self,
)] )]
#![warn(missing_docs)]
use std::mem; use std::mem;
@ -27,26 +28,33 @@ impl<'a, T> FromIn<'a, NONE> for Option<Box<'a, T>> {
} }
impl<'a> AstBuilder<'a> { impl<'a> AstBuilder<'a> {
/// Create a new AST builder that will allocate nodes in the given allocator.
#[inline] #[inline]
pub fn new(allocator: &'a Allocator) -> Self { pub fn new(allocator: &'a Allocator) -> Self {
Self { allocator } Self { allocator }
} }
/// Move a value into the memory arena.
#[inline] #[inline]
pub fn alloc<T>(self, value: T) -> Box<'a, T> { pub fn alloc<T>(self, value: T) -> Box<'a, T> {
Box::new_in(value, self.allocator) Box::new_in(value, self.allocator)
} }
/// Create a new empty [`Vec`] that stores its elements in the memory arena.
#[inline] #[inline]
pub fn vec<T>(self) -> Vec<'a, T> { pub fn vec<T>(self) -> Vec<'a, T> {
Vec::new_in(self.allocator) Vec::new_in(self.allocator)
} }
/// Create a new empty [`Vec`] that stores its elements in the memory arena.
/// Enough memory will be pre-allocated to store at least `capacity`
/// elements.
#[inline] #[inline]
pub fn vec_with_capacity<T>(self, capacity: usize) -> Vec<'a, T> { pub fn vec_with_capacity<T>(self, capacity: usize) -> Vec<'a, T> {
Vec::with_capacity_in(capacity, self.allocator) Vec::with_capacity_in(capacity, self.allocator)
} }
/// Create a new arena-allocated [`Vec`] initialized with a single element.
#[inline] #[inline]
pub fn vec1<T>(self, value: T) -> Vec<'a, T> { pub fn vec1<T>(self, value: T) -> Vec<'a, T> {
let mut vec = self.vec_with_capacity(1); let mut vec = self.vec_with_capacity(1);
@ -54,16 +62,20 @@ impl<'a> AstBuilder<'a> {
vec vec
} }
/// Collect an iterator into a new arena-allocated [`Vec`].
#[inline] #[inline]
pub fn vec_from_iter<T, I: IntoIterator<Item = T>>(self, iter: I) -> Vec<'a, T> { pub fn vec_from_iter<T, I: IntoIterator<Item = T>>(self, iter: I) -> Vec<'a, T> {
Vec::from_iter_in(iter, self.allocator) Vec::from_iter_in(iter, self.allocator)
} }
/// Move a string slice into the memory arena, returning a reference to the slice
/// in the heap.
#[inline] #[inline]
pub fn str(self, value: &str) -> &'a str { pub fn str(self, value: &str) -> &'a str {
String::from_str_in(value, self.allocator).into_bump_str() String::from_str_in(value, self.allocator).into_bump_str()
} }
/// Allocate an [`Atom`] from a string slice.
#[inline] #[inline]
pub fn atom(self, value: &str) -> Atom<'a> { pub fn atom(self, value: &str) -> Atom<'a> {
Atom::from(String::from_str_in(value, self.allocator).into_bump_str()) Atom::from(String::from_str_in(value, self.allocator).into_bump_str())
@ -80,19 +92,24 @@ impl<'a> AstBuilder<'a> {
unsafe { std::mem::transmute_copy(src) } unsafe { std::mem::transmute_copy(src) }
} }
/// Moves the expression out by replacing it with a null expression. /// Moves the expression out by replacing it with a [null
/// expression](Expression::NullLiteral).
#[inline] #[inline]
pub fn move_expression(self, expr: &mut Expression<'a>) -> Expression<'a> { pub fn move_expression(self, expr: &mut Expression<'a>) -> Expression<'a> {
let null_expr = self.expression_null_literal(expr.span()); let null_expr = self.expression_null_literal(expr.span());
mem::replace(expr, null_expr) mem::replace(expr, null_expr)
} }
/// Moves the statement out by replacing it with an [empty
/// statement](Statement::EmptyStatement).
#[inline] #[inline]
pub fn move_statement(self, stmt: &mut Statement<'a>) -> Statement<'a> { pub fn move_statement(self, stmt: &mut Statement<'a>) -> Statement<'a> {
let empty_stmt = self.empty_statement(stmt.span()); let empty_stmt = self.empty_statement(stmt.span());
mem::replace(stmt, Statement::EmptyStatement(self.alloc(empty_stmt))) mem::replace(stmt, Statement::EmptyStatement(self.alloc(empty_stmt)))
} }
/// Moves the assignment target out by replacing it with a dummy target with
/// no name and an empty [`Span`].
#[inline] #[inline]
pub fn move_assignment_target(self, target: &mut AssignmentTarget<'a>) -> AssignmentTarget<'a> { pub fn move_assignment_target(self, target: &mut AssignmentTarget<'a>) -> AssignmentTarget<'a> {
let dummy = let dummy =
@ -100,6 +117,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(target, dummy.into()) mem::replace(target, dummy.into())
} }
/// Move a declaration out by replacing it with an empty [variable
/// declaration](Declaration::VariableDeclaration).
#[inline] #[inline]
pub fn move_declaration(self, decl: &mut Declaration<'a>) -> Declaration<'a> { pub fn move_declaration(self, decl: &mut Declaration<'a>) -> Declaration<'a> {
let empty_decl = self.variable_declaration( let empty_decl = self.variable_declaration(
@ -112,6 +131,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(decl, empty_decl) mem::replace(decl, empty_decl)
} }
/// Move a variable declaration out by replacing it with an empty [variable
/// declaration](VariableDeclaration).
#[inline] #[inline]
pub fn move_variable_declaration( pub fn move_variable_declaration(
self, self,
@ -126,6 +147,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(decl, empty_decl) mem::replace(decl, empty_decl)
} }
/// Move an array element out by replacing it with an
/// [elision](ArrayExpressionElement::Elision).
pub fn move_array_expression_element( pub fn move_array_expression_element(
self, self,
element: &mut ArrayExpressionElement<'a>, element: &mut ArrayExpressionElement<'a>,
@ -134,6 +157,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(element, empty_element) mem::replace(element, empty_element)
} }
/// Take the contents of a arena-allocated [`Vec`], leaving an empty vec in
/// its place. This is akin to [`std::mem::take`].
#[inline] #[inline]
pub fn move_vec<T>(self, vec: &mut Vec<'a, T>) -> Vec<'a, T> { pub fn move_vec<T>(self, vec: &mut Vec<'a, T>) -> Vec<'a, T> {
mem::replace(vec, self.vec()) mem::replace(vec, self.vec())
@ -160,6 +185,8 @@ impl<'a> AstBuilder<'a> {
/* ---------- Functions ---------- */ /* ---------- Functions ---------- */
/// Create a [`FormalParameter`] with no type annotations, modifiers,
/// decorators, or initializer.
#[inline] #[inline]
pub fn plain_formal_parameter( pub fn plain_formal_parameter(
self, self,
@ -169,6 +196,8 @@ impl<'a> AstBuilder<'a> {
self.formal_parameter(span, self.vec(), pattern, None, false, false) self.formal_parameter(span, self.vec(), pattern, None, false, false)
} }
/// Create a [`Function`] with no "extras", i.e. decorators, type
/// annotations, accessibility modifiers, etc.
#[inline] #[inline]
pub fn plain_function( pub fn plain_function(
self, self,
@ -195,6 +224,7 @@ impl<'a> AstBuilder<'a> {
/* ---------- Modules ---------- */ /* ---------- Modules ---------- */
/// Create an empty [`ExportNamedDeclaration`] with no modifiers
#[inline] #[inline]
pub fn plain_export_named_declaration_declaration( pub fn plain_export_named_declaration_declaration(
self, self,
@ -211,6 +241,8 @@ impl<'a> AstBuilder<'a> {
)) ))
} }
/// Create an [`ExportNamedDeclaration`] with no modifiers that contains a
/// set of [exported symbol names](ExportSpecifier).
#[inline] #[inline]
pub fn plain_export_named_declaration( pub fn plain_export_named_declaration(
self, self,
@ -230,6 +262,8 @@ impl<'a> AstBuilder<'a> {
/* ---------- TypeScript ---------- */ /* ---------- TypeScript ---------- */
/// Create a [`TSInterfaceHeritage`] that extends from the given list of
/// other interfaces.
#[inline] #[inline]
pub fn ts_interface_heritages( pub fn ts_interface_heritages(
self, self,
@ -245,11 +279,13 @@ impl<'a> AstBuilder<'a> {
) )
} }
/// Create an [`JSXOpeningElement`].
#[inline] #[inline]
pub fn jsx_opening_fragment(self, span: Span) -> JSXOpeningFragment { pub fn jsx_opening_fragment(self, span: Span) -> JSXOpeningFragment {
JSXOpeningFragment { span } JSXOpeningFragment { span }
} }
/// Create an [`JSXClosingElement`].
#[inline] #[inline]
pub fn jsx_closing_fragment(self, span: Span) -> JSXClosingFragment { pub fn jsx_closing_fragment(self, span: Span) -> JSXClosingFragment {
JSXClosingFragment { span } JSXClosingFragment { span }

View file

@ -1,3 +1,4 @@
//! AST node factories
// Auto-generated code, DO NOT EDIT DIRECTLY! // Auto-generated code, DO NOT EDIT DIRECTLY!
// To edit this generated file you have to edit `tasks/ast_tools/src/generators/ast_builder.rs` // To edit this generated file you have to edit `tasks/ast_tools/src/generators/ast_builder.rs`
@ -6,6 +7,7 @@
clippy::too_many_arguments, clippy::too_many_arguments,
clippy::fn_params_excessive_bools clippy::fn_params_excessive_bools
)] )]
#![warn(missing_docs)]
use oxc_allocator::{Allocator, Box, IntoIn, Vec}; use oxc_allocator::{Allocator, Box, IntoIn, Vec};
@ -15,6 +17,7 @@ use crate::ast::*;
/// AST builder for creating AST nodes /// AST builder for creating AST nodes
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct AstBuilder<'a> { pub struct AstBuilder<'a> {
/// The memory allocator used to allocate AST nodes in the arena.
pub allocator: &'a Allocator, pub allocator: &'a Allocator,
} }
@ -1484,6 +1487,7 @@ impl<'a> AstBuilder<'a> {
Expression::TSInstantiationExpression(inner.into_in(self.allocator)) Expression::TSInstantiationExpression(inner.into_in(self.allocator))
} }
/// Convert a [`MemberExpression`] into the corresponding variant of [`Expression`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn expression_member(self, inner: MemberExpression<'a>) -> Expression<'a> { pub fn expression_member(self, inner: MemberExpression<'a>) -> Expression<'a> {
Expression::from(inner) Expression::from(inner)
@ -1725,6 +1729,7 @@ impl<'a> AstBuilder<'a> {
ArrayExpressionElement::Elision(inner.into_in(self.allocator)) ArrayExpressionElement::Elision(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`ArrayExpressionElement`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn array_expression_element_expression( pub fn array_expression_element_expression(
self, self,
@ -1964,6 +1969,7 @@ impl<'a> AstBuilder<'a> {
PropertyKey::PrivateIdentifier(inner.into_in(self.allocator)) PropertyKey::PrivateIdentifier(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`PropertyKey`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn property_key_expression(self, inner: Expression<'a>) -> PropertyKey<'a> { pub fn property_key_expression(self, inner: Expression<'a>) -> PropertyKey<'a> {
PropertyKey::from(inner) PropertyKey::from(inner)
@ -2509,6 +2515,7 @@ impl<'a> AstBuilder<'a> {
Argument::SpreadElement(inner.into_in(self.allocator)) Argument::SpreadElement(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`Argument`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn argument_expression(self, inner: Expression<'a>) -> Argument<'a> { pub fn argument_expression(self, inner: Expression<'a>) -> Argument<'a> {
Argument::from(inner) Argument::from(inner)
@ -2790,6 +2797,7 @@ impl<'a> AstBuilder<'a> {
Box::new_in(self.assignment_expression(span, operator, left, right), self.allocator) Box::new_in(self.assignment_expression(span, operator, left, right), self.allocator)
} }
/// Convert a [`SimpleAssignmentTarget`] into the corresponding variant of [`AssignmentTarget`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn assignment_target_simple( pub fn assignment_target_simple(
self, self,
@ -2798,6 +2806,7 @@ impl<'a> AstBuilder<'a> {
AssignmentTarget::from(inner) AssignmentTarget::from(inner)
} }
/// Convert a [`AssignmentTargetPattern`] into the corresponding variant of [`AssignmentTarget`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn assignment_target_assignment_target_pattern( pub fn assignment_target_assignment_target_pattern(
self, self,
@ -3006,6 +3015,7 @@ impl<'a> AstBuilder<'a> {
SimpleAssignmentTarget::TSInstantiationExpression(inner.into_in(self.allocator)) SimpleAssignmentTarget::TSInstantiationExpression(inner.into_in(self.allocator))
} }
/// Convert a [`MemberExpression`] into the corresponding variant of [`SimpleAssignmentTarget`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn simple_assignment_target_member_expression( pub fn simple_assignment_target_member_expression(
self, self,
@ -3226,6 +3236,7 @@ impl<'a> AstBuilder<'a> {
AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(inner.into_in(self.allocator)) AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(inner.into_in(self.allocator))
} }
/// Convert a [`AssignmentTarget`] into the corresponding variant of [`AssignmentTargetMaybeDefault`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn assignment_target_maybe_default_assignment_target( pub fn assignment_target_maybe_default_assignment_target(
self, self,
@ -3556,6 +3567,7 @@ impl<'a> AstBuilder<'a> {
ChainElement::CallExpression(inner.into_in(self.allocator)) ChainElement::CallExpression(inner.into_in(self.allocator))
} }
/// Convert a [`MemberExpression`] into the corresponding variant of [`ChainElement`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn chain_element_member_expression(self, inner: MemberExpression<'a>) -> ChainElement<'a> { pub fn chain_element_member_expression(self, inner: MemberExpression<'a>) -> ChainElement<'a> {
ChainElement::from(inner) ChainElement::from(inner)
@ -4054,11 +4066,13 @@ impl<'a> AstBuilder<'a> {
Statement::WithStatement(inner.into_in(self.allocator)) Statement::WithStatement(inner.into_in(self.allocator))
} }
/// Convert a [`Declaration`] into the corresponding variant of [`Statement`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn statement_declaration(self, inner: Declaration<'a>) -> Statement<'a> { pub fn statement_declaration(self, inner: Declaration<'a>) -> Statement<'a> {
Statement::from(inner) Statement::from(inner)
} }
/// Convert a [`ModuleDeclaration`] into the corresponding variant of [`Statement`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn statement_module_declaration(self, inner: ModuleDeclaration<'a>) -> Statement<'a> { pub fn statement_module_declaration(self, inner: ModuleDeclaration<'a>) -> Statement<'a> {
Statement::from(inner) Statement::from(inner)
@ -4832,6 +4846,7 @@ impl<'a> AstBuilder<'a> {
ForStatementInit::VariableDeclaration(inner.into_in(self.allocator)) ForStatementInit::VariableDeclaration(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`ForStatementInit`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn for_statement_init_expression(self, inner: Expression<'a>) -> ForStatementInit<'a> { pub fn for_statement_init_expression(self, inner: Expression<'a>) -> ForStatementInit<'a> {
ForStatementInit::from(inner) ForStatementInit::from(inner)
@ -4911,6 +4926,7 @@ impl<'a> AstBuilder<'a> {
ForStatementLeft::VariableDeclaration(inner.into_in(self.allocator)) ForStatementLeft::VariableDeclaration(inner.into_in(self.allocator))
} }
/// Convert a [`AssignmentTarget`] into the corresponding variant of [`ForStatementLeft`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn for_statement_left_assignment_target( pub fn for_statement_left_assignment_target(
self, self,
@ -7866,6 +7882,7 @@ impl<'a> AstBuilder<'a> {
ExportDefaultDeclarationKind::TSInterfaceDeclaration(inner.into_in(self.allocator)) ExportDefaultDeclarationKind::TSInterfaceDeclaration(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`ExportDefaultDeclarationKind`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn export_default_declaration_kind_expression( pub fn export_default_declaration_kind_expression(
self, self,
@ -8183,6 +8200,7 @@ impl<'a> AstBuilder<'a> {
TSEnumMemberName::StaticNumericLiteral(inner.into_in(self.allocator)) TSEnumMemberName::StaticNumericLiteral(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`TSEnumMemberName`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn ts_enum_member_name_expression(self, inner: Expression<'a>) -> TSEnumMemberName<'a> { pub fn ts_enum_member_name_expression(self, inner: Expression<'a>) -> TSEnumMemberName<'a> {
TSEnumMemberName::from(inner) TSEnumMemberName::from(inner)
@ -9879,6 +9897,7 @@ impl<'a> AstBuilder<'a> {
TSTupleElement::TSRestType(inner.into_in(self.allocator)) TSTupleElement::TSRestType(inner.into_in(self.allocator))
} }
/// Convert a [`TSType`] into the corresponding variant of [`TSTupleElement`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn ts_tuple_element_type(self, inner: TSType<'a>) -> TSTupleElement<'a> { pub fn ts_tuple_element_type(self, inner: TSType<'a>) -> TSTupleElement<'a> {
TSTupleElement::from(inner) TSTupleElement::from(inner)
@ -11755,6 +11774,7 @@ impl<'a> AstBuilder<'a> {
TSTypeQueryExprName::TSImportType(inner.into_in(self.allocator)) TSTypeQueryExprName::TSImportType(inner.into_in(self.allocator))
} }
/// Convert a [`TSTypeName`] into the corresponding variant of [`TSTypeQueryExprName`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn ts_type_query_expr_name_type_name( pub fn ts_type_query_expr_name_type_name(
self, self,
@ -12383,6 +12403,7 @@ impl<'a> AstBuilder<'a> {
TSModuleReference::ExternalModuleReference(inner.into_in(self.allocator)) TSModuleReference::ExternalModuleReference(inner.into_in(self.allocator))
} }
/// Convert a [`TSTypeName`] into the corresponding variant of [`TSModuleReference`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn ts_module_reference_type_name(self, inner: TSTypeName<'a>) -> TSModuleReference<'a> { pub fn ts_module_reference_type_name(self, inner: TSTypeName<'a>) -> TSModuleReference<'a> {
TSModuleReference::from(inner) TSModuleReference::from(inner)
@ -13212,6 +13233,7 @@ impl<'a> AstBuilder<'a> {
JSXExpression::EmptyExpression(inner.into_in(self.allocator)) JSXExpression::EmptyExpression(inner.into_in(self.allocator))
} }
/// Convert a [`Expression`] into the corresponding variant of [`JSXExpression`] without copying or re-allocating memory.
#[inline] #[inline]
pub fn jsx_expression_expression(self, inner: Expression<'a>) -> JSXExpression<'a> { pub fn jsx_expression_expression(self, inner: Expression<'a>) -> JSXExpression<'a> {
JSXExpression::from(inner) JSXExpression::from(inner)

View file

@ -37,6 +37,7 @@ impl Generator for AstBuilderGenerator {
GeneratorOutput::Rust { GeneratorOutput::Rust {
path: output(crate::AST_CRATE, "ast_builder.rs"), path: output(crate::AST_CRATE, "ast_builder.rs"),
tokens: quote! { tokens: quote! {
//! AST node factories
#header #header
#![allow( #![allow(
@ -44,6 +45,7 @@ impl Generator for AstBuilderGenerator {
clippy::too_many_arguments, clippy::too_many_arguments,
clippy::fn_params_excessive_bools, clippy::fn_params_excessive_bools,
)] )]
#![warn(missing_docs)]
///@@line_break ///@@line_break
use oxc_allocator::{Allocator, Box, IntoIn, Vec}; use oxc_allocator::{Allocator, Box, IntoIn, Vec};
@ -56,6 +58,7 @@ impl Generator for AstBuilderGenerator {
/// AST builder for creating AST nodes /// AST builder for creating AST nodes
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct AstBuilder<'a> { pub struct AstBuilder<'a> {
/// The memory allocator used to allocate AST nodes in the arena.
pub allocator: &'a Allocator, pub allocator: &'a Allocator,
} }
@ -121,8 +124,14 @@ fn generate_enum_inherit_builder_fn(
let fn_name = let fn_name =
enum_builder_name(enum_ident.to_string(), inherit.super_.name().inner_name().to_string()); enum_builder_name(enum_ident.to_string(), inherit.super_.name().inner_name().to_string());
let docs = DocComment::new(format!(
"Convert a [`{}`] into the corresponding variant of [`{}`] without copying or re-allocating memory.",
inherit.super_.name(),
enum_ident
));
quote! { quote! {
///@@line_break ///@@line_break
#docs
#[inline] #[inline]
pub fn #fn_name(self, inner: #super_type) -> #enum_as_type { pub fn #fn_name(self, inner: #super_type) -> #enum_as_type {
#enum_ident::from(inner) #enum_ident::from(inner)

View file

@ -1,3 +1,5 @@
use std::fmt;
use quote::ToTokens; use quote::ToTokens;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use serde::Serialize; use serde::Serialize;
@ -86,6 +88,18 @@ impl<'a> From<crate::util::TypeIdentResult<'a>> for TypeName {
} }
} }
} }
impl fmt::Display for TypeName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Ident(it) => write!(f, "{it}"),
Self::Vec(it) => write!(f, "Vec<{it}>"),
Self::Box(it) => write!(f, "Box<{it}>"),
Self::Opt(it) => write!(f, "Option<{it}>"),
Self::Ref(it) => write!(f, "&{it}"),
Self::Complex(it) => write!(f, "{it}"),
}
}
}
#[derive(Debug, Default, serde::Serialize)] #[derive(Debug, Default, serde::Serialize)]
pub struct Schema { pub struct Schema {