Rust API

Ast

An owned AST with its source text, language metadata, input source map, and mutable program access.

Ast bundles an oxc Program with the source text its spans anchor to, language metadata derived from that program, and an optional input source map.

pub struct Ast { /* private fields */ }

impl Ast {
    pub fn from_source<F>(
        source: Arc<str>,
        language: Language,
        source_type: SourceType,
        input_map: Option<SourceMap>,
        build: F,
    ) -> Ast
    where
        F: for<'a> FnOnce(&'a str, &'a Allocator) -> Program<'a>;

    pub fn try_from_source<F, E>(
        source: Arc<str>,
        language: Language,
        source_type: SourceType,
        input_map: Option<SourceMap>,
        build: F,
    ) -> Result<Ast, E>
    where
        F: for<'a> FnOnce(&'a str, &'a Allocator) -> Result<Program<'a>, E>;

    pub fn program(&self) -> &Program<'_>;
    pub fn source(&self) -> &Arc<str>;
    pub fn language(&self) -> Language;
    pub fn source_type(&self) -> SourceType;
    pub fn map(&self) -> Option<&SourceMap>;

    pub fn with_input_map(&self, map: Option<SourceMap>) -> Ast;

    pub fn with_mut<R>(
        &mut self,
        f: impl for<'i> FnOnce(&'i Allocator, &mut Program<'i>) -> R,
    ) -> R;
}

Construction

parse is the normal way to obtain an Ast. from_source and try_from_source are lower-level constructors for building one from an existing oxc Program: the closure receives the source text and allocator that the program must borrow, and must return a program whose source_text is that source.

Accessors

AccessorTypeDescription
ast.program()&Program<'_>The parsed program.
ast.source()&Arc<str>The source text the program's spans anchor to.
ast.language()LanguageThe grammar of the parsed program: JS, TS, DTS, JSX, or TSX.
ast.source_type()SourceTypeThe resolved module kind of the parsed program: Script, CommonJS, or Module.
ast.map()Option<&SourceMap>The input source map, if any.

Language and SourceType are the Telarel enums. source_type() never reports Unambiguous for a normally parsed AST: that value is a parser input, and a parsed program resolves to Script, CommonJS, or Module.

Program spans are UTF-8 byte offsets into source(), matching oxc::span::Span.

Input source map

ast.map() is the input source map: it describes how this AST's source was produced from upstream originals. It is not the map generated from this AST.

with_input_map rebuilds the AST with a different input map: the program is cloned into a fresh allocator and the source text is shared.

Mutation

with_mut is the only path to the arena. The closure receives the allocator and a mutable program, so new nodes can be allocated while mutating.

The closure may rewrite the tree, but not the source text: Program::source_text must stay content-equal to Ast::source. Debug builds assert this. Build a new Ast to change the source text.

Ast clones are O(1): they share the same arena. with_mut copies the arena first when another clone is still alive, so mutating a clone never mutates the original.

Only the transform hook carries mutations forward. prepare, finalize, and generate receive a borrowed &Ast, so they cannot mutate the program through with_mut.

Thread safety

Ast is Send + Sync so plugin futures can move owned handles or borrow the AST across threads. Sharing &Ast across threads is read-only: Program exposes interior-mutable Cell fields, so mutating them through a shared &Ast is a data race and is forbidden.

Example

use telarel::allocator::Allocator;
use telarel::ast::ast::Program;
use telarel::{parse, Ast, ParseOptions, AstResult};

let parsed: AstResult = parse(
    String::from("const x: number = 1;"),
    ParseOptions::default(),
    vec![],
).await?;

let mut ast: Ast = parsed.ast;

ast.with_mut(|_: &Allocator, program: &mut Program<'_>| {
    program.body.clear();
});

assert!(ast.program().body.is_empty());

Last updated on

Copyright © 2026, Alpheus

On this page