592 lines
22 KiB
Rust
592 lines
22 KiB
Rust
//! A folder (implementer of the [Fold] trait) maps ASTs to ASTs
|
|
|
|
use crate::ast::*;
|
|
use cl_structures::span::Span;
|
|
|
|
/// Deconstructs the entire AST, and reconstructs it from scratch.
|
|
///
|
|
/// Each method acts as a customization point.
|
|
///
|
|
/// There are a set of default implementations for enums
|
|
/// under the name [`or_fold_`*](or_fold_expr_kind),
|
|
/// provided for ease of use.
|
|
///
|
|
/// For all other nodes, traversal is *explicit*.
|
|
pub trait Fold {
|
|
fn fold_span(&mut self, span: Span) -> Span {
|
|
span
|
|
}
|
|
fn fold_mutability(&mut self, mutability: Mutability) -> Mutability {
|
|
mutability
|
|
}
|
|
fn fold_visibility(&mut self, visibility: Visibility) -> Visibility {
|
|
visibility
|
|
}
|
|
fn fold_sym(&mut self, ident: Sym) -> Sym {
|
|
ident
|
|
}
|
|
fn fold_literal(&mut self, lit: Literal) -> Literal {
|
|
or_fold_literal(self, lit)
|
|
}
|
|
fn fold_bool(&mut self, b: bool) -> bool {
|
|
b
|
|
}
|
|
fn fold_char(&mut self, c: char) -> char {
|
|
c
|
|
}
|
|
fn fold_int(&mut self, i: u128) -> u128 {
|
|
i
|
|
}
|
|
fn fold_smuggled_float(&mut self, f: u64) -> u64 {
|
|
f
|
|
}
|
|
fn fold_string(&mut self, s: String) -> String {
|
|
s
|
|
}
|
|
fn fold_file(&mut self, f: File) -> File {
|
|
let File { name, items } = f;
|
|
File { name, items: items.into_iter().map(|i| self.fold_item(i)).collect() }
|
|
}
|
|
fn fold_attrs(&mut self, a: Attrs) -> Attrs {
|
|
let Attrs { meta } = a;
|
|
Attrs { meta: meta.into_iter().map(|m| self.fold_meta(m)).collect() }
|
|
}
|
|
fn fold_meta(&mut self, m: Meta) -> Meta {
|
|
let Meta { name, kind } = m;
|
|
Meta { name: self.fold_sym(name), kind: self.fold_meta_kind(kind) }
|
|
}
|
|
fn fold_meta_kind(&mut self, kind: MetaKind) -> MetaKind {
|
|
or_fold_meta_kind(self, kind)
|
|
}
|
|
fn fold_item(&mut self, i: Item) -> Item {
|
|
let Item { span, attrs, vis, kind } = i;
|
|
Item {
|
|
span: self.fold_span(span),
|
|
attrs: self.fold_attrs(attrs),
|
|
vis: self.fold_visibility(vis),
|
|
kind: self.fold_item_kind(kind),
|
|
}
|
|
}
|
|
fn fold_item_kind(&mut self, kind: ItemKind) -> ItemKind {
|
|
or_fold_item_kind(self, kind)
|
|
}
|
|
fn fold_generics(&mut self, gens: Generics) -> Generics {
|
|
let Generics { vars } = gens;
|
|
Generics { vars: vars.into_iter().map(|sym| self.fold_sym(sym)).collect() }
|
|
}
|
|
fn fold_alias(&mut self, a: Alias) -> Alias {
|
|
let Alias { name, from } = a;
|
|
Alias { name: self.fold_sym(name), from: from.map(|from| Box::new(self.fold_ty(*from))) }
|
|
}
|
|
fn fold_const(&mut self, c: Const) -> Const {
|
|
let Const { name, ty, init } = c;
|
|
Const {
|
|
name: self.fold_sym(name),
|
|
ty: Box::new(self.fold_ty(*ty)),
|
|
init: Box::new(self.fold_expr(*init)),
|
|
}
|
|
}
|
|
fn fold_static(&mut self, s: Static) -> Static {
|
|
let Static { mutable, name, ty, init } = s;
|
|
Static {
|
|
mutable: self.fold_mutability(mutable),
|
|
name: self.fold_sym(name),
|
|
ty: Box::new(self.fold_ty(*ty)),
|
|
init: Box::new(self.fold_expr(*init)),
|
|
}
|
|
}
|
|
fn fold_module(&mut self, m: Module) -> Module {
|
|
let Module { name, file } = m;
|
|
Module { name: self.fold_sym(name), file: file.map(|v| self.fold_file(v)) }
|
|
}
|
|
fn fold_function(&mut self, f: Function) -> Function {
|
|
let Function { name, gens, sign, bind, body } = f;
|
|
Function {
|
|
name: self.fold_sym(name),
|
|
gens: self.fold_generics(gens),
|
|
sign: self.fold_ty_fn(sign),
|
|
bind: self.fold_pattern(bind),
|
|
body: body.map(|b| self.fold_expr(b)),
|
|
}
|
|
}
|
|
fn fold_struct(&mut self, s: Struct) -> Struct {
|
|
let Struct { name, gens, kind } = s;
|
|
Struct {
|
|
name: self.fold_sym(name),
|
|
gens: self.fold_generics(gens),
|
|
kind: self.fold_struct_kind(kind),
|
|
}
|
|
}
|
|
fn fold_struct_kind(&mut self, kind: StructKind) -> StructKind {
|
|
match kind {
|
|
StructKind::Empty => StructKind::Empty,
|
|
StructKind::Tuple(tys) => {
|
|
StructKind::Tuple(tys.into_iter().map(|t| self.fold_ty(t)).collect())
|
|
}
|
|
StructKind::Struct(mem) => StructKind::Struct(
|
|
mem.into_iter()
|
|
.map(|m| self.fold_struct_member(m))
|
|
.collect(),
|
|
),
|
|
}
|
|
}
|
|
fn fold_struct_member(&mut self, m: StructMember) -> StructMember {
|
|
let StructMember { vis, name, ty } = m;
|
|
StructMember {
|
|
vis: self.fold_visibility(vis),
|
|
name: self.fold_sym(name),
|
|
ty: self.fold_ty(ty),
|
|
}
|
|
}
|
|
fn fold_enum(&mut self, e: Enum) -> Enum {
|
|
let Enum { name, gens, variants: kind } = e;
|
|
Enum {
|
|
name: self.fold_sym(name),
|
|
gens: self.fold_generics(gens),
|
|
variants: kind.into_iter().map(|v| self.fold_variant(v)).collect(),
|
|
}
|
|
}
|
|
fn fold_variant(&mut self, v: Variant) -> Variant {
|
|
let Variant { name, kind, body } = v;
|
|
|
|
Variant {
|
|
name: self.fold_sym(name),
|
|
kind: self.fold_struct_kind(kind),
|
|
body: body.map(|e| Box::new(self.fold_expr(*e))),
|
|
}
|
|
}
|
|
fn fold_impl(&mut self, i: Impl) -> Impl {
|
|
let Impl { target, body } = i;
|
|
Impl { target: self.fold_impl_kind(target), body: self.fold_file(body) }
|
|
}
|
|
fn fold_impl_kind(&mut self, kind: ImplKind) -> ImplKind {
|
|
or_fold_impl_kind(self, kind)
|
|
}
|
|
fn fold_use(&mut self, u: Use) -> Use {
|
|
let Use { absolute, tree } = u;
|
|
Use { absolute, tree: self.fold_use_tree(tree) }
|
|
}
|
|
fn fold_use_tree(&mut self, tree: UseTree) -> UseTree {
|
|
or_fold_use_tree(self, tree)
|
|
}
|
|
fn fold_ty(&mut self, t: Ty) -> Ty {
|
|
let Ty { span, kind } = t;
|
|
Ty { span: self.fold_span(span), kind: self.fold_ty_kind(kind) }
|
|
}
|
|
fn fold_ty_kind(&mut self, kind: TyKind) -> TyKind {
|
|
or_fold_ty_kind(self, kind)
|
|
}
|
|
fn fold_ty_array(&mut self, a: TyArray) -> TyArray {
|
|
let TyArray { ty, count } = a;
|
|
TyArray { ty: Box::new(self.fold_ty_kind(*ty)), count }
|
|
}
|
|
fn fold_ty_slice(&mut self, s: TySlice) -> TySlice {
|
|
let TySlice { ty } = s;
|
|
TySlice { ty: Box::new(self.fold_ty_kind(*ty)) }
|
|
}
|
|
fn fold_ty_tuple(&mut self, t: TyTuple) -> TyTuple {
|
|
let TyTuple { types } = t;
|
|
TyTuple {
|
|
types: types
|
|
.into_iter()
|
|
.map(|kind| self.fold_ty_kind(kind))
|
|
.collect(),
|
|
}
|
|
}
|
|
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
|
let TyRef { mutable, count, to } = t;
|
|
TyRef { mutable: self.fold_mutability(mutable), count, to: Box::new(self.fold_ty(*to)) }
|
|
}
|
|
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
|
|
let TyFn { args, rety } = t;
|
|
TyFn {
|
|
args: Box::new(self.fold_ty_kind(*args)),
|
|
rety: rety.map(|t| Box::new(self.fold_ty(*t))),
|
|
}
|
|
}
|
|
fn fold_path(&mut self, p: Path) -> Path {
|
|
let Path { absolute, parts } = p;
|
|
Path { absolute, parts: parts.into_iter().map(|p| self.fold_path_part(p)).collect() }
|
|
}
|
|
fn fold_path_part(&mut self, p: PathPart) -> PathPart {
|
|
match p {
|
|
PathPart::SuperKw => PathPart::SuperKw,
|
|
PathPart::SelfTy => PathPart::SelfTy,
|
|
PathPart::Ident(i) => PathPart::Ident(self.fold_sym(i)),
|
|
}
|
|
}
|
|
fn fold_stmt(&mut self, s: Stmt) -> Stmt {
|
|
let Stmt { span, kind, semi } = s;
|
|
Stmt {
|
|
span: self.fold_span(span),
|
|
kind: self.fold_stmt_kind(kind),
|
|
semi: self.fold_semi(semi),
|
|
}
|
|
}
|
|
fn fold_stmt_kind(&mut self, kind: StmtKind) -> StmtKind {
|
|
or_fold_stmt_kind(self, kind)
|
|
}
|
|
fn fold_semi(&mut self, s: Semi) -> Semi {
|
|
s
|
|
}
|
|
fn fold_expr(&mut self, e: Expr) -> Expr {
|
|
let Expr { span, kind } = e;
|
|
Expr { span: self.fold_span(span), kind: self.fold_expr_kind(kind) }
|
|
}
|
|
fn fold_expr_kind(&mut self, kind: ExprKind) -> ExprKind {
|
|
or_fold_expr_kind(self, kind)
|
|
}
|
|
fn fold_closure(&mut self, value: Closure) -> Closure {
|
|
let Closure { arg, body } = value;
|
|
Closure { arg: Box::new(self.fold_pattern(*arg)), body: Box::new(self.fold_expr(*body)) }
|
|
}
|
|
fn fold_let(&mut self, l: Let) -> Let {
|
|
let Let { mutable, name, ty, init } = l;
|
|
Let {
|
|
mutable: self.fold_mutability(mutable),
|
|
name: self.fold_pattern(name),
|
|
ty: ty.map(|t| Box::new(self.fold_ty(*t))),
|
|
init: init.map(|e| Box::new(self.fold_expr(*e))),
|
|
}
|
|
}
|
|
|
|
fn fold_pattern(&mut self, p: Pattern) -> Pattern {
|
|
match p {
|
|
Pattern::Name(sym) => Pattern::Name(self.fold_sym(sym)),
|
|
Pattern::Path(path) => Pattern::Path(self.fold_path(path)),
|
|
Pattern::Literal(literal) => Pattern::Literal(self.fold_literal(literal)),
|
|
Pattern::Rest(Some(name)) => Pattern::Rest(Some(self.fold_pattern(*name).into())),
|
|
Pattern::Rest(None) => Pattern::Rest(None),
|
|
Pattern::Ref(mutability, pattern) => Pattern::Ref(
|
|
self.fold_mutability(mutability),
|
|
Box::new(self.fold_pattern(*pattern)),
|
|
),
|
|
Pattern::RangeExc(head, tail) => Pattern::RangeInc(
|
|
Box::new(self.fold_pattern(*head)),
|
|
Box::new(self.fold_pattern(*tail)),
|
|
),
|
|
Pattern::RangeInc(head, tail) => Pattern::RangeInc(
|
|
Box::new(self.fold_pattern(*head)),
|
|
Box::new(self.fold_pattern(*tail)),
|
|
),
|
|
Pattern::Tuple(patterns) => {
|
|
Pattern::Tuple(patterns.into_iter().map(|p| self.fold_pattern(p)).collect())
|
|
}
|
|
Pattern::Array(patterns) => {
|
|
Pattern::Array(patterns.into_iter().map(|p| self.fold_pattern(p)).collect())
|
|
}
|
|
Pattern::Struct(path, items) => Pattern::Struct(
|
|
self.fold_path(path),
|
|
items
|
|
.into_iter()
|
|
.map(|(name, bind)| (name, bind.map(|p| self.fold_pattern(p))))
|
|
.collect(),
|
|
),
|
|
Pattern::TupleStruct(path, items) => Pattern::TupleStruct(
|
|
self.fold_path(path),
|
|
items
|
|
.into_iter()
|
|
.map(|bind| self.fold_pattern(bind))
|
|
.collect(),
|
|
),
|
|
}
|
|
}
|
|
|
|
fn fold_match(&mut self, m: Match) -> Match {
|
|
let Match { scrutinee, arms } = m;
|
|
Match {
|
|
scrutinee: self.fold_expr(*scrutinee).into(),
|
|
arms: arms
|
|
.into_iter()
|
|
.map(|arm| self.fold_match_arm(arm))
|
|
.collect(),
|
|
}
|
|
}
|
|
|
|
fn fold_match_arm(&mut self, a: MatchArm) -> MatchArm {
|
|
let MatchArm(pat, expr) = a;
|
|
MatchArm(self.fold_pattern(pat), self.fold_expr(expr))
|
|
}
|
|
|
|
fn fold_assign(&mut self, a: Assign) -> Assign {
|
|
let Assign { parts } = a;
|
|
let (head, tail) = *parts;
|
|
Assign { parts: Box::new((self.fold_expr(head), self.fold_expr(tail))) }
|
|
}
|
|
fn fold_modify(&mut self, m: Modify) -> Modify {
|
|
let Modify { kind, parts } = m;
|
|
let (head, tail) = *parts;
|
|
Modify {
|
|
kind: self.fold_modify_kind(kind),
|
|
parts: Box::new((self.fold_expr(head), self.fold_expr(tail))),
|
|
}
|
|
}
|
|
fn fold_modify_kind(&mut self, kind: ModifyKind) -> ModifyKind {
|
|
kind
|
|
}
|
|
fn fold_binary(&mut self, b: Binary) -> Binary {
|
|
let Binary { kind, parts } = b;
|
|
let (head, tail) = *parts;
|
|
Binary {
|
|
kind: self.fold_binary_kind(kind),
|
|
parts: Box::new((self.fold_expr(head), self.fold_expr(tail))),
|
|
}
|
|
}
|
|
fn fold_binary_kind(&mut self, kind: BinaryKind) -> BinaryKind {
|
|
kind
|
|
}
|
|
fn fold_unary(&mut self, u: Unary) -> Unary {
|
|
let Unary { kind, tail } = u;
|
|
Unary { kind: self.fold_unary_kind(kind), tail: Box::new(self.fold_expr(*tail)) }
|
|
}
|
|
fn fold_unary_kind(&mut self, kind: UnaryKind) -> UnaryKind {
|
|
kind
|
|
}
|
|
fn fold_cast(&mut self, cast: Cast) -> Cast {
|
|
let Cast { head, ty } = cast;
|
|
Cast { head: Box::new(self.fold_expr(*head)), ty: self.fold_ty(ty) }
|
|
}
|
|
fn fold_member(&mut self, m: Member) -> Member {
|
|
let Member { head, kind } = m;
|
|
Member { head: Box::new(self.fold_expr(*head)), kind: self.fold_member_kind(kind) }
|
|
}
|
|
fn fold_member_kind(&mut self, kind: MemberKind) -> MemberKind {
|
|
or_fold_member_kind(self, kind)
|
|
}
|
|
fn fold_index(&mut self, i: Index) -> Index {
|
|
let Index { head, indices } = i;
|
|
Index {
|
|
head: Box::new(self.fold_expr(*head)),
|
|
indices: indices.into_iter().map(|e| self.fold_expr(e)).collect(),
|
|
}
|
|
}
|
|
|
|
fn fold_structor(&mut self, s: Structor) -> Structor {
|
|
let Structor { to, init } = s;
|
|
Structor {
|
|
to: self.fold_path(to),
|
|
init: init.into_iter().map(|f| self.fold_fielder(f)).collect(),
|
|
}
|
|
}
|
|
|
|
fn fold_fielder(&mut self, f: Fielder) -> Fielder {
|
|
let Fielder { name, init } = f;
|
|
Fielder { name: self.fold_sym(name), init: init.map(|e| Box::new(self.fold_expr(*e))) }
|
|
}
|
|
fn fold_array(&mut self, a: Array) -> Array {
|
|
let Array { values } = a;
|
|
Array { values: values.into_iter().map(|e| self.fold_expr(e)).collect() }
|
|
}
|
|
fn fold_array_rep(&mut self, a: ArrayRep) -> ArrayRep {
|
|
let ArrayRep { value, repeat } = a;
|
|
ArrayRep { value: Box::new(self.fold_expr(*value)), repeat }
|
|
}
|
|
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
|
|
let AddrOf { mutable, expr } = a;
|
|
AddrOf { mutable: self.fold_mutability(mutable), expr: Box::new(self.fold_expr(*expr)) }
|
|
}
|
|
fn fold_block(&mut self, b: Block) -> Block {
|
|
let Block { stmts } = b;
|
|
Block { stmts: stmts.into_iter().map(|s| self.fold_stmt(s)).collect() }
|
|
}
|
|
fn fold_group(&mut self, g: Group) -> Group {
|
|
let Group { expr } = g;
|
|
Group { expr: Box::new(self.fold_expr(*expr)) }
|
|
}
|
|
fn fold_tuple(&mut self, t: Tuple) -> Tuple {
|
|
let Tuple { exprs } = t;
|
|
Tuple { exprs: exprs.into_iter().map(|e| self.fold_expr(e)).collect() }
|
|
}
|
|
fn fold_while(&mut self, w: While) -> While {
|
|
let While { cond, pass, fail } = w;
|
|
While {
|
|
cond: Box::new(self.fold_expr(*cond)),
|
|
pass: Box::new(self.fold_block(*pass)),
|
|
fail: self.fold_else(fail),
|
|
}
|
|
}
|
|
fn fold_if(&mut self, i: If) -> If {
|
|
let If { cond, pass, fail } = i;
|
|
If {
|
|
cond: Box::new(self.fold_expr(*cond)),
|
|
pass: Box::new(self.fold_block(*pass)),
|
|
fail: self.fold_else(fail),
|
|
}
|
|
}
|
|
fn fold_for(&mut self, f: For) -> For {
|
|
let For { bind, cond, pass, fail } = f;
|
|
For {
|
|
bind: self.fold_pattern(bind),
|
|
cond: Box::new(self.fold_expr(*cond)),
|
|
pass: Box::new(self.fold_block(*pass)),
|
|
fail: self.fold_else(fail),
|
|
}
|
|
}
|
|
fn fold_else(&mut self, e: Else) -> Else {
|
|
let Else { body } = e;
|
|
Else { body: body.map(|e| Box::new(self.fold_expr(*e))) }
|
|
}
|
|
fn fold_break(&mut self, b: Break) -> Break {
|
|
let Break { body } = b;
|
|
Break { body: body.map(|e| Box::new(self.fold_expr(*e))) }
|
|
}
|
|
fn fold_return(&mut self, r: Return) -> Return {
|
|
let Return { body } = r;
|
|
Return { body: body.map(|e| Box::new(self.fold_expr(*e))) }
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds a [Literal] in the default way
|
|
pub fn or_fold_literal<F: Fold + ?Sized>(folder: &mut F, lit: Literal) -> Literal {
|
|
match lit {
|
|
Literal::Bool(b) => Literal::Bool(folder.fold_bool(b)),
|
|
Literal::Char(c) => Literal::Char(folder.fold_char(c)),
|
|
Literal::Int(i) => Literal::Int(folder.fold_int(i)),
|
|
Literal::Float(f) => Literal::Float(folder.fold_smuggled_float(f)),
|
|
Literal::String(s) => Literal::String(folder.fold_string(s)),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds a [MetaKind] in the default way
|
|
pub fn or_fold_meta_kind<F: Fold + ?Sized>(folder: &mut F, kind: MetaKind) -> MetaKind {
|
|
match kind {
|
|
MetaKind::Plain => MetaKind::Plain,
|
|
MetaKind::Equals(l) => MetaKind::Equals(folder.fold_literal(l)),
|
|
MetaKind::Func(lits) => {
|
|
MetaKind::Func(lits.into_iter().map(|l| folder.fold_literal(l)).collect())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds an [ItemKind] in the default way
|
|
pub fn or_fold_item_kind<F: Fold + ?Sized>(folder: &mut F, kind: ItemKind) -> ItemKind {
|
|
match kind {
|
|
ItemKind::Module(m) => ItemKind::Module(folder.fold_module(m)),
|
|
ItemKind::Alias(a) => ItemKind::Alias(folder.fold_alias(a)),
|
|
ItemKind::Enum(e) => ItemKind::Enum(folder.fold_enum(e)),
|
|
ItemKind::Struct(s) => ItemKind::Struct(folder.fold_struct(s)),
|
|
ItemKind::Const(c) => ItemKind::Const(folder.fold_const(c)),
|
|
ItemKind::Static(s) => ItemKind::Static(folder.fold_static(s)),
|
|
ItemKind::Function(f) => ItemKind::Function(folder.fold_function(f)),
|
|
ItemKind::Impl(i) => ItemKind::Impl(folder.fold_impl(i)),
|
|
ItemKind::Use(u) => ItemKind::Use(folder.fold_use(u)),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds a [StructKind] in the default way
|
|
pub fn or_fold_struct_kind<F: Fold + ?Sized>(folder: &mut F, kind: StructKind) -> StructKind {
|
|
match kind {
|
|
StructKind::Empty => StructKind::Empty,
|
|
StructKind::Tuple(tys) => {
|
|
StructKind::Tuple(tys.into_iter().map(|t| folder.fold_ty(t)).collect())
|
|
}
|
|
StructKind::Struct(mem) => StructKind::Struct(
|
|
mem.into_iter()
|
|
.map(|m| folder.fold_struct_member(m))
|
|
.collect(),
|
|
),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds an [ImplKind] in the default way
|
|
pub fn or_fold_impl_kind<F: Fold + ?Sized>(folder: &mut F, kind: ImplKind) -> ImplKind {
|
|
match kind {
|
|
ImplKind::Type(t) => ImplKind::Type(folder.fold_ty(t)),
|
|
ImplKind::Trait { impl_trait, for_type } => ImplKind::Trait {
|
|
impl_trait: folder.fold_path(impl_trait),
|
|
for_type: Box::new(folder.fold_ty(*for_type)),
|
|
},
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn or_fold_use_tree<F: Fold + ?Sized>(folder: &mut F, tree: UseTree) -> UseTree {
|
|
match tree {
|
|
UseTree::Tree(tree) => UseTree::Tree(
|
|
tree.into_iter()
|
|
.map(|tree| folder.fold_use_tree(tree))
|
|
.collect(),
|
|
),
|
|
UseTree::Path(path, rest) => UseTree::Path(
|
|
folder.fold_path_part(path),
|
|
Box::new(folder.fold_use_tree(*rest)),
|
|
),
|
|
UseTree::Alias(path, name) => UseTree::Alias(folder.fold_sym(path), folder.fold_sym(name)),
|
|
UseTree::Name(name) => UseTree::Name(folder.fold_sym(name)),
|
|
UseTree::Glob => UseTree::Glob,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds a [TyKind] in the default way
|
|
pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind {
|
|
match kind {
|
|
TyKind::Never => TyKind::Never,
|
|
TyKind::Empty => TyKind::Empty,
|
|
TyKind::Infer => TyKind::Infer,
|
|
TyKind::Path(p) => TyKind::Path(folder.fold_path(p)),
|
|
TyKind::Array(a) => TyKind::Array(folder.fold_ty_array(a)),
|
|
TyKind::Slice(s) => TyKind::Slice(folder.fold_ty_slice(s)),
|
|
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
|
|
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
|
|
TyKind::Fn(t) => TyKind::Fn(folder.fold_ty_fn(t)),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
/// Folds a [StmtKind] in the default way
|
|
pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> StmtKind {
|
|
match kind {
|
|
StmtKind::Empty => StmtKind::Empty,
|
|
StmtKind::Item(i) => StmtKind::Item(Box::new(folder.fold_item(*i))),
|
|
StmtKind::Expr(e) => StmtKind::Expr(Box::new(folder.fold_expr(*e))),
|
|
}
|
|
}
|
|
#[inline]
|
|
/// Folds an [ExprKind] in the default way
|
|
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
|
match kind {
|
|
ExprKind::Empty => ExprKind::Empty,
|
|
ExprKind::Closure(c) => ExprKind::Closure(folder.fold_closure(c)),
|
|
ExprKind::Quote(q) => ExprKind::Quote(q), // quoted expressions are left unmodified
|
|
ExprKind::Let(l) => ExprKind::Let(folder.fold_let(l)),
|
|
ExprKind::Match(m) => ExprKind::Match(folder.fold_match(m)),
|
|
ExprKind::Assign(a) => ExprKind::Assign(folder.fold_assign(a)),
|
|
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
|
ExprKind::Binary(b) => ExprKind::Binary(folder.fold_binary(b)),
|
|
ExprKind::Unary(u) => ExprKind::Unary(folder.fold_unary(u)),
|
|
ExprKind::Cast(c) => ExprKind::Cast(folder.fold_cast(c)),
|
|
ExprKind::Member(m) => ExprKind::Member(folder.fold_member(m)),
|
|
ExprKind::Index(i) => ExprKind::Index(folder.fold_index(i)),
|
|
ExprKind::Structor(s) => ExprKind::Structor(folder.fold_structor(s)),
|
|
ExprKind::Path(p) => ExprKind::Path(folder.fold_path(p)),
|
|
ExprKind::Literal(l) => ExprKind::Literal(folder.fold_literal(l)),
|
|
ExprKind::Array(a) => ExprKind::Array(folder.fold_array(a)),
|
|
ExprKind::ArrayRep(a) => ExprKind::ArrayRep(folder.fold_array_rep(a)),
|
|
ExprKind::AddrOf(a) => ExprKind::AddrOf(folder.fold_addrof(a)),
|
|
ExprKind::Block(b) => ExprKind::Block(folder.fold_block(b)),
|
|
ExprKind::Group(g) => ExprKind::Group(folder.fold_group(g)),
|
|
ExprKind::Tuple(t) => ExprKind::Tuple(folder.fold_tuple(t)),
|
|
ExprKind::While(w) => ExprKind::While(folder.fold_while(w)),
|
|
ExprKind::If(i) => ExprKind::If(folder.fold_if(i)),
|
|
ExprKind::For(f) => ExprKind::For(folder.fold_for(f)),
|
|
ExprKind::Break(b) => ExprKind::Break(folder.fold_break(b)),
|
|
ExprKind::Return(r) => ExprKind::Return(folder.fold_return(r)),
|
|
ExprKind::Continue => ExprKind::Continue,
|
|
}
|
|
}
|
|
pub fn or_fold_member_kind<F: Fold + ?Sized>(folder: &mut F, kind: MemberKind) -> MemberKind {
|
|
match kind {
|
|
MemberKind::Call(name, args) => {
|
|
MemberKind::Call(folder.fold_sym(name), folder.fold_tuple(args))
|
|
}
|
|
MemberKind::Struct(name) => MemberKind::Struct(folder.fold_sym(name)),
|
|
MemberKind::Tuple(name) => MemberKind::Tuple(folder.fold_literal(name)),
|
|
}
|
|
}
|