1use bumpalo::Bump;
68
69use crate::ast::*;
70
71pub trait Fold<'src> {
83 fn fold_program<'new>(
85 &mut self,
86 arena: &'new Bump,
87 program: &Program<'_, 'src>,
88 ) -> Program<'new, 'src> {
89 fold_program(self, arena, program)
90 }
91
92 fn fold_stmt<'new>(&mut self, arena: &'new Bump, stmt: &Stmt<'_, 'src>) -> Stmt<'new, 'src> {
94 fold_stmt(self, arena, stmt)
95 }
96
97 fn fold_stmts<'new>(
100 &mut self,
101 arena: &'new Bump,
102 stmts: &[Stmt<'_, 'src>],
103 ) -> ArenaVec<'new, Stmt<'new, 'src>> {
104 fold_stmts(self, arena, stmts)
105 }
106
107 fn fold_block<'new>(
109 &mut self,
110 arena: &'new Bump,
111 block: &Block<'_, 'src>,
112 ) -> Block<'new, 'src> {
113 fold_block(self, arena, block)
114 }
115
116 fn fold_expr<'new>(&mut self, arena: &'new Bump, expr: &Expr<'_, 'src>) -> Expr<'new, 'src> {
118 fold_expr(self, arena, expr)
119 }
120
121 fn fold_param<'new>(
123 &mut self,
124 arena: &'new Bump,
125 param: &Param<'_, 'src>,
126 ) -> Param<'new, 'src> {
127 fold_param(self, arena, param)
128 }
129
130 fn fold_arg<'new>(&mut self, arena: &'new Bump, arg: &Arg<'_, 'src>) -> Arg<'new, 'src> {
132 fold_arg(self, arena, arg)
133 }
134
135 fn fold_class_member<'new>(
137 &mut self,
138 arena: &'new Bump,
139 member: &ClassMember<'_, 'src>,
140 ) -> ClassMember<'new, 'src> {
141 fold_class_member(self, arena, member)
142 }
143
144 fn fold_enum_member<'new>(
146 &mut self,
147 arena: &'new Bump,
148 member: &EnumMember<'_, 'src>,
149 ) -> EnumMember<'new, 'src> {
150 fold_enum_member(self, arena, member)
151 }
152
153 fn fold_property_hook<'new>(
155 &mut self,
156 arena: &'new Bump,
157 hook: &PropertyHook<'_, 'src>,
158 ) -> PropertyHook<'new, 'src> {
159 fold_property_hook(self, arena, hook)
160 }
161
162 fn fold_type_hint<'new>(
164 &mut self,
165 arena: &'new Bump,
166 type_hint: &TypeHint<'_, 'src>,
167 ) -> TypeHint<'new, 'src> {
168 fold_type_hint(self, arena, type_hint)
169 }
170
171 fn fold_attribute<'new>(
173 &mut self,
174 arena: &'new Bump,
175 attribute: &Attribute<'_, 'src>,
176 ) -> Attribute<'new, 'src> {
177 fold_attribute(self, arena, attribute)
178 }
179
180 fn fold_catch_clause<'new>(
182 &mut self,
183 arena: &'new Bump,
184 catch: &CatchClause<'_, 'src>,
185 ) -> CatchClause<'new, 'src> {
186 fold_catch_clause(self, arena, catch)
187 }
188
189 fn fold_match_arm<'new>(
191 &mut self,
192 arena: &'new Bump,
193 arm: &MatchArm<'_, 'src>,
194 ) -> MatchArm<'new, 'src> {
195 fold_match_arm(self, arena, arm)
196 }
197
198 fn fold_closure_use_var(
200 &mut self,
201 _arena: &Bump,
202 var: &ClosureUseVar<'src>,
203 ) -> ClosureUseVar<'src> {
204 var.clone()
205 }
206
207 fn fold_trait_use<'new>(
209 &mut self,
210 arena: &'new Bump,
211 trait_use: &TraitUseDecl<'_, 'src>,
212 ) -> TraitUseDecl<'new, 'src> {
213 fold_trait_use(self, arena, trait_use)
214 }
215
216 fn fold_trait_adaptation<'new>(
218 &mut self,
219 arena: &'new Bump,
220 adaptation: &TraitAdaptation<'_, 'src>,
221 ) -> TraitAdaptation<'new, 'src> {
222 fold_trait_adaptation(self, arena, adaptation)
223 }
224
225 fn fold_name<'new>(&mut self, arena: &'new Bump, name: &Name<'_, 'src>) -> Name<'new, 'src> {
227 fold_name(self, arena, name)
228 }
229}
230
231pub fn fold_program<'new, 'src, F: Fold<'src> + ?Sized>(
237 folder: &mut F,
238 arena: &'new Bump,
239 program: &Program<'_, 'src>,
240) -> Program<'new, 'src> {
241 Program {
242 stmts: folder.fold_stmts(arena, &program.stmts),
243 span: program.span,
244 }
245}
246
247pub fn fold_stmt<'new, 'src, F: Fold<'src> + ?Sized>(
249 folder: &mut F,
250 arena: &'new Bump,
251 stmt: &Stmt<'_, 'src>,
252) -> Stmt<'new, 'src> {
253 let kind = match &stmt.kind {
254 StmtKind::Expression(expr) => {
255 StmtKind::Expression(arena.alloc(folder.fold_expr(arena, expr)))
256 }
257 StmtKind::Echo(exprs) => StmtKind::Echo(fold_exprs(folder, arena, exprs)),
258 StmtKind::Return(expr) => {
259 StmtKind::Return(expr.map(|e| &*arena.alloc(folder.fold_expr(arena, e))))
260 }
261 StmtKind::Block(block) => StmtKind::Block(arena.alloc(folder.fold_block(arena, block))),
262 StmtKind::If(if_stmt) => {
263 let mut elseif_branches =
264 ArenaVec::with_capacity_in(if_stmt.elseif_branches.len(), arena);
265 for branch in if_stmt.elseif_branches.iter() {
266 elseif_branches.push(ElseIfBranch {
267 condition: folder.fold_expr(arena, &branch.condition),
268 body: folder.fold_stmt(arena, &branch.body),
269 span: branch.span,
270 });
271 }
272 let new_if = arena.alloc(IfStmt {
273 condition: folder.fold_expr(arena, &if_stmt.condition),
274 then_branch: arena.alloc(folder.fold_stmt(arena, if_stmt.then_branch)),
275 elseif_branches,
276 else_branch: if_stmt
277 .else_branch
278 .map(|b| &*arena.alloc(folder.fold_stmt(arena, b))),
279 else_kw_span: if_stmt.else_kw_span,
280 uses_alternative: if_stmt.uses_alternative,
281 });
282 StmtKind::If(new_if)
283 }
284 StmtKind::While(w) => {
285 let new_w = arena.alloc(WhileStmt {
286 condition: folder.fold_expr(arena, &w.condition),
287 body: arena.alloc(folder.fold_stmt(arena, w.body)),
288 uses_alternative: w.uses_alternative,
289 });
290 StmtKind::While(new_w)
291 }
292 StmtKind::For(f) => {
293 let new_f = arena.alloc(ForStmt {
294 init: fold_exprs(folder, arena, &f.init),
295 condition: fold_exprs(folder, arena, &f.condition),
296 update: fold_exprs(folder, arena, &f.update),
297 body: arena.alloc(folder.fold_stmt(arena, f.body)),
298 uses_alternative: f.uses_alternative,
299 });
300 StmtKind::For(new_f)
301 }
302 StmtKind::Foreach(fe) => {
303 let new_fe = arena.alloc(ForeachStmt {
304 expr: folder.fold_expr(arena, &fe.expr),
305 key: fe.key.as_ref().map(|k| folder.fold_expr(arena, k)),
306 value: folder.fold_expr(arena, &fe.value),
307 by_ref: fe.by_ref,
308 body: arena.alloc(folder.fold_stmt(arena, fe.body)),
309 uses_alternative: fe.uses_alternative,
310 });
311 StmtKind::Foreach(new_fe)
312 }
313 StmtKind::DoWhile(dw) => {
314 let new_dw = arena.alloc(DoWhileStmt {
315 body: arena.alloc(folder.fold_stmt(arena, dw.body)),
316 condition: folder.fold_expr(arena, &dw.condition),
317 });
318 StmtKind::DoWhile(new_dw)
319 }
320 StmtKind::Function(func) => {
321 StmtKind::Function(arena.alloc(fold_function_decl(folder, arena, func)))
322 }
323 StmtKind::Break(expr) => {
324 StmtKind::Break(expr.map(|e| &*arena.alloc(folder.fold_expr(arena, e))))
325 }
326 StmtKind::Continue(expr) => {
327 StmtKind::Continue(expr.map(|e| &*arena.alloc(folder.fold_expr(arena, e))))
328 }
329 StmtKind::Switch(sw) => {
330 let mut cases = ArenaVec::with_capacity_in(sw.body.cases.len(), arena);
331 for case in sw.body.cases.iter() {
332 cases.push(SwitchCase {
333 value: case.value.as_ref().map(|v| folder.fold_expr(arena, v)),
334 body: folder.fold_stmts(arena, &case.body),
335 span: case.span,
336 });
337 }
338 let new_sw = arena.alloc(SwitchStmt {
339 expr: folder.fold_expr(arena, &sw.expr),
340 body: SwitchBody {
341 cases,
342 span: sw.body.span,
343 },
344 uses_alternative: sw.uses_alternative,
345 });
346 StmtKind::Switch(new_sw)
347 }
348 StmtKind::Goto(ident) => StmtKind::Goto(*ident),
349 StmtKind::Label(ident) => StmtKind::Label(*ident),
350 StmtKind::Declare(decl) => {
351 let mut directives = ArenaVec::with_capacity_in(decl.directives.len(), arena);
352 for (name, expr) in decl.directives.iter() {
353 directives.push((*name, folder.fold_expr(arena, expr)));
354 }
355 let new_decl = arena.alloc(DeclareStmt {
356 directives,
357 body: decl.body.map(|b| &*arena.alloc(folder.fold_stmt(arena, b))),
358 uses_alternative: decl.uses_alternative,
359 });
360 StmtKind::Declare(new_decl)
361 }
362 StmtKind::Unset(exprs) => StmtKind::Unset(fold_exprs(folder, arena, exprs)),
363 StmtKind::Throw(expr) => StmtKind::Throw(arena.alloc(folder.fold_expr(arena, expr))),
364 StmtKind::TryCatch(tc) => {
365 let mut catches = ArenaVec::with_capacity_in(tc.catches.len(), arena);
366 for catch in tc.catches.iter() {
367 catches.push(folder.fold_catch_clause(arena, catch));
368 }
369 let new_tc = arena.alloc(TryCatchStmt {
370 body: arena.alloc(folder.fold_block(arena, tc.body)),
371 catches,
372 finally: tc
373 .finally
374 .map(|f| &*arena.alloc(folder.fold_block(arena, f))),
375 finally_kw_span: tc.finally_kw_span,
376 });
377 StmtKind::TryCatch(new_tc)
378 }
379 StmtKind::Global(exprs) => StmtKind::Global(fold_exprs(folder, arena, exprs)),
380 StmtKind::Class(class) => {
381 StmtKind::Class(arena.alloc(fold_class_decl(folder, arena, class)))
382 }
383 StmtKind::Interface(iface) => {
384 StmtKind::Interface(arena.alloc(fold_interface_decl(folder, arena, iface)))
385 }
386 StmtKind::Trait(t) => StmtKind::Trait(arena.alloc(fold_trait_decl(folder, arena, t))),
387 StmtKind::Enum(e) => StmtKind::Enum(arena.alloc(fold_enum_decl(folder, arena, e))),
388 StmtKind::Namespace(ns) => {
389 let new_ns = arena.alloc(NamespaceDecl {
390 name: ns.name.as_ref().map(|n| folder.fold_name(arena, n)),
391 body: match &ns.body {
392 NamespaceBody::Braced(block) => {
393 NamespaceBody::Braced(arena.alloc(folder.fold_block(arena, block)))
394 }
395 NamespaceBody::Simple => NamespaceBody::Simple,
396 },
397 });
398 StmtKind::Namespace(new_ns)
399 }
400 StmtKind::Use(use_decl) => {
401 let mut uses = ArenaVec::with_capacity_in(use_decl.uses.len(), arena);
402 for item in use_decl.uses.iter() {
403 uses.push(UseItem {
404 name: folder.fold_name(arena, &item.name),
405 alias: item.alias,
406 kind: item.kind,
407 span: item.span,
408 });
409 }
410 let new_use = arena.alloc(UseDecl {
411 kind: use_decl.kind,
412 uses,
413 });
414 StmtKind::Use(new_use)
415 }
416 StmtKind::Const(items) => {
417 let mut new_items = ArenaVec::with_capacity_in(items.len(), arena);
418 for item in items.iter() {
419 new_items.push(ConstItem {
420 name: item.name,
421 value: folder.fold_expr(arena, &item.value),
422 attributes: fold_attrs(folder, arena, &item.attributes),
423 span: item.span,
424 doc_comment: item.doc_comment.as_ref().map(fold_comment),
425 });
426 }
427 StmtKind::Const(new_items)
428 }
429 StmtKind::StaticVar(vars) => {
430 let mut new_vars = ArenaVec::with_capacity_in(vars.len(), arena);
431 for var in vars.iter() {
432 new_vars.push(StaticVar {
433 name: var.name,
434 default: var.default.as_ref().map(|d| folder.fold_expr(arena, d)),
435 span: var.span,
436 });
437 }
438 StmtKind::StaticVar(new_vars)
439 }
440 StmtKind::HaltCompiler(s) => StmtKind::HaltCompiler(s),
441 StmtKind::Nop => StmtKind::Nop,
442 StmtKind::InlineHtml(s) => StmtKind::InlineHtml(s),
443 StmtKind::Error => StmtKind::Error,
444 };
445 Stmt {
446 kind,
447 span: stmt.span,
448 doc_comment: stmt.doc_comment.map(|c| &*arena.alloc(fold_comment(c))),
449 }
450}
451
452pub fn fold_expr<'new, 'src, F: Fold<'src> + ?Sized>(
454 folder: &mut F,
455 arena: &'new Bump,
456 expr: &Expr<'_, 'src>,
457) -> Expr<'new, 'src> {
458 let kind = match &expr.kind {
459 ExprKind::Int(n) => ExprKind::Int(*n),
460 ExprKind::Float(f) => ExprKind::Float(*f),
461 ExprKind::String(s) => ExprKind::String(fold_byte_str(*s, arena)),
462 ExprKind::InterpolatedString(parts) => {
463 ExprKind::InterpolatedString(fold_string_parts(folder, arena, parts))
464 }
465 ExprKind::Heredoc { label, parts } => ExprKind::Heredoc {
466 label,
467 parts: fold_string_parts(folder, arena, parts),
468 },
469 ExprKind::Nowdoc { label, value } => ExprKind::Nowdoc {
470 label,
471 value: arena.alloc_str(value),
472 },
473 ExprKind::ShellExec(parts) => ExprKind::ShellExec(fold_string_parts(folder, arena, parts)),
474 ExprKind::Bool(b) => ExprKind::Bool(*b),
475 ExprKind::Null => ExprKind::Null,
476 ExprKind::Variable(name) => ExprKind::Variable(fold_name_str(*name, arena)),
477 ExprKind::VariableVariable(inner) => {
478 ExprKind::VariableVariable(arena.alloc(folder.fold_expr(arena, inner)))
479 }
480 ExprKind::Identifier(name) => ExprKind::Identifier(fold_name_str(*name, arena)),
481 ExprKind::Name(name) => ExprKind::Name(folder.fold_name(arena, name)),
482 ExprKind::Assign(assign) => ExprKind::Assign(AssignExpr {
483 target: arena.alloc(folder.fold_expr(arena, assign.target)),
484 op: assign.op,
485 value: arena.alloc(folder.fold_expr(arena, assign.value)),
486 by_ref: assign.by_ref,
487 }),
488 ExprKind::Binary(binary) => ExprKind::Binary(BinaryExpr {
489 left: arena.alloc(folder.fold_expr(arena, binary.left)),
490 op: binary.op,
491 right: arena.alloc(folder.fold_expr(arena, binary.right)),
492 }),
493 ExprKind::UnaryPrefix(u) => ExprKind::UnaryPrefix(UnaryPrefixExpr {
494 op: u.op,
495 operand: arena.alloc(folder.fold_expr(arena, u.operand)),
496 }),
497 ExprKind::UnaryPostfix(u) => ExprKind::UnaryPostfix(UnaryPostfixExpr {
498 operand: arena.alloc(folder.fold_expr(arena, u.operand)),
499 op: u.op,
500 }),
501 ExprKind::Ternary(t) => ExprKind::Ternary(TernaryExpr {
502 condition: arena.alloc(folder.fold_expr(arena, t.condition)),
503 then_expr: t
504 .then_expr
505 .map(|e| &*arena.alloc(folder.fold_expr(arena, e))),
506 else_expr: arena.alloc(folder.fold_expr(arena, t.else_expr)),
507 }),
508 ExprKind::NullCoalesce(nc) => ExprKind::NullCoalesce(NullCoalesceExpr {
509 left: arena.alloc(folder.fold_expr(arena, nc.left)),
510 right: arena.alloc(folder.fold_expr(arena, nc.right)),
511 }),
512 ExprKind::FunctionCall(call) => ExprKind::FunctionCall(FunctionCallExpr {
513 name: arena.alloc(folder.fold_expr(arena, call.name)),
514 args: fold_args(folder, arena, &call.args),
515 }),
516 ExprKind::Array(elements) => {
517 let mut new_elements = ArenaVec::with_capacity_in(elements.len(), arena);
518 for elem in elements.iter() {
519 new_elements.push(ArrayElement {
520 key: elem.key.as_ref().map(|k| folder.fold_expr(arena, k)),
521 kind: match &elem.kind {
522 ArrayElementKind::Value(e) => {
523 ArrayElementKind::Value(folder.fold_expr(arena, e))
524 }
525 ArrayElementKind::Spread(e) => {
526 ArrayElementKind::Spread(folder.fold_expr(arena, e))
527 }
528 ArrayElementKind::ByRef(e) => {
529 ArrayElementKind::ByRef(folder.fold_expr(arena, e))
530 }
531 },
532 span: elem.span,
533 });
534 }
535 ExprKind::Array(new_elements)
536 }
537 ExprKind::ArrayAccess(access) => ExprKind::ArrayAccess(ArrayAccessExpr {
538 array: arena.alloc(folder.fold_expr(arena, access.array)),
539 index: access
540 .index
541 .map(|i| &*arena.alloc(folder.fold_expr(arena, i))),
542 }),
543 ExprKind::Print(e) => ExprKind::Print(arena.alloc(folder.fold_expr(arena, e))),
544 ExprKind::Parenthesized(e) => {
545 ExprKind::Parenthesized(arena.alloc(folder.fold_expr(arena, e)))
546 }
547 ExprKind::Cast(kind, e) => ExprKind::Cast(*kind, arena.alloc(folder.fold_expr(arena, e))),
548 ExprKind::ErrorSuppress(e) => {
549 ExprKind::ErrorSuppress(arena.alloc(folder.fold_expr(arena, e)))
550 }
551 ExprKind::Isset(exprs) => ExprKind::Isset(fold_exprs(folder, arena, exprs)),
552 ExprKind::Empty(e) => ExprKind::Empty(arena.alloc(folder.fold_expr(arena, e))),
553 ExprKind::Include(kind, e) => {
554 ExprKind::Include(*kind, arena.alloc(folder.fold_expr(arena, e)))
555 }
556 ExprKind::Eval(e) => ExprKind::Eval(arena.alloc(folder.fold_expr(arena, e))),
557 ExprKind::Exit(e) => ExprKind::Exit(e.map(|e| &*arena.alloc(folder.fold_expr(arena, e)))),
558 ExprKind::MagicConst(k) => ExprKind::MagicConst(*k),
559 ExprKind::Clone(e) => ExprKind::Clone(arena.alloc(folder.fold_expr(arena, e))),
560 ExprKind::CloneWith(obj, overrides) => ExprKind::CloneWith(
561 arena.alloc(folder.fold_expr(arena, obj)),
562 arena.alloc(folder.fold_expr(arena, overrides)),
563 ),
564 ExprKind::New(new_expr) => ExprKind::New(NewExpr {
565 class: arena.alloc(folder.fold_expr(arena, new_expr.class)),
566 args: fold_args(folder, arena, &new_expr.args),
567 }),
568 ExprKind::PropertyAccess(access) => ExprKind::PropertyAccess(PropertyAccessExpr {
569 object: arena.alloc(folder.fold_expr(arena, access.object)),
570 property: arena.alloc(folder.fold_expr(arena, access.property)),
571 }),
572 ExprKind::NullsafePropertyAccess(access) => {
573 ExprKind::NullsafePropertyAccess(PropertyAccessExpr {
574 object: arena.alloc(folder.fold_expr(arena, access.object)),
575 property: arena.alloc(folder.fold_expr(arena, access.property)),
576 })
577 }
578 ExprKind::MethodCall(call) => ExprKind::MethodCall(arena.alloc(MethodCallExpr {
579 object: arena.alloc(folder.fold_expr(arena, call.object)),
580 method: arena.alloc(folder.fold_expr(arena, call.method)),
581 args: fold_args(folder, arena, &call.args),
582 })),
583 ExprKind::NullsafeMethodCall(call) => {
584 ExprKind::NullsafeMethodCall(arena.alloc(MethodCallExpr {
585 object: arena.alloc(folder.fold_expr(arena, call.object)),
586 method: arena.alloc(folder.fold_expr(arena, call.method)),
587 args: fold_args(folder, arena, &call.args),
588 }))
589 }
590 ExprKind::StaticPropertyAccess(access) => {
591 ExprKind::StaticPropertyAccess(StaticAccessExpr {
592 class: arena.alloc(folder.fold_expr(arena, access.class)),
593 member: arena.alloc(folder.fold_expr(arena, access.member)),
594 })
595 }
596 ExprKind::StaticMethodCall(call) => {
597 ExprKind::StaticMethodCall(arena.alloc(StaticMethodCallExpr {
598 class: arena.alloc(folder.fold_expr(arena, call.class)),
599 method: arena.alloc(folder.fold_expr(arena, call.method)),
600 args: fold_args(folder, arena, &call.args),
601 }))
602 }
603 ExprKind::StaticMethodCallDynamic(call) => {
604 ExprKind::StaticMethodCallDynamic(arena.alloc(StaticMethodCallDynamicExpr {
605 class: arena.alloc(folder.fold_expr(arena, call.class)),
606 method: arena.alloc(folder.fold_expr(arena, call.method)),
607 args: fold_args(folder, arena, &call.args),
608 }))
609 }
610 ExprKind::ClassConstAccess(access) => ExprKind::ClassConstAccess(StaticAccessExpr {
611 class: arena.alloc(folder.fold_expr(arena, access.class)),
612 member: arena.alloc(folder.fold_expr(arena, access.member)),
613 }),
614 ExprKind::ClassConstAccessDynamic { class, member } => ExprKind::ClassConstAccessDynamic {
615 class: arena.alloc(folder.fold_expr(arena, class)),
616 member: arena.alloc(folder.fold_expr(arena, member)),
617 },
618 ExprKind::StaticPropertyAccessDynamic { class, member } => {
619 ExprKind::StaticPropertyAccessDynamic {
620 class: arena.alloc(folder.fold_expr(arena, class)),
621 member: arena.alloc(folder.fold_expr(arena, member)),
622 }
623 }
624 ExprKind::Closure(closure) => {
625 let mut use_vars = ArenaVec::with_capacity_in(closure.use_vars.len(), arena);
626 for var in closure.use_vars.iter() {
627 use_vars.push(folder.fold_closure_use_var(arena, var));
628 }
629 let new_closure = arena.alloc(ClosureExpr {
630 is_static: closure.is_static,
631 by_ref: closure.by_ref,
632 params: fold_params(folder, arena, &closure.params),
633 use_vars,
634 return_type: closure
635 .return_type
636 .as_ref()
637 .map(|t| folder.fold_type_hint(arena, t)),
638 body: arena.alloc(folder.fold_block(arena, closure.body)),
639 attributes: fold_attrs(folder, arena, &closure.attributes),
640 });
641 ExprKind::Closure(new_closure)
642 }
643 ExprKind::ArrowFunction(arrow) => {
644 let new_arrow = arena.alloc(ArrowFunctionExpr {
645 is_static: arrow.is_static,
646 by_ref: arrow.by_ref,
647 params: fold_params(folder, arena, &arrow.params),
648 return_type: arrow
649 .return_type
650 .as_ref()
651 .map(|t| folder.fold_type_hint(arena, t)),
652 body: arena.alloc(folder.fold_expr(arena, arrow.body)),
653 attributes: fold_attrs(folder, arena, &arrow.attributes),
654 });
655 ExprKind::ArrowFunction(new_arrow)
656 }
657 ExprKind::Match(match_expr) => ExprKind::Match(MatchExpr {
658 subject: arena.alloc(folder.fold_expr(arena, match_expr.subject)),
659 arms: {
660 let mut arms = ArenaVec::with_capacity_in(match_expr.arms.len(), arena);
661 for arm in match_expr.arms.iter() {
662 arms.push(folder.fold_match_arm(arena, arm));
663 }
664 arms
665 },
666 brace_span: match_expr.brace_span,
667 }),
668 ExprKind::Throw(e) => ExprKind::Throw(arena.alloc(folder.fold_expr(arena, e))),
669 ExprKind::Yield(y) => ExprKind::Yield(YieldExpr {
670 key: y.key.map(|k| &*arena.alloc(folder.fold_expr(arena, k))),
671 value: y.value.map(|v| &*arena.alloc(folder.fold_expr(arena, v))),
672 is_from: y.is_from,
673 }),
674 ExprKind::AnonymousClass(class) => {
675 ExprKind::AnonymousClass(arena.alloc(fold_class_decl(folder, arena, class)))
676 }
677 ExprKind::CallableCreate(cc) => {
678 let kind = match &cc.kind {
679 CallableCreateKind::Function(name) => {
680 CallableCreateKind::Function(arena.alloc(folder.fold_expr(arena, name)))
681 }
682 CallableCreateKind::Method { object, method } => CallableCreateKind::Method {
683 object: arena.alloc(folder.fold_expr(arena, object)),
684 method: arena.alloc(folder.fold_expr(arena, method)),
685 },
686 CallableCreateKind::NullsafeMethod { object, method } => {
687 CallableCreateKind::NullsafeMethod {
688 object: arena.alloc(folder.fold_expr(arena, object)),
689 method: arena.alloc(folder.fold_expr(arena, method)),
690 }
691 }
692 CallableCreateKind::StaticMethod { class, method } => {
693 CallableCreateKind::StaticMethod {
694 class: arena.alloc(folder.fold_expr(arena, class)),
695 method: arena.alloc(folder.fold_expr(arena, method)),
696 }
697 }
698 };
699 ExprKind::CallableCreate(CallableCreateExpr { kind })
700 }
701 ExprKind::Omit => ExprKind::Omit,
702 ExprKind::Error => ExprKind::Error,
703 };
704 Expr {
705 kind,
706 span: expr.span,
707 }
708}
709
710pub fn fold_param<'new, 'src, F: Fold<'src> + ?Sized>(
712 folder: &mut F,
713 arena: &'new Bump,
714 param: &Param<'_, 'src>,
715) -> Param<'new, 'src> {
716 Param {
717 name: param.name,
718 type_hint: param
719 .type_hint
720 .as_ref()
721 .map(|t| folder.fold_type_hint(arena, t)),
722 default: param.default.as_ref().map(|d| folder.fold_expr(arena, d)),
723 by_ref: param.by_ref,
724 variadic: param.variadic,
725 modifiers: param.modifiers,
726 attributes: fold_attrs(folder, arena, ¶m.attributes),
727 hooks: fold_hooks(folder, arena, ¶m.hooks),
728 doc_comment: param.doc_comment,
729 span: param.span,
730 }
731}
732
733pub fn fold_arg<'new, 'src, F: Fold<'src> + ?Sized>(
735 folder: &mut F,
736 arena: &'new Bump,
737 arg: &Arg<'_, 'src>,
738) -> Arg<'new, 'src> {
739 Arg {
740 name: arg.name.as_ref().map(|n| folder.fold_name(arena, n)),
741 kind: match &arg.kind {
742 ArgKind::Value(e) => ArgKind::Value(folder.fold_expr(arena, e)),
743 ArgKind::Spread(e) => ArgKind::Spread(folder.fold_expr(arena, e)),
744 ArgKind::ByRef(e) => ArgKind::ByRef(folder.fold_expr(arena, e)),
745 ArgKind::Placeholder => ArgKind::Placeholder,
746 ArgKind::SpreadPlaceholder => ArgKind::SpreadPlaceholder,
747 },
748 span: arg.span,
749 }
750}
751
752pub fn fold_class_member<'new, 'src, F: Fold<'src> + ?Sized>(
754 folder: &mut F,
755 arena: &'new Bump,
756 member: &ClassMember<'_, 'src>,
757) -> ClassMember<'new, 'src> {
758 let kind = match &member.kind {
759 ClassMemberKind::Property(prop) => {
760 ClassMemberKind::Property(fold_property_decl(folder, arena, prop))
761 }
762 ClassMemberKind::Method(method) => {
763 ClassMemberKind::Method(fold_method_decl(folder, arena, method))
764 }
765 ClassMemberKind::ClassConst(cc) => {
766 ClassMemberKind::ClassConst(fold_class_const_decl(folder, arena, cc))
767 }
768 ClassMemberKind::TraitUse(tu) => {
769 ClassMemberKind::TraitUse(folder.fold_trait_use(arena, tu))
770 }
771 };
772 ClassMember {
773 kind,
774 span: member.span,
775 }
776}
777
778pub fn fold_enum_member<'new, 'src, F: Fold<'src> + ?Sized>(
780 folder: &mut F,
781 arena: &'new Bump,
782 member: &EnumMember<'_, 'src>,
783) -> EnumMember<'new, 'src> {
784 let kind = match &member.kind {
785 EnumMemberKind::Case(case) => EnumMemberKind::Case(EnumCase {
786 name: case.name,
787 value: case.value.as_ref().map(|v| folder.fold_expr(arena, v)),
788 attributes: fold_attrs(folder, arena, &case.attributes),
789 doc_comment: case.doc_comment.as_ref().map(fold_comment),
790 }),
791 EnumMemberKind::Method(method) => {
792 EnumMemberKind::Method(fold_method_decl(folder, arena, method))
793 }
794 EnumMemberKind::ClassConst(cc) => {
795 EnumMemberKind::ClassConst(fold_class_const_decl(folder, arena, cc))
796 }
797 EnumMemberKind::TraitUse(tu) => EnumMemberKind::TraitUse(folder.fold_trait_use(arena, tu)),
798 };
799 EnumMember {
800 kind,
801 span: member.span,
802 }
803}
804
805pub fn fold_property_hook<'new, 'src, F: Fold<'src> + ?Sized>(
807 folder: &mut F,
808 arena: &'new Bump,
809 hook: &PropertyHook<'_, 'src>,
810) -> PropertyHook<'new, 'src> {
811 let body = match &hook.body {
812 PropertyHookBody::Block(block) => {
813 PropertyHookBody::Block(arena.alloc(fold_block(folder, arena, block)))
814 }
815 PropertyHookBody::Expression(expr) => {
816 PropertyHookBody::Expression(folder.fold_expr(arena, expr))
817 }
818 PropertyHookBody::Abstract => PropertyHookBody::Abstract,
819 };
820 PropertyHook {
821 kind: hook.kind,
822 body,
823 modifiers: hook.modifiers,
824 by_ref: hook.by_ref,
825 params: fold_params(folder, arena, &hook.params),
826 attributes: fold_attrs(folder, arena, &hook.attributes),
827 span: hook.span,
828 }
829}
830
831pub fn fold_type_hint<'new, 'src, F: Fold<'src> + ?Sized>(
833 folder: &mut F,
834 arena: &'new Bump,
835 type_hint: &TypeHint<'_, 'src>,
836) -> TypeHint<'new, 'src> {
837 let kind = match &type_hint.kind {
838 TypeHintKind::Named(name) => TypeHintKind::Named(folder.fold_name(arena, name)),
839 TypeHintKind::Keyword(builtin, span) => TypeHintKind::Keyword(*builtin, *span),
840 TypeHintKind::Nullable(inner) => {
841 TypeHintKind::Nullable(arena.alloc(folder.fold_type_hint(arena, inner)))
842 }
843 TypeHintKind::Union(types) => {
844 let mut new_types = ArenaVec::with_capacity_in(types.len(), arena);
845 for t in types.iter() {
846 new_types.push(folder.fold_type_hint(arena, t));
847 }
848 TypeHintKind::Union(new_types)
849 }
850 TypeHintKind::Intersection(types) => {
851 let mut new_types = ArenaVec::with_capacity_in(types.len(), arena);
852 for t in types.iter() {
853 new_types.push(folder.fold_type_hint(arena, t));
854 }
855 TypeHintKind::Intersection(new_types)
856 }
857 };
858 TypeHint {
859 kind,
860 span: type_hint.span,
861 }
862}
863
864pub fn fold_attribute<'new, 'src, F: Fold<'src> + ?Sized>(
866 folder: &mut F,
867 arena: &'new Bump,
868 attribute: &Attribute<'_, 'src>,
869) -> Attribute<'new, 'src> {
870 Attribute {
871 name: folder.fold_name(arena, &attribute.name),
872 args: fold_args(folder, arena, &attribute.args),
873 span: attribute.span,
874 }
875}
876
877pub fn fold_catch_clause<'new, 'src, F: Fold<'src> + ?Sized>(
879 folder: &mut F,
880 arena: &'new Bump,
881 catch: &CatchClause<'_, 'src>,
882) -> CatchClause<'new, 'src> {
883 let mut types = ArenaVec::with_capacity_in(catch.types.len(), arena);
884 for ty in catch.types.iter() {
885 types.push(folder.fold_name(arena, ty));
886 }
887 CatchClause {
888 types,
889 var: catch.var,
890 body: arena.alloc(folder.fold_block(arena, catch.body)),
891 span: catch.span,
892 }
893}
894
895pub fn fold_match_arm<'new, 'src, F: Fold<'src> + ?Sized>(
897 folder: &mut F,
898 arena: &'new Bump,
899 arm: &MatchArm<'_, 'src>,
900) -> MatchArm<'new, 'src> {
901 let conditions = arm.conditions.as_ref().map(|conds| {
902 let mut new_conds = ArenaVec::with_capacity_in(conds.len(), arena);
903 for c in conds.iter() {
904 new_conds.push(folder.fold_expr(arena, c));
905 }
906 new_conds
907 });
908 MatchArm {
909 conditions,
910 body: folder.fold_expr(arena, &arm.body),
911 span: arm.span,
912 }
913}
914
915pub fn fold_trait_use<'new, 'src, F: Fold<'src> + ?Sized>(
917 folder: &mut F,
918 arena: &'new Bump,
919 trait_use: &TraitUseDecl<'_, 'src>,
920) -> TraitUseDecl<'new, 'src> {
921 let mut traits = ArenaVec::with_capacity_in(trait_use.traits.len(), arena);
922 for t in trait_use.traits.iter() {
923 traits.push(folder.fold_name(arena, t));
924 }
925 let mut adaptations = ArenaVec::with_capacity_in(trait_use.adaptations.len(), arena);
926 for a in trait_use.adaptations.iter() {
927 adaptations.push(folder.fold_trait_adaptation(arena, a));
928 }
929 TraitUseDecl {
930 traits,
931 adaptations,
932 adaptations_brace_span: trait_use.adaptations_brace_span,
933 doc_comment: trait_use.doc_comment.as_ref().map(fold_comment),
934 }
935}
936
937pub fn fold_trait_adaptation<'new, 'src, F: Fold<'src> + ?Sized>(
939 folder: &mut F,
940 arena: &'new Bump,
941 adaptation: &TraitAdaptation<'_, 'src>,
942) -> TraitAdaptation<'new, 'src> {
943 let kind = match &adaptation.kind {
944 TraitAdaptationKind::Precedence {
945 trait_name,
946 method,
947 insteadof,
948 } => {
949 let mut new_insteadof = ArenaVec::with_capacity_in(insteadof.len(), arena);
950 for n in insteadof.iter() {
951 new_insteadof.push(folder.fold_name(arena, n));
952 }
953 TraitAdaptationKind::Precedence {
954 trait_name: folder.fold_name(arena, trait_name),
955 method: folder.fold_name(arena, method),
956 insteadof: new_insteadof,
957 }
958 }
959 TraitAdaptationKind::Alias {
960 trait_name,
961 method,
962 new_modifier,
963 is_final,
964 new_name,
965 } => TraitAdaptationKind::Alias {
966 trait_name: trait_name.as_ref().map(|n| folder.fold_name(arena, n)),
967 method: folder.fold_name(arena, method),
968 new_modifier: *new_modifier,
969 is_final: *is_final,
970 new_name: new_name.as_ref().map(|n| folder.fold_name(arena, n)),
971 },
972 };
973 TraitAdaptation {
974 kind,
975 span: adaptation.span,
976 }
977}
978
979pub fn fold_name<'new, 'src, F: Fold<'src> + ?Sized>(
981 _folder: &mut F,
982 arena: &'new Bump,
983 name: &Name<'_, 'src>,
984) -> Name<'new, 'src> {
985 match name {
986 Name::Simple { value, span } => Name::Simple { value, span: *span },
987 Name::Complex { parts, kind, span } => {
988 let mut new_parts = ArenaVec::with_capacity_in(parts.len(), arena);
989 for &part in parts.iter() {
990 new_parts.push(part);
991 }
992 Name::Complex {
993 parts: new_parts,
994 kind: *kind,
995 span: *span,
996 }
997 }
998 Name::Error { span } => Name::Error { span: *span },
999 }
1000}
1001
1002fn fold_function_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1007 folder: &mut F,
1008 arena: &'new Bump,
1009 func: &FunctionDecl<'_, 'src>,
1010) -> FunctionDecl<'new, 'src> {
1011 FunctionDecl {
1012 name: func.name,
1013 params: fold_params(folder, arena, &func.params),
1014 body: arena.alloc(folder.fold_block(arena, func.body)),
1015 return_type: func
1016 .return_type
1017 .as_ref()
1018 .map(|t| folder.fold_type_hint(arena, t)),
1019 by_ref: func.by_ref,
1020 attributes: fold_attrs(folder, arena, &func.attributes),
1021 doc_comment: func.doc_comment.as_ref().map(fold_comment),
1022 }
1023}
1024
1025fn fold_method_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1026 folder: &mut F,
1027 arena: &'new Bump,
1028 method: &MethodDecl<'_, 'src>,
1029) -> MethodDecl<'new, 'src> {
1030 MethodDecl {
1031 name: method.name,
1032 modifiers: method.modifiers,
1033 by_ref: method.by_ref,
1034 params: fold_params(folder, arena, &method.params),
1035 return_type: method
1036 .return_type
1037 .as_ref()
1038 .map(|t| folder.fold_type_hint(arena, t)),
1039 body: method
1040 .body
1041 .map(|b| &*arena.alloc(folder.fold_block(arena, b))),
1042 attributes: fold_attrs(folder, arena, &method.attributes),
1043 doc_comment: method.doc_comment.as_ref().map(fold_comment),
1044 }
1045}
1046
1047fn fold_property_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1048 folder: &mut F,
1049 arena: &'new Bump,
1050 prop: &PropertyDecl<'_, 'src>,
1051) -> PropertyDecl<'new, 'src> {
1052 PropertyDecl {
1053 name: prop.name,
1054 modifiers: prop.modifiers,
1055 type_hint: prop
1056 .type_hint
1057 .as_ref()
1058 .map(|t| folder.fold_type_hint(arena, t)),
1059 default: prop.default.as_ref().map(|d| folder.fold_expr(arena, d)),
1060 attributes: fold_attrs(folder, arena, &prop.attributes),
1061 hooks: fold_hooks(folder, arena, &prop.hooks),
1062 doc_comment: prop.doc_comment.as_ref().map(fold_comment),
1063 }
1064}
1065
1066fn fold_class_const_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1067 folder: &mut F,
1068 arena: &'new Bump,
1069 cc: &ClassConstDecl<'_, 'src>,
1070) -> ClassConstDecl<'new, 'src> {
1071 ClassConstDecl {
1072 name: cc.name,
1073 modifiers: cc.modifiers,
1074 type_hint: cc
1075 .type_hint
1076 .map(|t| &*arena.alloc(folder.fold_type_hint(arena, t))),
1077 value: folder.fold_expr(arena, &cc.value),
1078 attributes: fold_attrs(folder, arena, &cc.attributes),
1079 doc_comment: cc.doc_comment.as_ref().map(fold_comment),
1080 }
1081}
1082
1083fn fold_class_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1084 folder: &mut F,
1085 arena: &'new Bump,
1086 class: &ClassDecl<'_, 'src>,
1087) -> ClassDecl<'new, 'src> {
1088 let mut members = ArenaVec::with_capacity_in(class.body.members.len(), arena);
1089 for member in class.body.members.iter() {
1090 members.push(folder.fold_class_member(arena, member));
1091 }
1092 ClassDecl {
1093 name: class.name,
1094 modifiers: class.modifiers.clone(),
1095 extends: class.extends.as_ref().map(|n| folder.fold_name(arena, n)),
1096 implements: {
1097 let mut v = ArenaVec::with_capacity_in(class.implements.len(), arena);
1098 for n in class.implements.iter() {
1099 v.push(folder.fold_name(arena, n));
1100 }
1101 v
1102 },
1103 body: ClassBody {
1104 members,
1105 span: class.body.span,
1106 },
1107 attributes: fold_attrs(folder, arena, &class.attributes),
1108 doc_comment: class.doc_comment.as_ref().map(fold_comment),
1109 }
1110}
1111
1112fn fold_interface_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1113 folder: &mut F,
1114 arena: &'new Bump,
1115 iface: &InterfaceDecl<'_, 'src>,
1116) -> InterfaceDecl<'new, 'src> {
1117 let mut extends = ArenaVec::with_capacity_in(iface.extends.len(), arena);
1118 for n in iface.extends.iter() {
1119 extends.push(folder.fold_name(arena, n));
1120 }
1121 let mut members = ArenaVec::with_capacity_in(iface.body.members.len(), arena);
1122 for member in iface.body.members.iter() {
1123 members.push(folder.fold_class_member(arena, member));
1124 }
1125 InterfaceDecl {
1126 name: iface.name,
1127 extends,
1128 body: ClassBody {
1129 members,
1130 span: iface.body.span,
1131 },
1132 attributes: fold_attrs(folder, arena, &iface.attributes),
1133 doc_comment: iface.doc_comment.as_ref().map(fold_comment),
1134 }
1135}
1136
1137fn fold_trait_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1138 folder: &mut F,
1139 arena: &'new Bump,
1140 t: &TraitDecl<'_, 'src>,
1141) -> TraitDecl<'new, 'src> {
1142 let mut members = ArenaVec::with_capacity_in(t.body.members.len(), arena);
1143 for member in t.body.members.iter() {
1144 members.push(folder.fold_class_member(arena, member));
1145 }
1146 TraitDecl {
1147 name: t.name,
1148 body: ClassBody {
1149 members,
1150 span: t.body.span,
1151 },
1152 attributes: fold_attrs(folder, arena, &t.attributes),
1153 doc_comment: t.doc_comment.as_ref().map(fold_comment),
1154 }
1155}
1156
1157fn fold_enum_decl<'new, 'src, F: Fold<'src> + ?Sized>(
1158 folder: &mut F,
1159 arena: &'new Bump,
1160 e: &EnumDecl<'_, 'src>,
1161) -> EnumDecl<'new, 'src> {
1162 let mut members = ArenaVec::with_capacity_in(e.body.members.len(), arena);
1163 for member in e.body.members.iter() {
1164 members.push(folder.fold_enum_member(arena, member));
1165 }
1166 EnumDecl {
1167 name: e.name,
1168 scalar_type: e.scalar_type.as_ref().map(|n| folder.fold_name(arena, n)),
1169 implements: {
1170 let mut v = ArenaVec::with_capacity_in(e.implements.len(), arena);
1171 for n in e.implements.iter() {
1172 v.push(folder.fold_name(arena, n));
1173 }
1174 v
1175 },
1176 body: EnumBody {
1177 members,
1178 span: e.body.span,
1179 },
1180 attributes: fold_attrs(folder, arena, &e.attributes),
1181 doc_comment: e.doc_comment.as_ref().map(fold_comment),
1182 }
1183}
1184
1185pub fn fold_stmts<'new, 'src, F: Fold<'src> + ?Sized>(
1191 folder: &mut F,
1192 arena: &'new Bump,
1193 stmts: &[Stmt<'_, 'src>],
1194) -> ArenaVec<'new, Stmt<'new, 'src>> {
1195 let mut vec = ArenaVec::with_capacity_in(stmts.len(), arena);
1196 for stmt in stmts {
1197 vec.push(folder.fold_stmt(arena, stmt));
1198 }
1199 vec
1200}
1201
1202pub fn fold_block<'new, 'src, F: Fold<'src> + ?Sized>(
1204 folder: &mut F,
1205 arena: &'new Bump,
1206 block: &Block<'_, 'src>,
1207) -> Block<'new, 'src> {
1208 Block {
1209 stmts: folder.fold_stmts(arena, &block.stmts),
1210 span: block.span,
1211 }
1212}
1213
1214fn fold_exprs<'new, 'src, F: Fold<'src> + ?Sized>(
1215 folder: &mut F,
1216 arena: &'new Bump,
1217 exprs: &[Expr<'_, 'src>],
1218) -> ArenaVec<'new, Expr<'new, 'src>> {
1219 let mut vec = ArenaVec::with_capacity_in(exprs.len(), arena);
1220 for expr in exprs {
1221 vec.push(folder.fold_expr(arena, expr));
1222 }
1223 vec
1224}
1225
1226fn fold_args<'new, 'src, F: Fold<'src> + ?Sized>(
1227 folder: &mut F,
1228 arena: &'new Bump,
1229 args: &[Arg<'_, 'src>],
1230) -> ArenaVec<'new, Arg<'new, 'src>> {
1231 let mut vec = ArenaVec::with_capacity_in(args.len(), arena);
1232 for arg in args {
1233 vec.push(folder.fold_arg(arena, arg));
1234 }
1235 vec
1236}
1237
1238fn fold_params<'new, 'src, F: Fold<'src> + ?Sized>(
1239 folder: &mut F,
1240 arena: &'new Bump,
1241 params: &[Param<'_, 'src>],
1242) -> ArenaVec<'new, Param<'new, 'src>> {
1243 let mut vec = ArenaVec::with_capacity_in(params.len(), arena);
1244 for param in params {
1245 vec.push(folder.fold_param(arena, param));
1246 }
1247 vec
1248}
1249
1250fn fold_attrs<'new, 'src, F: Fold<'src> + ?Sized>(
1251 folder: &mut F,
1252 arena: &'new Bump,
1253 attrs: &[Attribute<'_, 'src>],
1254) -> ArenaVec<'new, Attribute<'new, 'src>> {
1255 let mut vec = ArenaVec::with_capacity_in(attrs.len(), arena);
1256 for attr in attrs {
1257 vec.push(folder.fold_attribute(arena, attr));
1258 }
1259 vec
1260}
1261
1262fn fold_hooks<'new, 'src, F: Fold<'src> + ?Sized>(
1263 folder: &mut F,
1264 arena: &'new Bump,
1265 hooks: &[PropertyHook<'_, 'src>],
1266) -> ArenaVec<'new, PropertyHook<'new, 'src>> {
1267 let mut vec = ArenaVec::with_capacity_in(hooks.len(), arena);
1268 for hook in hooks {
1269 vec.push(folder.fold_property_hook(arena, hook));
1270 }
1271 vec
1272}
1273
1274fn fold_string_parts<'new, 'src, F: Fold<'src> + ?Sized>(
1275 folder: &mut F,
1276 arena: &'new Bump,
1277 parts: &[StringPart<'_, 'src>],
1278) -> ArenaVec<'new, StringPart<'new, 'src>> {
1279 let mut vec = ArenaVec::with_capacity_in(parts.len(), arena);
1280 for part in parts {
1281 vec.push(match part {
1282 StringPart::Literal(s) => StringPart::Literal(fold_byte_str(*s, arena)),
1283 StringPart::Expr(e) => StringPart::Expr(folder.fold_expr(arena, e)),
1284 });
1285 }
1286 vec
1287}
1288
1289pub fn fold_byte_str<'new, 'src>(
1296 value: ByteStr<'_, 'src>,
1297 arena: &'new Bump,
1298) -> ByteStr<'new, 'src> {
1299 match value.into_src_str() {
1300 Some(s) => ByteStr::from_source(s),
1301 None => ByteStr::new_in(arena, value.as_bytes()),
1302 }
1303}
1304
1305pub fn fold_name_str<'new, 'src>(
1309 name: NameStr<'_, 'src>,
1310 arena: &'new Bump,
1311) -> NameStr<'new, 'src> {
1312 if let Some(s) = name.into_src_str() {
1313 NameStr::from_source(s)
1314 } else {
1315 NameStr::from_arena(arena.alloc_str(name.as_str()))
1316 }
1317}
1318
1319fn fold_comment<'src>(comment: &Comment<'src>) -> Comment<'src> {
1320 Comment {
1321 kind: comment.kind,
1322 text: comment.text,
1323 span: comment.span,
1324 }
1325}