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::unused_self,
)]
#![warn(missing_docs)]
use std::mem;
@ -27,26 +28,33 @@ impl<'a, T> FromIn<'a, NONE> for Option<Box<'a, T>> {
}
impl<'a> AstBuilder<'a> {
/// Create a new AST builder that will allocate nodes in the given allocator.
#[inline]
pub fn new(allocator: &'a Allocator) -> Self {
Self { allocator }
}
/// Move a value into the memory arena.
#[inline]
pub fn alloc<T>(self, value: T) -> Box<'a, T> {
Box::new_in(value, self.allocator)
}
/// Create a new empty [`Vec`] that stores its elements in the memory arena.
#[inline]
pub fn vec<T>(self) -> Vec<'a, T> {
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]
pub fn vec_with_capacity<T>(self, capacity: usize) -> Vec<'a, T> {
Vec::with_capacity_in(capacity, self.allocator)
}
/// Create a new arena-allocated [`Vec`] initialized with a single element.
#[inline]
pub fn vec1<T>(self, value: T) -> Vec<'a, T> {
let mut vec = self.vec_with_capacity(1);
@ -54,16 +62,20 @@ impl<'a> AstBuilder<'a> {
vec
}
/// Collect an iterator into a new arena-allocated [`Vec`].
#[inline]
pub fn vec_from_iter<T, I: IntoIterator<Item = T>>(self, iter: I) -> Vec<'a, T> {
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]
pub fn str(self, value: &str) -> &'a str {
String::from_str_in(value, self.allocator).into_bump_str()
}
/// Allocate an [`Atom`] from a string slice.
#[inline]
pub fn atom(self, value: &str) -> Atom<'a> {
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) }
}
/// 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]
pub fn move_expression(self, expr: &mut Expression<'a>) -> Expression<'a> {
let null_expr = self.expression_null_literal(expr.span());
mem::replace(expr, null_expr)
}
/// Moves the statement out by replacing it with an [empty
/// statement](Statement::EmptyStatement).
#[inline]
pub fn move_statement(self, stmt: &mut Statement<'a>) -> Statement<'a> {
let empty_stmt = self.empty_statement(stmt.span());
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]
pub fn move_assignment_target(self, target: &mut AssignmentTarget<'a>) -> AssignmentTarget<'a> {
let dummy =
@ -100,6 +117,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(target, dummy.into())
}
/// Move a declaration out by replacing it with an empty [variable
/// declaration](Declaration::VariableDeclaration).
#[inline]
pub fn move_declaration(self, decl: &mut Declaration<'a>) -> Declaration<'a> {
let empty_decl = self.variable_declaration(
@ -112,6 +131,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(decl, empty_decl)
}
/// Move a variable declaration out by replacing it with an empty [variable
/// declaration](VariableDeclaration).
#[inline]
pub fn move_variable_declaration(
self,
@ -126,6 +147,8 @@ impl<'a> AstBuilder<'a> {
mem::replace(decl, empty_decl)
}
/// Move an array element out by replacing it with an
/// [elision](ArrayExpressionElement::Elision).
pub fn move_array_expression_element(
self,
element: &mut ArrayExpressionElement<'a>,
@ -134,6 +157,8 @@ impl<'a> AstBuilder<'a> {
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]
pub fn move_vec<T>(self, vec: &mut Vec<'a, T>) -> Vec<'a, T> {
mem::replace(vec, self.vec())
@ -160,6 +185,8 @@ impl<'a> AstBuilder<'a> {
/* ---------- Functions ---------- */
/// Create a [`FormalParameter`] with no type annotations, modifiers,
/// decorators, or initializer.
#[inline]
pub fn plain_formal_parameter(
self,
@ -169,6 +196,8 @@ impl<'a> AstBuilder<'a> {
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]
pub fn plain_function(
self,
@ -195,6 +224,7 @@ impl<'a> AstBuilder<'a> {
/* ---------- Modules ---------- */
/// Create an empty [`ExportNamedDeclaration`] with no modifiers
#[inline]
pub fn plain_export_named_declaration_declaration(
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]
pub fn plain_export_named_declaration(
self,
@ -230,6 +262,8 @@ impl<'a> AstBuilder<'a> {
/* ---------- TypeScript ---------- */
/// Create a [`TSInterfaceHeritage`] that extends from the given list of
/// other interfaces.
#[inline]
pub fn ts_interface_heritages(
self,
@ -245,11 +279,13 @@ impl<'a> AstBuilder<'a> {
)
}
/// Create an [`JSXOpeningElement`].
#[inline]
pub fn jsx_opening_fragment(self, span: Span) -> JSXOpeningFragment {
JSXOpeningFragment { span }
}
/// Create an [`JSXClosingElement`].
#[inline]
pub fn jsx_closing_fragment(self, span: Span) -> JSXClosingFragment {
JSXClosingFragment { span }

View file

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

View file

@ -37,6 +37,7 @@ impl Generator for AstBuilderGenerator {
GeneratorOutput::Rust {
path: output(crate::AST_CRATE, "ast_builder.rs"),
tokens: quote! {
//! AST node factories
#header
#![allow(
@ -44,6 +45,7 @@ impl Generator for AstBuilderGenerator {
clippy::too_many_arguments,
clippy::fn_params_excessive_bools,
)]
#![warn(missing_docs)]
///@@line_break
use oxc_allocator::{Allocator, Box, IntoIn, Vec};
@ -56,6 +58,7 @@ impl Generator for AstBuilderGenerator {
/// AST builder for creating AST nodes
#[derive(Clone, Copy)]
pub struct AstBuilder<'a> {
/// The memory allocator used to allocate AST nodes in the arena.
pub allocator: &'a Allocator,
}
@ -121,8 +124,14 @@ fn generate_enum_inherit_builder_fn(
let fn_name =
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! {
///@@line_break
#docs
#[inline]
pub fn #fn_name(self, inner: #super_type) -> #enum_as_type {
#enum_ident::from(inner)

View file

@ -1,3 +1,5 @@
use std::fmt;
use quote::ToTokens;
use rustc_hash::FxHashSet;
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)]
pub struct Schema {