oxc_ast 0.139.0

A collection of JavaScript tools written in Rust.
Documentation
//! AST Definitions
//!
//! # Enum inheritance
//!
//! Some enum AST types inherit variants from other enums, declared with `INHERIT` marker variants.
//!
//! "Inherit" means: If `enum Y` inherits the variants of `enum X`,
//! then all `X`'s variants are duplicated as variants of `Y`.
//!
//! This is mainly an explanation of the consumer-facing API. For further details on implementation,
//! see the `#[ast]` macro in `oxc_ast_macros`, and `InheritVariantsGenerator` in `oxc_ast_tools`.
//!
//! ## Defining enum inheritance
//!
//! Instead of nested enums:
//!
//! ```ignore
//! #[ast]
//! pub enum Expression<'a> {
//!     BooleanLiteral(Box<'a, BooleanLiteral>),
//!     NullLiteral(Box<'a, NullLiteral>),
//!     // ...more variants
//!     MemberExpression(MemberExpression<'a>),
//! }
//!
//! #[ast]
//! pub enum MemberExpression<'a> {
//!     ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>),
//!     StaticMemberExpression(Box<'a, StaticMemberExpression<'a>>),
//!     PrivateFieldExpression(Box<'a, PrivateFieldExpression<'a>>),
//! }
//! ```
//!
//! We add an `INHERIT` marker variant, naming the enum to inherit from:
//!
//! ```ignore
//! #[ast]
//! pub enum Expression<'a> {
//!     BooleanLiteral(Box<'a, BooleanLiteral>) = 0,
//!     NullLiteral(Box<'a, NullLiteral>) = 1,
//!     // ...more variants
//!
//!     INHERIT(MemberExpression<'a>),
//! }
//!
//! #[ast]
//! pub enum MemberExpression<'a> {
//!     ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>) = 48,
//!     StaticMemberExpression(Box<'a, StaticMemberExpression<'a>>) = 49,
//!     PrivateFieldExpression(Box<'a, PrivateFieldExpression<'a>>) = 50,
//! }
//! ```
//!
//! The `#[ast]` macro replaces the `INHERIT(MemberExpression<'a>)` marker variant
//! with `MemberExpression`'s variants, expanding `Expression` to:
//!
//! ```ignore
//! #[repr(C, u8)]
//! pub enum Expression<'a> {
//!     BooleanLiteral(Box<'a, BooleanLiteral>) = 0,
//!     NullLiteral(Box<'a, NullLiteral>) = 1,
//!     // ...more variants
//!
//!     // Inherited from `MemberExpression`
//!     ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>) = 48,
//!     StaticMemberExpression(Box<'a, StaticMemberExpression<'a>>) = 49,
//!     PrivateFieldExpression(Box<'a, PrivateFieldExpression<'a>>) = 50,
//! }
//! ```
//!
//! `oxc_ast_tools` generates the variant data the `#[ast]` macro inserts
//! (see `enum_variants` in `oxc_ast_macros`'s generated `enums.rs`).
//!
//! The conversion methods and trait impls between the 2 enums (`is_member_expression`,
//! `as_member_expression`, `From` / `TryFrom` etc) are also generated by `oxc_ast_tools`
//! (see `InheritVariantsGenerator`), and live in `crate::generated::inherit_variants`.
//! They provide the APIs listed below.
//!
//! ## Using inherited variants
//!
//! #### Creation
//!
//! ```ignore
//! // Old
//! let expr = Expression::MemberExpression(
//!   MemberExpression::ComputedMemberExpression(computed_member_expr)
//! );
//!
//! // New
//! let expr = Expression::ComputedMemberExpression(computed_member_expr);
//! ```
//!
//! #### Conversion
//!
//! ```ignore
//! // Old
//! let expr = Expression::MemberExpression(member_expr);
//!
//! // New
//! let expr = Expression::from(member_expr);
//! ```
//!
//! ```ignore
//! // Old
//! let maybe_member_expr = match expr {
//!     Expression::MemberExpression(member_expr) => Some(member_expr),
//!     _ => None,
//! };
//!
//! // New
//! let maybe_member_expr = MemberExpression::try_from(expr).ok();
//! ```
//!
//! #### Testing
//!
//! ```ignore
//! // Old
//! if matches!(expr, Expression::MemberExpression(_)) { }
//!
//! // New
//! if expr.is_member_expression() { }
//! // or
//! if matches!(expr, match_member_expression!(Expression)) { }
//! ```
//!
//! #### Branching
//!
//! ```ignore
//! // Old
//! if let Expression::MemberExpression(member_expr) = &expr { }
//!
//! // New
//! if let Some(member_expr) = expr.as_member_expression() { }
//! ```
//!
//! #### Matching
//!
//! ```ignore
//! // Old
//! match get_expression() {
//!     Expression::MemberExpression(member_expr) => visitor.visit(member_expr),
//! }
//!
//! // New (exhaustive match)
//! match get_expression() {
//!     expr @ match_member_expression!(Expression) => visitor.visit(expr.to_member_expression()),
//! }
//!
//! // New (alternative)
//! match get_expression() {
//!     expr if expr.is_member_expression() => visitor.visit(expr.to_member_expression()),
//! }
//! ```
//!
//! ## Why `#[repr(C, u8)]` on enums?
//!
//! `#[repr(C, u8)]` allows us to define the discriminants for variants in both the "inherited"
//! and "inheritee" enums.
//!
//! The discriminants and "payloads" match between the 2 types for the inherited variants.
//! Therefore `MemberExpression::ComputedMemberExpression` and `Expression::ComputedMemberExpression`
//! have identical representations in memory, and a `MemberExpression` can be converted to an
//! `Expression` with a zero-cost transmute.
//!
//! The APIs listed above use this property.
//!
//! It is **essential** that the discriminants and "payload" types match between the "inherited"
//! and "inheritee" types, or using the APIs above would be instant UB.
//! This is guaranteed because the `#[ast]` macro inserts the inherited variants into enums
//! and gets the details of those variants from ultimate source of truth - the original enum type
//! definitions, via `oxc_ast_tools`.

// Re-export AST types from other crates
pub use oxc_span::{Language, LanguageVariant, ModuleKind, SourceType, Span};
pub use oxc_str::Str;
pub use oxc_syntax::{
    number::{BigintBase, NumberBase},
    operator::{
        AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator,
    },
};

pub(crate) mod comment;
pub(crate) mod js;
pub(crate) mod jsx;
pub(crate) mod literal;
pub(crate) mod ts;

pub use comment::*;
pub use js::*;
pub use jsx::*;
pub use literal::*;
pub use ts::*;

// `match_*!` macros are `#[macro_export]`ed at the crate root.
// Re-export them here so they're also available via `crate::ast` (e.g. `use crate::ast::*`).
pub use crate::generated::inherit_variants::*;