Expand description
Arena-to-arena AST transformation via the Fold trait.
§Overview
Fold is the transformation counterpart of crate::visitor::Visitor.
Where Visitor walks a tree read-only, Fold rebuilds it — reading from an
input node (in any arena '_) and writing into a caller-supplied output arena
'new. This is the only sound design for arena-allocated ASTs: in-place
mutation (VisitorMut) would let you write a &'new Expr into a slot that
requires a &'old Expr, silently breaking the arena lifetime invariant.
§Lifetimes
'src— the source-text lifetime, bound on theFoldtrait.&'src strslices that point directly into the original PHP source are passed through unchanged across the fold; they are never re-allocated.'new— the output arena lifetime; a generic on each method so oneimpl Fold<'src>can fold into different arenas over its lifetime.'_— the input arena lifetime, intentionally erased. The fold never reads back through output-arena pointers, so the input and output arenas are fully independent.
§Arena-allocated strings
Several AST nodes store &'arena str values that were not borrowed from
the source buffer — for example string literals, StmtKind::Label, and
ExprKind::Nowdoc values. The identity fold re-allocates these via
arena.alloc_str(s) so the output nodes are self-contained within the
new arena. Source-borrowed NameStr values (NameStr::__src) are
preserved as-is without copying.
§Usage
use bumpalo::Bump;
use php_ast::fold::{Fold, fold_program};
use php_ast::ast::*;
/// An identity fold — rebuilds the AST without changes.
struct Identity;
impl<'src> Fold<'src> for Identity {}
// Fold `program` (in `src_arena`) into `out_arena`:
// let folded = Identity.fold_program(&out_arena, &program);To transform specific nodes, override the corresponding method and call the
free fold_* function for the default recursion:
use bumpalo::Bump;
use php_ast::fold::{Fold, fold_expr};
use php_ast::ast::*;
struct NegateInts;
impl<'src> Fold<'src> for NegateInts {
fn fold_expr<'new>(&mut self, arena: &'new Bump, expr: &Expr<'_, 'src>) -> Expr<'new, 'src> {
if let ExprKind::Int(n) = expr.kind {
return Expr { kind: ExprKind::Int(-n), span: expr.span };
}
fold_expr(self, arena, expr)
}
}Traits§
- Fold
- Trait for arena-to-arena PHP AST transformation.
Functions§
- fold_
arg - Folds a call argument.
- fold_
attribute - Folds an attribute.
- fold_
block - Folds a block of statements.
- fold_
catch_ clause - Folds a
catchclause. - fold_
class_ member - Folds a class-like member.
- fold_
enum_ member - Folds an enum member.
- fold_
expr - Folds an expression.
- fold_
match_ arm - Folds a
matcharm. - fold_
name - Folds a name reference.
- fold_
name_ str - Copies a name string into the new arena.
- fold_
param - Folds a function parameter.
- fold_
program - Folds the root program node.
- fold_
property_ hook - Folds a property hook.
- fold_
stmt - Folds a statement.
- fold_
trait_ adaptation - Folds a trait
insteadof/asadaptation. - fold_
trait_ use - Folds a
use Trait;declaration. - fold_
type_ hint - Folds a type hint.