mirror of
https://github.com/danbulant/oxc
synced 2026-05-22 13:48:55 +00:00
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:
parent
661dfd2026
commit
8d27e2daab
4 changed files with 82 additions and 1 deletions
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue