1pub mod fold;
21pub mod visitor;
22
23pub use fold::{
24 fold_owned_arg, fold_owned_attribute, fold_owned_catch_clause, fold_owned_class_member,
25 fold_owned_closure_use_var, fold_owned_enum_member, fold_owned_expr, fold_owned_match_arm,
26 fold_owned_name, fold_owned_param, fold_owned_program, fold_owned_property_hook,
27 fold_owned_stmt, fold_owned_type_hint, FoldOwned,
28};
29pub use visitor::{
30 walk_owned_arg, walk_owned_attribute, walk_owned_catch_clause, walk_owned_class_member,
31 walk_owned_comments, walk_owned_enum_member, walk_owned_expr, walk_owned_match_arm,
32 walk_owned_name, walk_owned_param, walk_owned_program, walk_owned_property_hook,
33 walk_owned_stmt, walk_owned_trait_use, walk_owned_type_hint, OwnedScope, OwnedScopeVisitor,
34 OwnedScopeWalker, OwnedVisitor,
35};
36
37use serde::Serialize;
38
39use crate::ast as arena_ast;
40use crate::ast::{
41 AssignOp, BinaryOp, BuiltinType, CastKind, ClassModifiers, CommentKind, IncludeKind,
42 MagicConstKind, NameKind, PropertyHookKind, UnaryPostfixOp, UnaryPrefixOp, UseKind, Visibility,
43};
44use crate::Span;
45
46fn is_false(b: &bool) -> bool {
51 !*b
52}
53
54fn slice_is_empty<T>(v: &[T]) -> bool {
55 v.is_empty()
56}
57
58pub type Ident = Option<Box<str>>;
70
71#[derive(Debug, Clone, Serialize)]
81pub struct Name {
82 pub parts: Box<[Box<str>]>,
83 pub kind: NameKind,
84 pub span: Span,
85}
86
87#[derive(Debug, Clone, Serialize)]
92pub struct Comment {
93 pub kind: CommentKind,
94 pub text: Box<str>,
95 pub span: Span,
96}
97
98#[derive(Debug, Clone, Serialize)]
106pub struct TypeHint {
107 pub kind: TypeHintKind,
108 pub span: Span,
109}
110
111#[derive(Debug, Clone)]
112pub enum TypeHintKind {
113 Named(Name),
114 Keyword(BuiltinType, Span),
116 Nullable(Box<TypeHint>),
117 Union(Box<[TypeHint]>),
118 Intersection(Box<[TypeHint]>),
119}
120
121impl Serialize for TypeHintKind {
122 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
123 match self {
124 Self::Named(name) => s.serialize_newtype_variant("TypeHintKind", 0, "Named", name),
125 Self::Nullable(inner) => {
126 s.serialize_newtype_variant("TypeHintKind", 2, "Nullable", inner)
127 }
128 Self::Union(types) => s.serialize_newtype_variant("TypeHintKind", 3, "Union", types),
129 Self::Intersection(types) => {
130 s.serialize_newtype_variant("TypeHintKind", 4, "Intersection", types)
131 }
132 Self::Keyword(builtin, span) => {
133 struct BuiltinNameRepr<'a>(&'a BuiltinType, &'a Span);
134 impl Serialize for BuiltinNameRepr<'_> {
135 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
136 use serde::ser::SerializeStruct;
137 let mut st = s.serialize_struct("Name", 3)?;
138 st.serialize_field("parts", &[self.0.as_str()])?;
139 st.serialize_field("kind", &NameKind::Unqualified)?;
140 st.serialize_field("span", self.1)?;
141 st.end()
142 }
143 }
144 s.serialize_newtype_variant(
145 "TypeHintKind",
146 0,
147 "Named",
148 &BuiltinNameRepr(builtin, span),
149 )
150 }
151 }
152 }
153}
154
155#[derive(Debug, Clone, Serialize)]
160pub struct Arg {
161 pub name: Option<Name>,
162 pub value: Expr,
163 pub unpack: bool,
164 pub by_ref: bool,
165 pub span: Span,
166}
167
168#[derive(Debug, Clone, Serialize)]
169pub struct Attribute {
170 pub name: Name,
171 pub args: Box<[Arg]>,
172 pub span: Span,
173}
174
175#[derive(Debug, Clone, Serialize)]
180pub struct Program {
181 pub stmts: Box<[Stmt]>,
182 pub span: Span,
183}
184
185#[derive(Debug, Clone, Serialize)]
190pub struct Stmt {
191 pub kind: StmtKind,
192 pub span: Span,
193}
194
195#[derive(Debug, Clone, Serialize)]
196pub enum StmtKind {
197 Expression(Box<Expr>),
198 Echo(Box<[Expr]>),
199 Return(Option<Box<Expr>>),
200 Block(Box<[Stmt]>),
201 If(Box<IfStmt>),
202 While(Box<WhileStmt>),
203 For(Box<ForStmt>),
204 Foreach(Box<ForeachStmt>),
205 DoWhile(Box<DoWhileStmt>),
206 Function(Box<FunctionDecl>),
207 Break(Option<Box<Expr>>),
208 Continue(Option<Box<Expr>>),
209 Switch(Box<SwitchStmt>),
210 Goto(Ident),
211 Label(Box<str>),
212 Declare(Box<DeclareStmt>),
213 Unset(Box<[Expr]>),
214 Throw(Box<Expr>),
215 TryCatch(Box<TryCatchStmt>),
216 Global(Box<[Expr]>),
217 Class(Box<ClassDecl>),
218 Interface(Box<InterfaceDecl>),
219 Trait(Box<TraitDecl>),
220 Enum(Box<EnumDecl>),
221 Namespace(Box<NamespaceDecl>),
222 Use(Box<UseDecl>),
223 Const(Box<[ConstItem]>),
224 StaticVar(Box<[StaticVar]>),
225 HaltCompiler(Box<str>),
226 Nop,
227 InlineHtml(Box<str>),
228 Error,
229}
230
231#[derive(Debug, Clone, Serialize)]
232pub struct IfStmt {
233 pub condition: Expr,
234 pub then_branch: Box<Stmt>,
235 pub elseif_branches: Box<[ElseIfBranch]>,
236 pub else_branch: Option<Box<Stmt>>,
237 #[serde(default, skip_serializing_if = "is_false")]
238 pub uses_alternative: bool,
239}
240
241#[derive(Debug, Clone, Serialize)]
242pub struct ElseIfBranch {
243 pub condition: Expr,
244 pub body: Stmt,
245 pub span: Span,
246}
247
248#[derive(Debug, Clone, Serialize)]
249pub struct WhileStmt {
250 pub condition: Expr,
251 pub body: Box<Stmt>,
252 #[serde(default, skip_serializing_if = "is_false")]
253 pub uses_alternative: bool,
254}
255
256#[derive(Debug, Clone, Serialize)]
257pub struct ForStmt {
258 pub init: Box<[Expr]>,
259 pub condition: Box<[Expr]>,
260 pub update: Box<[Expr]>,
261 pub body: Box<Stmt>,
262 #[serde(default, skip_serializing_if = "is_false")]
263 pub uses_alternative: bool,
264}
265
266#[derive(Debug, Clone, Serialize)]
267pub struct ForeachStmt {
268 pub expr: Expr,
269 pub key: Option<Expr>,
270 pub value: Expr,
271 pub body: Box<Stmt>,
272 #[serde(default, skip_serializing_if = "is_false")]
273 pub uses_alternative: bool,
274}
275
276#[derive(Debug, Clone, Serialize)]
277pub struct DoWhileStmt {
278 pub body: Box<Stmt>,
279 pub condition: Expr,
280}
281
282#[derive(Debug, Clone, Serialize)]
283pub struct SwitchStmt {
284 pub expr: Expr,
285 pub cases: Box<[SwitchCase]>,
286 #[serde(default, skip_serializing_if = "is_false")]
287 pub uses_alternative: bool,
288}
289
290#[derive(Debug, Clone, Serialize)]
291pub struct SwitchCase {
292 pub value: Option<Expr>,
293 pub body: Box<[Stmt]>,
294 pub span: Span,
295}
296
297#[derive(Debug, Clone, Serialize)]
298pub struct TryCatchStmt {
299 pub body: Box<[Stmt]>,
300 pub catches: Box<[CatchClause]>,
301 pub finally: Option<Box<[Stmt]>>,
302}
303
304#[derive(Debug, Clone, Serialize)]
305pub struct CatchClause {
306 pub types: Box<[Name]>,
307 pub var: Option<Box<str>>,
308 pub body: Box<[Stmt]>,
309 pub span: Span,
310}
311
312#[derive(Debug, Clone, Serialize)]
313pub struct NamespaceDecl {
314 pub name: Option<Name>,
315 pub body: NamespaceBody,
316}
317
318#[derive(Debug, Clone, Serialize)]
319pub enum NamespaceBody {
320 Braced(Box<[Stmt]>),
321 Simple,
322}
323
324#[derive(Debug, Clone, Serialize)]
325pub struct DeclareStmt {
326 pub directives: Box<[(Box<str>, Expr)]>,
327 pub body: Option<Box<Stmt>>,
328 #[serde(default, skip_serializing_if = "is_false")]
329 pub uses_alternative: bool,
330}
331
332#[derive(Debug, Clone, Serialize)]
333pub struct UseDecl {
334 pub kind: UseKind,
335 pub uses: Box<[UseItem]>,
336}
337
338#[derive(Debug, Clone, Serialize)]
339pub struct UseItem {
340 pub name: Name,
341 pub alias: Option<Box<str>>,
342 #[serde(skip_serializing_if = "Option::is_none")]
343 pub kind: Option<UseKind>,
344 pub span: Span,
345}
346
347#[derive(Debug, Clone, Serialize)]
348pub struct ConstItem {
349 pub name: Ident,
350 pub value: Expr,
351 pub attributes: Box<[Attribute]>,
352 pub span: Span,
353 #[serde(skip_serializing_if = "Option::is_none")]
354 pub doc_comment: Option<Comment>,
355}
356
357#[derive(Debug, Clone, Serialize)]
358pub struct StaticVar {
359 pub name: Ident,
360 pub default: Option<Expr>,
361 pub span: Span,
362}
363
364#[derive(Debug, Clone, Serialize)]
369pub struct Expr {
370 pub kind: ExprKind,
371 pub span: Span,
372}
373
374#[derive(Debug, Clone, Serialize)]
375pub enum ExprKind {
376 Int(i64),
377 Float(f64),
378 String(Box<str>),
379 InterpolatedString(Box<[StringPart]>),
380 Heredoc {
381 label: Box<str>,
382 parts: Box<[StringPart]>,
383 },
384 Nowdoc {
385 label: Box<str>,
386 value: Box<str>,
387 },
388 ShellExec(Box<[StringPart]>),
389 Bool(bool),
390 Null,
391 Variable(Box<str>),
392 VariableVariable(Box<Expr>),
393 Identifier(Box<str>),
394 Assign(AssignExpr),
395 Binary(BinaryExpr),
396 UnaryPrefix(UnaryPrefixExpr),
397 UnaryPostfix(UnaryPostfixExpr),
398 Ternary(TernaryExpr),
399 NullCoalesce(NullCoalesceExpr),
400 FunctionCall(FunctionCallExpr),
401 Array(Box<[ArrayElement]>),
402 ArrayAccess(ArrayAccessExpr),
403 Print(Box<Expr>),
404 Parenthesized(Box<Expr>),
405 Cast(CastKind, Box<Expr>),
406 ErrorSuppress(Box<Expr>),
407 Isset(Box<[Expr]>),
408 Empty(Box<Expr>),
409 Include(IncludeKind, Box<Expr>),
410 Eval(Box<Expr>),
411 Exit(Option<Box<Expr>>),
412 MagicConst(MagicConstKind),
413 Clone(Box<Expr>),
414 CloneWith(Box<Expr>, Box<Expr>),
415 New(NewExpr),
416 PropertyAccess(PropertyAccessExpr),
417 NullsafePropertyAccess(PropertyAccessExpr),
418 MethodCall(Box<MethodCallExpr>),
419 NullsafeMethodCall(Box<MethodCallExpr>),
420 StaticPropertyAccess(StaticAccessExpr),
421 StaticMethodCall(Box<StaticMethodCallExpr>),
422 StaticDynMethodCall(Box<StaticDynMethodCallExpr>),
423 ClassConstAccess(StaticAccessExpr),
424 ClassConstAccessDynamic {
425 class: Box<Expr>,
426 member: Box<Expr>,
427 },
428 StaticPropertyAccessDynamic {
429 class: Box<Expr>,
430 member: Box<Expr>,
431 },
432 Closure(Box<ClosureExpr>),
433 ArrowFunction(Box<ArrowFunctionExpr>),
434 Match(MatchExpr),
435 ThrowExpr(Box<Expr>),
436 Yield(YieldExpr),
437 AnonymousClass(Box<ClassDecl>),
438 CallableCreate(CallableCreateExpr),
439 Omit,
440 Error,
441}
442
443#[derive(Debug, Clone, Serialize)]
444pub struct AssignExpr {
445 pub target: Box<Expr>,
446 pub op: AssignOp,
447 pub value: Box<Expr>,
448 #[serde(skip_serializing_if = "is_false")]
449 pub by_ref: bool,
450}
451
452#[derive(Debug, Clone, Serialize)]
453pub struct BinaryExpr {
454 pub left: Box<Expr>,
455 pub op: BinaryOp,
456 pub right: Box<Expr>,
457}
458
459#[derive(Debug, Clone, Serialize)]
460pub struct UnaryPrefixExpr {
461 pub op: UnaryPrefixOp,
462 pub operand: Box<Expr>,
463}
464
465#[derive(Debug, Clone, Serialize)]
466pub struct UnaryPostfixExpr {
467 pub operand: Box<Expr>,
468 pub op: UnaryPostfixOp,
469}
470
471#[derive(Debug, Clone, Serialize)]
472pub struct TernaryExpr {
473 pub condition: Box<Expr>,
474 pub then_expr: Option<Box<Expr>>,
475 pub else_expr: Box<Expr>,
476}
477
478#[derive(Debug, Clone, Serialize)]
479pub struct NullCoalesceExpr {
480 pub left: Box<Expr>,
481 pub right: Box<Expr>,
482}
483
484#[derive(Debug, Clone, Serialize)]
485pub struct FunctionCallExpr {
486 pub name: Box<Expr>,
487 pub args: Box<[Arg]>,
488}
489
490#[derive(Debug, Clone, Serialize)]
491pub struct ArrayElement {
492 pub key: Option<Expr>,
493 pub value: Expr,
494 pub unpack: bool,
495 #[serde(skip_serializing_if = "is_false")]
496 pub by_ref: bool,
497 pub span: Span,
498}
499
500#[derive(Debug, Clone, Serialize)]
501pub struct ArrayAccessExpr {
502 pub array: Box<Expr>,
503 pub index: Option<Box<Expr>>,
504}
505
506#[derive(Debug, Clone, Serialize)]
507pub struct NewExpr {
508 pub class: Box<Expr>,
509 pub args: Box<[Arg]>,
510}
511
512#[derive(Debug, Clone, Serialize)]
513pub struct PropertyAccessExpr {
514 pub object: Box<Expr>,
515 pub property: Box<Expr>,
516}
517
518#[derive(Debug, Clone, Serialize)]
519pub struct MethodCallExpr {
520 pub object: Box<Expr>,
521 pub method: Box<Expr>,
522 pub args: Box<[Arg]>,
523}
524
525#[derive(Debug, Clone, Serialize)]
526pub struct StaticAccessExpr {
527 pub class: Box<Expr>,
528 pub member: Box<Expr>,
529}
530
531#[derive(Debug, Clone, Serialize)]
532pub struct StaticMethodCallExpr {
533 pub class: Box<Expr>,
534 pub method: Box<Expr>,
535 pub args: Box<[Arg]>,
536}
537
538#[derive(Debug, Clone, Serialize)]
539pub struct StaticDynMethodCallExpr {
540 pub class: Box<Expr>,
541 pub method: Box<Expr>,
542 pub args: Box<[Arg]>,
543}
544
545#[derive(Debug, Clone, Serialize)]
546pub struct ClosureExpr {
547 pub is_static: bool,
548 pub by_ref: bool,
549 pub params: Box<[Param]>,
550 pub use_vars: Box<[ClosureUseVar]>,
551 pub return_type: Option<TypeHint>,
552 pub body: Box<[Stmt]>,
553 pub attributes: Box<[Attribute]>,
554}
555
556#[derive(Debug, Clone, Serialize)]
557pub struct ClosureUseVar {
558 pub name: Box<str>,
559 pub by_ref: bool,
560 pub span: Span,
561}
562
563#[derive(Debug, Clone, Serialize)]
564pub struct ArrowFunctionExpr {
565 pub is_static: bool,
566 pub by_ref: bool,
567 pub params: Box<[Param]>,
568 pub return_type: Option<TypeHint>,
569 pub body: Box<Expr>,
570 pub attributes: Box<[Attribute]>,
571}
572
573#[derive(Debug, Clone, Serialize)]
574pub struct MatchExpr {
575 pub subject: Box<Expr>,
576 pub arms: Box<[MatchArm]>,
577}
578
579#[derive(Debug, Clone, Serialize)]
580pub struct MatchArm {
581 pub conditions: Option<Box<[Expr]>>,
582 pub body: Expr,
583 pub span: Span,
584}
585
586#[derive(Debug, Clone, Serialize)]
587pub struct YieldExpr {
588 pub key: Option<Box<Expr>>,
589 pub value: Option<Box<Expr>>,
590 pub is_from: bool,
591}
592
593#[derive(Debug, Clone, Serialize)]
594pub struct CallableCreateExpr {
595 pub kind: CallableCreateKind,
596}
597
598#[derive(Debug, Clone, Serialize)]
599pub enum CallableCreateKind {
600 Function(Box<Expr>),
601 Method {
602 object: Box<Expr>,
603 method: Box<Expr>,
604 },
605 NullsafeMethod {
606 object: Box<Expr>,
607 method: Box<Expr>,
608 },
609 StaticMethod {
610 class: Box<Expr>,
611 method: Box<Expr>,
612 },
613}
614
615#[derive(Debug, Clone, Serialize)]
616pub enum StringPart {
617 Literal(Box<str>),
618 Expr(Expr),
619}
620
621#[derive(Debug, Clone, Serialize)]
626pub struct FunctionDecl {
627 pub name: Ident,
628 pub params: Box<[Param]>,
629 pub body: Box<[Stmt]>,
630 pub return_type: Option<TypeHint>,
631 pub by_ref: bool,
632 pub attributes: Box<[Attribute]>,
633 #[serde(skip_serializing_if = "Option::is_none")]
634 pub doc_comment: Option<Comment>,
635}
636
637#[derive(Debug, Clone, Serialize)]
638pub struct Param {
639 pub name: Ident,
640 pub type_hint: Option<TypeHint>,
641 pub default: Option<Expr>,
642 pub by_ref: bool,
643 pub variadic: bool,
644 pub is_readonly: bool,
645 pub is_final: bool,
646 pub visibility: Option<Visibility>,
647 pub set_visibility: Option<Visibility>,
648 pub attributes: Box<[Attribute]>,
649 #[serde(skip_serializing_if = "slice_is_empty")]
650 pub hooks: Box<[PropertyHook]>,
651 pub span: Span,
652}
653
654#[derive(Debug, Clone, Serialize)]
655pub struct ClassDecl {
656 pub name: Option<Ident>,
657 pub modifiers: ClassModifiers,
658 pub extends: Option<Name>,
659 pub implements: Box<[Name]>,
660 pub members: Box<[ClassMember]>,
661 pub attributes: Box<[Attribute]>,
662 #[serde(skip_serializing_if = "Option::is_none")]
663 pub doc_comment: Option<Comment>,
664}
665
666#[derive(Debug, Clone, Serialize)]
667pub struct ClassMember {
668 pub kind: ClassMemberKind,
669 pub span: Span,
670}
671
672#[derive(Debug, Clone, Serialize)]
673pub enum ClassMemberKind {
674 Property(PropertyDecl),
675 Method(MethodDecl),
676 ClassConst(ClassConstDecl),
677 TraitUse(TraitUseDecl),
678}
679
680#[derive(Debug, Clone, Serialize)]
681pub struct PropertyDecl {
682 pub name: Ident,
683 pub visibility: Option<Visibility>,
684 pub set_visibility: Option<Visibility>,
685 pub is_static: bool,
686 pub is_readonly: bool,
687 pub type_hint: Option<TypeHint>,
688 pub default: Option<Expr>,
689 pub attributes: Box<[Attribute]>,
690 #[serde(skip_serializing_if = "slice_is_empty")]
691 pub hooks: Box<[PropertyHook]>,
692 #[serde(skip_serializing_if = "Option::is_none")]
693 pub doc_comment: Option<Comment>,
694}
695
696#[derive(Debug, Clone, Serialize)]
697pub struct PropertyHook {
698 pub kind: PropertyHookKind,
699 pub body: PropertyHookBody,
700 pub is_final: bool,
701 pub by_ref: bool,
702 pub params: Box<[Param]>,
703 pub attributes: Box<[Attribute]>,
704 pub span: Span,
705}
706
707#[derive(Debug, Clone, Serialize)]
708pub enum PropertyHookBody {
709 Block(Box<[Stmt]>),
710 Expression(Expr),
711 Abstract,
712}
713
714#[derive(Debug, Clone, Serialize)]
715pub struct MethodDecl {
716 pub name: Ident,
717 pub visibility: Option<Visibility>,
718 pub is_static: bool,
719 pub is_abstract: bool,
720 pub is_final: bool,
721 pub by_ref: bool,
722 pub params: Box<[Param]>,
723 pub return_type: Option<TypeHint>,
724 pub body: Option<Box<[Stmt]>>,
725 pub attributes: Box<[Attribute]>,
726 #[serde(skip_serializing_if = "Option::is_none")]
727 pub doc_comment: Option<Comment>,
728}
729
730#[derive(Debug, Clone, Serialize)]
731pub struct ClassConstDecl {
732 pub name: Ident,
733 pub visibility: Option<Visibility>,
734 pub is_final: bool,
735 #[serde(skip_serializing_if = "Option::is_none")]
736 pub type_hint: Option<Box<TypeHint>>,
737 pub value: Expr,
738 pub attributes: Box<[Attribute]>,
739 #[serde(skip_serializing_if = "Option::is_none")]
740 pub doc_comment: Option<Comment>,
741}
742
743#[derive(Debug, Clone, Serialize)]
744pub struct TraitUseDecl {
745 pub traits: Box<[Name]>,
746 pub adaptations: Box<[TraitAdaptation]>,
747}
748
749#[derive(Debug, Clone, Serialize)]
750pub struct TraitAdaptation {
751 pub kind: TraitAdaptationKind,
752 pub span: Span,
753}
754
755#[derive(Debug, Clone, Serialize)]
756pub enum TraitAdaptationKind {
757 Precedence {
758 trait_name: Name,
759 method: Name,
760 insteadof: Box<[Name]>,
761 },
762 Alias {
763 trait_name: Option<Name>,
764 method: Name,
765 new_modifier: Option<Visibility>,
766 new_name: Option<Name>,
767 },
768}
769
770#[derive(Debug, Clone, Serialize)]
771pub struct InterfaceDecl {
772 pub name: Ident,
773 pub extends: Box<[Name]>,
774 pub members: Box<[ClassMember]>,
775 pub attributes: Box<[Attribute]>,
776 #[serde(skip_serializing_if = "Option::is_none")]
777 pub doc_comment: Option<Comment>,
778}
779
780#[derive(Debug, Clone, Serialize)]
781pub struct TraitDecl {
782 pub name: Ident,
783 pub members: Box<[ClassMember]>,
784 pub attributes: Box<[Attribute]>,
785 #[serde(skip_serializing_if = "Option::is_none")]
786 pub doc_comment: Option<Comment>,
787}
788
789#[derive(Debug, Clone, Serialize)]
790pub struct EnumDecl {
791 pub name: Ident,
792 pub scalar_type: Option<Name>,
793 pub implements: Box<[Name]>,
794 pub members: Box<[EnumMember]>,
795 pub attributes: Box<[Attribute]>,
796 #[serde(skip_serializing_if = "Option::is_none")]
797 pub doc_comment: Option<Comment>,
798}
799
800#[derive(Debug, Clone, Serialize)]
801pub struct EnumMember {
802 pub kind: EnumMemberKind,
803 pub span: Span,
804}
805
806#[derive(Debug, Clone, Serialize)]
807pub enum EnumMemberKind {
808 Case(EnumCase),
809 Method(MethodDecl),
810 ClassConst(ClassConstDecl),
811 TraitUse(TraitUseDecl),
812}
813
814#[derive(Debug, Clone, Serialize)]
815pub struct EnumCase {
816 pub name: Ident,
817 pub value: Option<Expr>,
818 pub attributes: Box<[Attribute]>,
819 #[serde(skip_serializing_if = "Option::is_none")]
820 pub doc_comment: Option<Comment>,
821}
822
823fn owned_ident(ident: arena_ast::Ident<'_>) -> Ident {
828 ident.as_str().map(|s| s.into())
829}
830
831fn owned_name(name: &arena_ast::Name<'_, '_>) -> Name {
832 match name {
833 arena_ast::Name::Simple { value, span } => Name {
834 parts: vec![Box::from(*value)].into_boxed_slice(),
835 kind: NameKind::Unqualified,
836 span: *span,
837 },
838 arena_ast::Name::Complex { parts, kind, span } => Name {
839 parts: parts
840 .iter()
841 .map(|s| Box::from(*s))
842 .collect::<Vec<_>>()
843 .into_boxed_slice(),
844 kind: *kind,
845 span: *span,
846 },
847 arena_ast::Name::Error { span } => Name {
848 parts: Box::from([]),
849 kind: NameKind::Error,
850 span: *span,
851 },
852 }
853}
854
855fn owned_comment(c: &arena_ast::Comment<'_>) -> Comment {
856 Comment {
857 kind: c.kind,
858 text: c.text.into(),
859 span: c.span,
860 }
861}
862
863fn owned_opt_comment(c: &Option<arena_ast::Comment<'_>>) -> Option<Comment> {
864 c.as_ref().map(owned_comment)
865}
866
867fn owned_type_hint(th: &arena_ast::TypeHint<'_, '_>) -> TypeHint {
868 TypeHint {
869 kind: owned_type_hint_kind(&th.kind),
870 span: th.span,
871 }
872}
873
874fn owned_type_hint_kind(k: &arena_ast::TypeHintKind<'_, '_>) -> TypeHintKind {
875 match k {
876 arena_ast::TypeHintKind::Named(n) => TypeHintKind::Named(owned_name(n)),
877 arena_ast::TypeHintKind::Keyword(b, span) => TypeHintKind::Keyword(*b, *span),
878 arena_ast::TypeHintKind::Nullable(inner) => {
879 TypeHintKind::Nullable(Box::new(owned_type_hint(inner)))
880 }
881 arena_ast::TypeHintKind::Union(types) => TypeHintKind::Union(
882 types
883 .iter()
884 .map(owned_type_hint)
885 .collect::<Vec<_>>()
886 .into_boxed_slice(),
887 ),
888 arena_ast::TypeHintKind::Intersection(types) => TypeHintKind::Intersection(
889 types
890 .iter()
891 .map(owned_type_hint)
892 .collect::<Vec<_>>()
893 .into_boxed_slice(),
894 ),
895 }
896}
897
898fn owned_arg(arg: &arena_ast::Arg<'_, '_>) -> Arg {
899 Arg {
900 name: arg.name.as_ref().map(owned_name),
901 value: owned_expr(&arg.value),
902 unpack: arg.unpack,
903 by_ref: arg.by_ref,
904 span: arg.span,
905 }
906}
907
908fn owned_args(args: &[arena_ast::Arg<'_, '_>]) -> Box<[Arg]> {
909 args.iter()
910 .map(owned_arg)
911 .collect::<Vec<_>>()
912 .into_boxed_slice()
913}
914
915fn owned_attr(attr: &arena_ast::Attribute<'_, '_>) -> Attribute {
916 Attribute {
917 name: owned_name(&attr.name),
918 args: owned_args(&attr.args),
919 span: attr.span,
920 }
921}
922
923fn owned_attrs(attrs: &[arena_ast::Attribute<'_, '_>]) -> Box<[Attribute]> {
924 attrs
925 .iter()
926 .map(owned_attr)
927 .collect::<Vec<_>>()
928 .into_boxed_slice()
929}
930
931fn owned_string_parts(parts: &[arena_ast::StringPart<'_, '_>]) -> Box<[StringPart]> {
932 parts
933 .iter()
934 .map(|p| match p {
935 arena_ast::StringPart::Literal(s) => StringPart::Literal(Box::from(*s)),
936 arena_ast::StringPart::Expr(e) => StringPart::Expr(owned_expr(e)),
937 })
938 .collect::<Vec<_>>()
939 .into_boxed_slice()
940}
941
942pub fn to_owned_expr(expr: &arena_ast::Expr<'_, '_>) -> Expr {
944 owned_expr(expr)
945}
946
947fn owned_expr(expr: &arena_ast::Expr<'_, '_>) -> Expr {
948 Expr {
949 kind: owned_expr_kind(&expr.kind),
950 span: expr.span,
951 }
952}
953
954fn owned_exprs(exprs: &[arena_ast::Expr<'_, '_>]) -> Box<[Expr]> {
955 exprs
956 .iter()
957 .map(owned_expr)
958 .collect::<Vec<_>>()
959 .into_boxed_slice()
960}
961
962fn owned_expr_kind(k: &arena_ast::ExprKind<'_, '_>) -> ExprKind {
963 match k {
964 arena_ast::ExprKind::Int(v) => ExprKind::Int(*v),
965 arena_ast::ExprKind::Float(v) => ExprKind::Float(*v),
966 arena_ast::ExprKind::String(s) => ExprKind::String(Box::from(*s)),
967 arena_ast::ExprKind::InterpolatedString(parts) => {
968 ExprKind::InterpolatedString(owned_string_parts(parts))
969 }
970 arena_ast::ExprKind::Heredoc { label, parts } => ExprKind::Heredoc {
971 label: Box::from(*label),
972 parts: owned_string_parts(parts),
973 },
974 arena_ast::ExprKind::Nowdoc { label, value } => ExprKind::Nowdoc {
975 label: Box::from(*label),
976 value: Box::from(*value),
977 },
978 arena_ast::ExprKind::ShellExec(parts) => ExprKind::ShellExec(owned_string_parts(parts)),
979 arena_ast::ExprKind::Bool(v) => ExprKind::Bool(*v),
980 arena_ast::ExprKind::Null => ExprKind::Null,
981 arena_ast::ExprKind::Variable(s) => ExprKind::Variable(s.as_str().into()),
982 arena_ast::ExprKind::VariableVariable(inner) => {
983 ExprKind::VariableVariable(Box::new(owned_expr(inner)))
984 }
985 arena_ast::ExprKind::Identifier(s) => ExprKind::Identifier(s.as_str().into()),
986 arena_ast::ExprKind::Assign(a) => ExprKind::Assign(AssignExpr {
987 target: Box::new(owned_expr(a.target)),
988 op: a.op,
989 value: Box::new(owned_expr(a.value)),
990 by_ref: a.by_ref,
991 }),
992 arena_ast::ExprKind::Binary(b) => ExprKind::Binary(BinaryExpr {
993 left: Box::new(owned_expr(b.left)),
994 op: b.op,
995 right: Box::new(owned_expr(b.right)),
996 }),
997 arena_ast::ExprKind::UnaryPrefix(u) => ExprKind::UnaryPrefix(UnaryPrefixExpr {
998 op: u.op,
999 operand: Box::new(owned_expr(u.operand)),
1000 }),
1001 arena_ast::ExprKind::UnaryPostfix(u) => ExprKind::UnaryPostfix(UnaryPostfixExpr {
1002 operand: Box::new(owned_expr(u.operand)),
1003 op: u.op,
1004 }),
1005 arena_ast::ExprKind::Ternary(t) => ExprKind::Ternary(TernaryExpr {
1006 condition: Box::new(owned_expr(t.condition)),
1007 then_expr: t.then_expr.map(|e| Box::new(owned_expr(e))),
1008 else_expr: Box::new(owned_expr(t.else_expr)),
1009 }),
1010 arena_ast::ExprKind::NullCoalesce(n) => ExprKind::NullCoalesce(NullCoalesceExpr {
1011 left: Box::new(owned_expr(n.left)),
1012 right: Box::new(owned_expr(n.right)),
1013 }),
1014 arena_ast::ExprKind::FunctionCall(f) => ExprKind::FunctionCall(FunctionCallExpr {
1015 name: Box::new(owned_expr(f.name)),
1016 args: owned_args(&f.args),
1017 }),
1018 arena_ast::ExprKind::Array(elems) => ExprKind::Array(
1019 elems
1020 .iter()
1021 .map(|e| ArrayElement {
1022 key: e.key.as_ref().map(owned_expr),
1023 value: owned_expr(&e.value),
1024 unpack: e.unpack,
1025 by_ref: e.by_ref,
1026 span: e.span,
1027 })
1028 .collect::<Vec<_>>()
1029 .into_boxed_slice(),
1030 ),
1031 arena_ast::ExprKind::ArrayAccess(a) => ExprKind::ArrayAccess(ArrayAccessExpr {
1032 array: Box::new(owned_expr(a.array)),
1033 index: a.index.map(|e| Box::new(owned_expr(e))),
1034 }),
1035 arena_ast::ExprKind::Print(e) => ExprKind::Print(Box::new(owned_expr(e))),
1036 arena_ast::ExprKind::Parenthesized(e) => ExprKind::Parenthesized(Box::new(owned_expr(e))),
1037 arena_ast::ExprKind::Cast(kind, e) => ExprKind::Cast(*kind, Box::new(owned_expr(e))),
1038 arena_ast::ExprKind::ErrorSuppress(e) => ExprKind::ErrorSuppress(Box::new(owned_expr(e))),
1039 arena_ast::ExprKind::Isset(exprs) => ExprKind::Isset(owned_exprs(exprs)),
1040 arena_ast::ExprKind::Empty(e) => ExprKind::Empty(Box::new(owned_expr(e))),
1041 arena_ast::ExprKind::Include(kind, e) => ExprKind::Include(*kind, Box::new(owned_expr(e))),
1042 arena_ast::ExprKind::Eval(e) => ExprKind::Eval(Box::new(owned_expr(e))),
1043 arena_ast::ExprKind::Exit(e) => ExprKind::Exit(e.map(|e| Box::new(owned_expr(e)))),
1044 arena_ast::ExprKind::MagicConst(m) => ExprKind::MagicConst(*m),
1045 arena_ast::ExprKind::Clone(e) => ExprKind::Clone(Box::new(owned_expr(e))),
1046 arena_ast::ExprKind::CloneWith(obj, props) => {
1047 ExprKind::CloneWith(Box::new(owned_expr(obj)), Box::new(owned_expr(props)))
1048 }
1049 arena_ast::ExprKind::New(n) => ExprKind::New(NewExpr {
1050 class: Box::new(owned_expr(n.class)),
1051 args: owned_args(&n.args),
1052 }),
1053 arena_ast::ExprKind::PropertyAccess(p) => ExprKind::PropertyAccess(PropertyAccessExpr {
1054 object: Box::new(owned_expr(p.object)),
1055 property: Box::new(owned_expr(p.property)),
1056 }),
1057 arena_ast::ExprKind::NullsafePropertyAccess(p) => {
1058 ExprKind::NullsafePropertyAccess(PropertyAccessExpr {
1059 object: Box::new(owned_expr(p.object)),
1060 property: Box::new(owned_expr(p.property)),
1061 })
1062 }
1063 arena_ast::ExprKind::MethodCall(m) => ExprKind::MethodCall(Box::new(MethodCallExpr {
1064 object: Box::new(owned_expr(m.object)),
1065 method: Box::new(owned_expr(m.method)),
1066 args: owned_args(&m.args),
1067 })),
1068 arena_ast::ExprKind::NullsafeMethodCall(m) => {
1069 ExprKind::NullsafeMethodCall(Box::new(MethodCallExpr {
1070 object: Box::new(owned_expr(m.object)),
1071 method: Box::new(owned_expr(m.method)),
1072 args: owned_args(&m.args),
1073 }))
1074 }
1075 arena_ast::ExprKind::StaticPropertyAccess(s) => {
1076 ExprKind::StaticPropertyAccess(StaticAccessExpr {
1077 class: Box::new(owned_expr(s.class)),
1078 member: Box::new(owned_expr(s.member)),
1079 })
1080 }
1081 arena_ast::ExprKind::StaticMethodCall(s) => {
1082 ExprKind::StaticMethodCall(Box::new(StaticMethodCallExpr {
1083 class: Box::new(owned_expr(s.class)),
1084 method: Box::new(owned_expr(s.method)),
1085 args: owned_args(&s.args),
1086 }))
1087 }
1088 arena_ast::ExprKind::StaticDynMethodCall(s) => {
1089 ExprKind::StaticDynMethodCall(Box::new(StaticDynMethodCallExpr {
1090 class: Box::new(owned_expr(s.class)),
1091 method: Box::new(owned_expr(s.method)),
1092 args: owned_args(&s.args),
1093 }))
1094 }
1095 arena_ast::ExprKind::ClassConstAccess(s) => ExprKind::ClassConstAccess(StaticAccessExpr {
1096 class: Box::new(owned_expr(s.class)),
1097 member: Box::new(owned_expr(s.member)),
1098 }),
1099 arena_ast::ExprKind::ClassConstAccessDynamic { class, member } => {
1100 ExprKind::ClassConstAccessDynamic {
1101 class: Box::new(owned_expr(class)),
1102 member: Box::new(owned_expr(member)),
1103 }
1104 }
1105 arena_ast::ExprKind::StaticPropertyAccessDynamic { class, member } => {
1106 ExprKind::StaticPropertyAccessDynamic {
1107 class: Box::new(owned_expr(class)),
1108 member: Box::new(owned_expr(member)),
1109 }
1110 }
1111 arena_ast::ExprKind::Closure(c) => ExprKind::Closure(Box::new(ClosureExpr {
1112 is_static: c.is_static,
1113 by_ref: c.by_ref,
1114 params: owned_params(&c.params),
1115 use_vars: c
1116 .use_vars
1117 .iter()
1118 .map(|v| ClosureUseVar {
1119 name: v.name.into(),
1120 by_ref: v.by_ref,
1121 span: v.span,
1122 })
1123 .collect::<Vec<_>>()
1124 .into_boxed_slice(),
1125 return_type: c.return_type.as_ref().map(owned_type_hint),
1126 body: owned_stmts(&c.body),
1127 attributes: owned_attrs(&c.attributes),
1128 })),
1129 arena_ast::ExprKind::ArrowFunction(f) => {
1130 ExprKind::ArrowFunction(Box::new(ArrowFunctionExpr {
1131 is_static: f.is_static,
1132 by_ref: f.by_ref,
1133 params: owned_params(&f.params),
1134 return_type: f.return_type.as_ref().map(owned_type_hint),
1135 body: Box::new(owned_expr(f.body)),
1136 attributes: owned_attrs(&f.attributes),
1137 }))
1138 }
1139 arena_ast::ExprKind::Match(m) => ExprKind::Match(MatchExpr {
1140 subject: Box::new(owned_expr(m.subject)),
1141 arms: m
1142 .arms
1143 .iter()
1144 .map(|arm| MatchArm {
1145 conditions: arm.conditions.as_ref().map(|conds| owned_exprs(conds)),
1146 body: owned_expr(&arm.body),
1147 span: arm.span,
1148 })
1149 .collect::<Vec<_>>()
1150 .into_boxed_slice(),
1151 }),
1152 arena_ast::ExprKind::ThrowExpr(e) => ExprKind::ThrowExpr(Box::new(owned_expr(e))),
1153 arena_ast::ExprKind::Yield(y) => ExprKind::Yield(YieldExpr {
1154 key: y.key.map(|e| Box::new(owned_expr(e))),
1155 value: y.value.map(|e| Box::new(owned_expr(e))),
1156 is_from: y.is_from,
1157 }),
1158 arena_ast::ExprKind::AnonymousClass(cls) => {
1159 ExprKind::AnonymousClass(Box::new(owned_class_decl(cls)))
1160 }
1161 arena_ast::ExprKind::CallableCreate(c) => ExprKind::CallableCreate(CallableCreateExpr {
1162 kind: match &c.kind {
1163 arena_ast::CallableCreateKind::Function(e) => {
1164 CallableCreateKind::Function(Box::new(owned_expr(e)))
1165 }
1166 arena_ast::CallableCreateKind::Method { object, method } => {
1167 CallableCreateKind::Method {
1168 object: Box::new(owned_expr(object)),
1169 method: Box::new(owned_expr(method)),
1170 }
1171 }
1172 arena_ast::CallableCreateKind::NullsafeMethod { object, method } => {
1173 CallableCreateKind::NullsafeMethod {
1174 object: Box::new(owned_expr(object)),
1175 method: Box::new(owned_expr(method)),
1176 }
1177 }
1178 arena_ast::CallableCreateKind::StaticMethod { class, method } => {
1179 CallableCreateKind::StaticMethod {
1180 class: Box::new(owned_expr(class)),
1181 method: Box::new(owned_expr(method)),
1182 }
1183 }
1184 },
1185 }),
1186 arena_ast::ExprKind::Omit => ExprKind::Omit,
1187 arena_ast::ExprKind::Error => ExprKind::Error,
1188 }
1189}
1190
1191fn owned_param(p: &arena_ast::Param<'_, '_>) -> Param {
1192 Param {
1193 name: owned_ident(p.name),
1194 type_hint: p.type_hint.as_ref().map(owned_type_hint),
1195 default: p.default.as_ref().map(owned_expr),
1196 by_ref: p.by_ref,
1197 variadic: p.variadic,
1198 is_readonly: p.is_readonly,
1199 is_final: p.is_final,
1200 visibility: p.visibility,
1201 set_visibility: p.set_visibility,
1202 attributes: owned_attrs(&p.attributes),
1203 hooks: owned_hooks(&p.hooks),
1204 span: p.span,
1205 }
1206}
1207
1208fn owned_params(params: &[arena_ast::Param<'_, '_>]) -> Box<[Param]> {
1209 params
1210 .iter()
1211 .map(owned_param)
1212 .collect::<Vec<_>>()
1213 .into_boxed_slice()
1214}
1215
1216fn owned_hook(h: &arena_ast::PropertyHook<'_, '_>) -> PropertyHook {
1217 PropertyHook {
1218 kind: h.kind,
1219 body: match &h.body {
1220 arena_ast::PropertyHookBody::Block(stmts) => {
1221 PropertyHookBody::Block(owned_stmts(stmts))
1222 }
1223 arena_ast::PropertyHookBody::Expression(e) => {
1224 PropertyHookBody::Expression(owned_expr(e))
1225 }
1226 arena_ast::PropertyHookBody::Abstract => PropertyHookBody::Abstract,
1227 },
1228 is_final: h.is_final,
1229 by_ref: h.by_ref,
1230 params: owned_params(&h.params),
1231 attributes: owned_attrs(&h.attributes),
1232 span: h.span,
1233 }
1234}
1235
1236fn owned_hooks(hooks: &[arena_ast::PropertyHook<'_, '_>]) -> Box<[PropertyHook]> {
1237 hooks
1238 .iter()
1239 .map(owned_hook)
1240 .collect::<Vec<_>>()
1241 .into_boxed_slice()
1242}
1243
1244fn owned_stmts(stmts: &[arena_ast::Stmt<'_, '_>]) -> Box<[Stmt]> {
1245 stmts
1246 .iter()
1247 .map(owned_stmt)
1248 .collect::<Vec<_>>()
1249 .into_boxed_slice()
1250}
1251
1252pub fn to_owned_stmt(stmt: &arena_ast::Stmt<'_, '_>) -> Stmt {
1254 owned_stmt(stmt)
1255}
1256
1257fn owned_stmt(stmt: &arena_ast::Stmt<'_, '_>) -> Stmt {
1258 Stmt {
1259 kind: owned_stmt_kind(&stmt.kind),
1260 span: stmt.span,
1261 }
1262}
1263
1264fn owned_stmt_kind(k: &arena_ast::StmtKind<'_, '_>) -> StmtKind {
1265 match k {
1266 arena_ast::StmtKind::Expression(e) => StmtKind::Expression(Box::new(owned_expr(e))),
1267 arena_ast::StmtKind::Echo(exprs) => StmtKind::Echo(owned_exprs(exprs)),
1268 arena_ast::StmtKind::Return(e) => StmtKind::Return(e.map(|e| Box::new(owned_expr(e)))),
1269 arena_ast::StmtKind::Block(stmts) => StmtKind::Block(owned_stmts(stmts)),
1270 arena_ast::StmtKind::If(s) => StmtKind::If(Box::new(IfStmt {
1271 condition: owned_expr(&s.condition),
1272 then_branch: Box::new(owned_stmt(s.then_branch)),
1273 elseif_branches: s
1274 .elseif_branches
1275 .iter()
1276 .map(|b| ElseIfBranch {
1277 condition: owned_expr(&b.condition),
1278 body: owned_stmt(&b.body),
1279 span: b.span,
1280 })
1281 .collect::<Vec<_>>()
1282 .into_boxed_slice(),
1283 else_branch: s.else_branch.map(|b| Box::new(owned_stmt(b))),
1284 uses_alternative: s.uses_alternative,
1285 })),
1286 arena_ast::StmtKind::While(s) => StmtKind::While(Box::new(WhileStmt {
1287 condition: owned_expr(&s.condition),
1288 body: Box::new(owned_stmt(s.body)),
1289 uses_alternative: s.uses_alternative,
1290 })),
1291 arena_ast::StmtKind::For(s) => StmtKind::For(Box::new(ForStmt {
1292 init: owned_exprs(&s.init),
1293 condition: owned_exprs(&s.condition),
1294 update: owned_exprs(&s.update),
1295 body: Box::new(owned_stmt(s.body)),
1296 uses_alternative: s.uses_alternative,
1297 })),
1298 arena_ast::StmtKind::Foreach(s) => StmtKind::Foreach(Box::new(ForeachStmt {
1299 expr: owned_expr(&s.expr),
1300 key: s.key.as_ref().map(owned_expr),
1301 value: owned_expr(&s.value),
1302 body: Box::new(owned_stmt(s.body)),
1303 uses_alternative: s.uses_alternative,
1304 })),
1305 arena_ast::StmtKind::DoWhile(s) => StmtKind::DoWhile(Box::new(DoWhileStmt {
1306 body: Box::new(owned_stmt(s.body)),
1307 condition: owned_expr(&s.condition),
1308 })),
1309 arena_ast::StmtKind::Function(f) => StmtKind::Function(Box::new(owned_function_decl(f))),
1310 arena_ast::StmtKind::Break(e) => StmtKind::Break(e.map(|e| Box::new(owned_expr(e)))),
1311 arena_ast::StmtKind::Continue(e) => StmtKind::Continue(e.map(|e| Box::new(owned_expr(e)))),
1312 arena_ast::StmtKind::Switch(s) => StmtKind::Switch(Box::new(SwitchStmt {
1313 expr: owned_expr(&s.expr),
1314 cases: s
1315 .cases
1316 .iter()
1317 .map(|c| SwitchCase {
1318 value: c.value.as_ref().map(owned_expr),
1319 body: owned_stmts(&c.body),
1320 span: c.span,
1321 })
1322 .collect::<Vec<_>>()
1323 .into_boxed_slice(),
1324 uses_alternative: s.uses_alternative,
1325 })),
1326 arena_ast::StmtKind::Goto(ident) => StmtKind::Goto(owned_ident(*ident)),
1327 arena_ast::StmtKind::Label(s) => StmtKind::Label(Box::from(*s)),
1328 arena_ast::StmtKind::Declare(d) => StmtKind::Declare(Box::new(DeclareStmt {
1329 directives: d
1330 .directives
1331 .iter()
1332 .map(|(k, v)| (Box::from(*k), owned_expr(v)))
1333 .collect::<Vec<_>>()
1334 .into_boxed_slice(),
1335 body: d.body.map(|b| Box::new(owned_stmt(b))),
1336 uses_alternative: d.uses_alternative,
1337 })),
1338 arena_ast::StmtKind::Unset(exprs) => StmtKind::Unset(owned_exprs(exprs)),
1339 arena_ast::StmtKind::Throw(e) => StmtKind::Throw(Box::new(owned_expr(e))),
1340 arena_ast::StmtKind::TryCatch(t) => StmtKind::TryCatch(Box::new(TryCatchStmt {
1341 body: owned_stmts(&t.body),
1342 catches: t
1343 .catches
1344 .iter()
1345 .map(|c| CatchClause {
1346 types: c
1347 .types
1348 .iter()
1349 .map(owned_name)
1350 .collect::<Vec<_>>()
1351 .into_boxed_slice(),
1352 var: c.var.map(Box::from),
1353 body: owned_stmts(&c.body),
1354 span: c.span,
1355 })
1356 .collect::<Vec<_>>()
1357 .into_boxed_slice(),
1358 finally: t.finally.as_ref().map(|stmts| owned_stmts(stmts)),
1359 })),
1360 arena_ast::StmtKind::Global(exprs) => StmtKind::Global(owned_exprs(exprs)),
1361 arena_ast::StmtKind::Class(cls) => StmtKind::Class(Box::new(owned_class_decl(cls))),
1362 arena_ast::StmtKind::Interface(iface) => {
1363 StmtKind::Interface(Box::new(owned_interface_decl(iface)))
1364 }
1365 arena_ast::StmtKind::Trait(tr) => StmtKind::Trait(Box::new(owned_trait_decl(tr))),
1366 arena_ast::StmtKind::Enum(en) => StmtKind::Enum(Box::new(owned_enum_decl(en))),
1367 arena_ast::StmtKind::Namespace(ns) => StmtKind::Namespace(Box::new(NamespaceDecl {
1368 name: ns.name.as_ref().map(owned_name),
1369 body: match &ns.body {
1370 arena_ast::NamespaceBody::Braced(stmts) => {
1371 NamespaceBody::Braced(owned_stmts(stmts))
1372 }
1373 arena_ast::NamespaceBody::Simple => NamespaceBody::Simple,
1374 },
1375 })),
1376 arena_ast::StmtKind::Use(u) => StmtKind::Use(Box::new(UseDecl {
1377 kind: u.kind,
1378 uses: u
1379 .uses
1380 .iter()
1381 .map(|item| UseItem {
1382 name: owned_name(&item.name),
1383 alias: item.alias.map(Box::from),
1384 kind: item.kind,
1385 span: item.span,
1386 })
1387 .collect::<Vec<_>>()
1388 .into_boxed_slice(),
1389 })),
1390 arena_ast::StmtKind::Const(items) => StmtKind::Const(
1391 items
1392 .iter()
1393 .map(|item| ConstItem {
1394 name: owned_ident(item.name),
1395 value: owned_expr(&item.value),
1396 attributes: owned_attrs(&item.attributes),
1397 span: item.span,
1398 doc_comment: owned_opt_comment(&item.doc_comment),
1399 })
1400 .collect::<Vec<_>>()
1401 .into_boxed_slice(),
1402 ),
1403 arena_ast::StmtKind::StaticVar(vars) => StmtKind::StaticVar(
1404 vars.iter()
1405 .map(|v| StaticVar {
1406 name: owned_ident(v.name),
1407 default: v.default.as_ref().map(owned_expr),
1408 span: v.span,
1409 })
1410 .collect::<Vec<_>>()
1411 .into_boxed_slice(),
1412 ),
1413 arena_ast::StmtKind::HaltCompiler(s) => StmtKind::HaltCompiler(Box::from(*s)),
1414 arena_ast::StmtKind::Nop => StmtKind::Nop,
1415 arena_ast::StmtKind::InlineHtml(s) => StmtKind::InlineHtml(Box::from(*s)),
1416 arena_ast::StmtKind::Error => StmtKind::Error,
1417 }
1418}
1419
1420fn owned_function_decl(f: &arena_ast::FunctionDecl<'_, '_>) -> FunctionDecl {
1421 FunctionDecl {
1422 name: owned_ident(f.name),
1423 params: owned_params(&f.params),
1424 body: owned_stmts(&f.body),
1425 return_type: f.return_type.as_ref().map(owned_type_hint),
1426 by_ref: f.by_ref,
1427 attributes: owned_attrs(&f.attributes),
1428 doc_comment: owned_opt_comment(&f.doc_comment),
1429 }
1430}
1431
1432fn owned_class_member(m: &arena_ast::ClassMember<'_, '_>) -> ClassMember {
1433 ClassMember {
1434 kind: match &m.kind {
1435 arena_ast::ClassMemberKind::Property(p) => ClassMemberKind::Property(PropertyDecl {
1436 name: owned_ident(p.name),
1437 visibility: p.visibility,
1438 set_visibility: p.set_visibility,
1439 is_static: p.is_static,
1440 is_readonly: p.is_readonly,
1441 type_hint: p.type_hint.as_ref().map(owned_type_hint),
1442 default: p.default.as_ref().map(owned_expr),
1443 attributes: owned_attrs(&p.attributes),
1444 hooks: owned_hooks(&p.hooks),
1445 doc_comment: owned_opt_comment(&p.doc_comment),
1446 }),
1447 arena_ast::ClassMemberKind::Method(m) => ClassMemberKind::Method(MethodDecl {
1448 name: owned_ident(m.name),
1449 visibility: m.visibility,
1450 is_static: m.is_static,
1451 is_abstract: m.is_abstract,
1452 is_final: m.is_final,
1453 by_ref: m.by_ref,
1454 params: owned_params(&m.params),
1455 return_type: m.return_type.as_ref().map(owned_type_hint),
1456 body: m.body.as_ref().map(|stmts| owned_stmts(stmts)),
1457 attributes: owned_attrs(&m.attributes),
1458 doc_comment: owned_opt_comment(&m.doc_comment),
1459 }),
1460 arena_ast::ClassMemberKind::ClassConst(c) => {
1461 ClassMemberKind::ClassConst(owned_class_const(c))
1462 }
1463 arena_ast::ClassMemberKind::TraitUse(t) => {
1464 ClassMemberKind::TraitUse(owned_trait_use(t))
1465 }
1466 },
1467 span: m.span,
1468 }
1469}
1470
1471fn owned_class_members(members: &[arena_ast::ClassMember<'_, '_>]) -> Box<[ClassMember]> {
1472 members
1473 .iter()
1474 .map(owned_class_member)
1475 .collect::<Vec<_>>()
1476 .into_boxed_slice()
1477}
1478
1479fn owned_class_const(c: &arena_ast::ClassConstDecl<'_, '_>) -> ClassConstDecl {
1480 ClassConstDecl {
1481 name: owned_ident(c.name),
1482 visibility: c.visibility,
1483 is_final: c.is_final,
1484 type_hint: c.type_hint.map(|th| Box::new(owned_type_hint(th))),
1485 value: owned_expr(&c.value),
1486 attributes: owned_attrs(&c.attributes),
1487 doc_comment: owned_opt_comment(&c.doc_comment),
1488 }
1489}
1490
1491fn owned_trait_use(t: &arena_ast::TraitUseDecl<'_, '_>) -> TraitUseDecl {
1492 TraitUseDecl {
1493 traits: t
1494 .traits
1495 .iter()
1496 .map(owned_name)
1497 .collect::<Vec<_>>()
1498 .into_boxed_slice(),
1499 adaptations: t
1500 .adaptations
1501 .iter()
1502 .map(|a| TraitAdaptation {
1503 kind: match &a.kind {
1504 arena_ast::TraitAdaptationKind::Precedence {
1505 trait_name,
1506 method,
1507 insteadof,
1508 } => TraitAdaptationKind::Precedence {
1509 trait_name: owned_name(trait_name),
1510 method: owned_name(method),
1511 insteadof: insteadof
1512 .iter()
1513 .map(owned_name)
1514 .collect::<Vec<_>>()
1515 .into_boxed_slice(),
1516 },
1517 arena_ast::TraitAdaptationKind::Alias {
1518 trait_name,
1519 method,
1520 new_modifier,
1521 new_name,
1522 } => TraitAdaptationKind::Alias {
1523 trait_name: trait_name.as_ref().map(owned_name),
1524 method: owned_name(method),
1525 new_modifier: *new_modifier,
1526 new_name: new_name.as_ref().map(owned_name),
1527 },
1528 },
1529 span: a.span,
1530 })
1531 .collect::<Vec<_>>()
1532 .into_boxed_slice(),
1533 }
1534}
1535
1536fn owned_class_decl(cls: &arena_ast::ClassDecl<'_, '_>) -> ClassDecl {
1537 ClassDecl {
1538 name: cls
1539 .name
1540 .map(|ident| Some(owned_ident(ident)))
1541 .unwrap_or(None),
1542 modifiers: cls.modifiers.clone(),
1543 extends: cls.extends.as_ref().map(owned_name),
1544 implements: cls
1545 .implements
1546 .iter()
1547 .map(owned_name)
1548 .collect::<Vec<_>>()
1549 .into_boxed_slice(),
1550 members: owned_class_members(&cls.members),
1551 attributes: owned_attrs(&cls.attributes),
1552 doc_comment: owned_opt_comment(&cls.doc_comment),
1553 }
1554}
1555
1556fn owned_interface_decl(iface: &arena_ast::InterfaceDecl<'_, '_>) -> InterfaceDecl {
1557 InterfaceDecl {
1558 name: owned_ident(iface.name),
1559 extends: iface
1560 .extends
1561 .iter()
1562 .map(owned_name)
1563 .collect::<Vec<_>>()
1564 .into_boxed_slice(),
1565 members: owned_class_members(&iface.members),
1566 attributes: owned_attrs(&iface.attributes),
1567 doc_comment: owned_opt_comment(&iface.doc_comment),
1568 }
1569}
1570
1571fn owned_trait_decl(tr: &arena_ast::TraitDecl<'_, '_>) -> TraitDecl {
1572 TraitDecl {
1573 name: owned_ident(tr.name),
1574 members: owned_class_members(&tr.members),
1575 attributes: owned_attrs(&tr.attributes),
1576 doc_comment: owned_opt_comment(&tr.doc_comment),
1577 }
1578}
1579
1580fn owned_enum_decl(en: &arena_ast::EnumDecl<'_, '_>) -> EnumDecl {
1581 EnumDecl {
1582 name: owned_ident(en.name),
1583 scalar_type: en.scalar_type.as_ref().map(owned_name),
1584 implements: en
1585 .implements
1586 .iter()
1587 .map(owned_name)
1588 .collect::<Vec<_>>()
1589 .into_boxed_slice(),
1590 members: en
1591 .members
1592 .iter()
1593 .map(|m| EnumMember {
1594 kind: match &m.kind {
1595 arena_ast::EnumMemberKind::Case(c) => EnumMemberKind::Case(EnumCase {
1596 name: owned_ident(c.name),
1597 value: c.value.as_ref().map(owned_expr),
1598 attributes: owned_attrs(&c.attributes),
1599 doc_comment: owned_opt_comment(&c.doc_comment),
1600 }),
1601 arena_ast::EnumMemberKind::Method(m) => EnumMemberKind::Method(MethodDecl {
1602 name: owned_ident(m.name),
1603 visibility: m.visibility,
1604 is_static: m.is_static,
1605 is_abstract: m.is_abstract,
1606 is_final: m.is_final,
1607 by_ref: m.by_ref,
1608 params: owned_params(&m.params),
1609 return_type: m.return_type.as_ref().map(owned_type_hint),
1610 body: m.body.as_ref().map(|stmts| owned_stmts(stmts)),
1611 attributes: owned_attrs(&m.attributes),
1612 doc_comment: owned_opt_comment(&m.doc_comment),
1613 }),
1614 arena_ast::EnumMemberKind::ClassConst(c) => {
1615 EnumMemberKind::ClassConst(owned_class_const(c))
1616 }
1617 arena_ast::EnumMemberKind::TraitUse(t) => {
1618 EnumMemberKind::TraitUse(owned_trait_use(t))
1619 }
1620 },
1621 span: m.span,
1622 })
1623 .collect::<Vec<_>>()
1624 .into_boxed_slice(),
1625 attributes: owned_attrs(&en.attributes),
1626 doc_comment: owned_opt_comment(&en.doc_comment),
1627 }
1628}
1629
1630pub fn to_owned_program(program: &arena_ast::Program<'_, '_>) -> Program {
1632 Program {
1633 stmts: owned_stmts(&program.stmts),
1634 span: program.span,
1635 }
1636}
1637
1638pub fn from_owned_program<'arena>(
1652 arena: &'arena bumpalo::Bump,
1653 program: &Program,
1654) -> arena_ast::Program<'arena, 'arena> {
1655 arena_ast::Program {
1656 stmts: av_stmts(arena, &program.stmts),
1657 span: program.span,
1658 }
1659}
1660
1661#[inline]
1663fn av_str<'a>(arena: &'a bumpalo::Bump, s: &str) -> &'a str {
1664 arena.alloc_str(s)
1665}
1666
1667fn av_ident<'a>(arena: &'a bumpalo::Bump, ident: &Ident) -> arena_ast::Ident<'a> {
1668 match ident {
1669 Some(s) => arena_ast::Ident::name(arena.alloc_str(s)),
1670 None => arena_ast::Ident::ERROR,
1671 }
1672}
1673
1674fn av_name<'a>(arena: &'a bumpalo::Bump, name: &Name) -> arena_ast::Name<'a, 'a> {
1675 if name.kind == NameKind::Error {
1676 return arena_ast::Name::Error { span: name.span };
1677 }
1678 if name.parts.len() == 1 && name.kind == NameKind::Unqualified {
1679 return arena_ast::Name::Simple {
1680 value: arena.alloc_str(&name.parts[0]),
1681 span: name.span,
1682 };
1683 }
1684 let mut parts = arena_ast::ArenaVec::with_capacity_in(name.parts.len(), arena);
1685 for p in name.parts.iter() {
1686 parts.push(arena.alloc_str(p) as &str);
1687 }
1688 arena_ast::Name::Complex {
1689 parts,
1690 kind: name.kind,
1691 span: name.span,
1692 }
1693}
1694
1695fn av_type_hint<'a>(arena: &'a bumpalo::Bump, th: &TypeHint) -> arena_ast::TypeHint<'a, 'a> {
1696 arena_ast::TypeHint {
1697 kind: av_type_hint_kind(arena, &th.kind),
1698 span: th.span,
1699 }
1700}
1701
1702fn av_type_hint_kind<'a>(
1703 arena: &'a bumpalo::Bump,
1704 k: &TypeHintKind,
1705) -> arena_ast::TypeHintKind<'a, 'a> {
1706 match k {
1707 TypeHintKind::Named(n) => arena_ast::TypeHintKind::Named(av_name(arena, n)),
1708 TypeHintKind::Keyword(b, span) => arena_ast::TypeHintKind::Keyword(*b, *span),
1709 TypeHintKind::Nullable(inner) => {
1710 arena_ast::TypeHintKind::Nullable(arena.alloc(av_type_hint(arena, inner)))
1711 }
1712 TypeHintKind::Union(types) => {
1713 let mut v = arena_ast::ArenaVec::with_capacity_in(types.len(), arena);
1714 for t in types.iter() {
1715 v.push(av_type_hint(arena, t));
1716 }
1717 arena_ast::TypeHintKind::Union(v)
1718 }
1719 TypeHintKind::Intersection(types) => {
1720 let mut v = arena_ast::ArenaVec::with_capacity_in(types.len(), arena);
1721 for t in types.iter() {
1722 v.push(av_type_hint(arena, t));
1723 }
1724 arena_ast::TypeHintKind::Intersection(v)
1725 }
1726 }
1727}
1728
1729fn av_arg<'a>(arena: &'a bumpalo::Bump, arg: &Arg) -> arena_ast::Arg<'a, 'a> {
1730 arena_ast::Arg {
1731 name: arg.name.as_ref().map(|n| av_name(arena, n)),
1732 value: av_expr(arena, &arg.value),
1733 unpack: arg.unpack,
1734 by_ref: arg.by_ref,
1735 span: arg.span,
1736 }
1737}
1738
1739fn av_args<'a>(
1740 arena: &'a bumpalo::Bump,
1741 args: &[Arg],
1742) -> arena_ast::ArenaVec<'a, arena_ast::Arg<'a, 'a>> {
1743 let mut v = arena_ast::ArenaVec::with_capacity_in(args.len(), arena);
1744 for a in args.iter() {
1745 v.push(av_arg(arena, a));
1746 }
1747 v
1748}
1749
1750fn av_attr<'a>(arena: &'a bumpalo::Bump, attr: &Attribute) -> arena_ast::Attribute<'a, 'a> {
1751 arena_ast::Attribute {
1752 name: av_name(arena, &attr.name),
1753 args: av_args(arena, &attr.args),
1754 span: attr.span,
1755 }
1756}
1757
1758fn av_attrs<'a>(
1759 arena: &'a bumpalo::Bump,
1760 attrs: &[Attribute],
1761) -> arena_ast::ArenaVec<'a, arena_ast::Attribute<'a, 'a>> {
1762 let mut v = arena_ast::ArenaVec::with_capacity_in(attrs.len(), arena);
1763 for a in attrs.iter() {
1764 v.push(av_attr(arena, a));
1765 }
1766 v
1767}
1768
1769fn av_comment<'a>(arena: &'a bumpalo::Bump, c: &Comment) -> arena_ast::Comment<'a> {
1770 arena_ast::Comment {
1771 kind: c.kind,
1772 text: arena.alloc_str(&c.text),
1773 span: c.span,
1774 }
1775}
1776
1777fn av_opt_comment<'a>(
1778 arena: &'a bumpalo::Bump,
1779 c: &Option<Comment>,
1780) -> Option<arena_ast::Comment<'a>> {
1781 c.as_ref().map(|c| av_comment(arena, c))
1782}
1783
1784fn av_string_parts<'a>(
1785 arena: &'a bumpalo::Bump,
1786 parts: &[StringPart],
1787) -> arena_ast::ArenaVec<'a, arena_ast::StringPart<'a, 'a>> {
1788 let mut v = arena_ast::ArenaVec::with_capacity_in(parts.len(), arena);
1789 for p in parts.iter() {
1790 v.push(match p {
1791 StringPart::Literal(s) => arena_ast::StringPart::Literal(arena.alloc_str(s)),
1792 StringPart::Expr(e) => arena_ast::StringPart::Expr(av_expr(arena, e)),
1793 });
1794 }
1795 v
1796}
1797
1798fn av_expr<'a>(arena: &'a bumpalo::Bump, expr: &Expr) -> arena_ast::Expr<'a, 'a> {
1799 arena_ast::Expr {
1800 kind: av_expr_kind(arena, &expr.kind),
1801 span: expr.span,
1802 }
1803}
1804
1805fn av_exprs<'a>(
1806 arena: &'a bumpalo::Bump,
1807 exprs: &[Expr],
1808) -> arena_ast::ArenaVec<'a, arena_ast::Expr<'a, 'a>> {
1809 let mut v = arena_ast::ArenaVec::with_capacity_in(exprs.len(), arena);
1810 for e in exprs.iter() {
1811 v.push(av_expr(arena, e));
1812 }
1813 v
1814}
1815
1816fn av_namestr<'a>(arena: &'a bumpalo::Bump, s: &str) -> arena_ast::NameStr<'a, 'a> {
1817 arena_ast::NameStr::__arena(arena.alloc_str(s))
1818}
1819
1820fn av_expr_kind<'a>(arena: &'a bumpalo::Bump, k: &ExprKind) -> arena_ast::ExprKind<'a, 'a> {
1821 match k {
1822 ExprKind::Int(v) => arena_ast::ExprKind::Int(*v),
1823 ExprKind::Float(v) => arena_ast::ExprKind::Float(*v),
1824 ExprKind::String(s) => arena_ast::ExprKind::String(arena.alloc_str(s)),
1825 ExprKind::InterpolatedString(parts) => {
1826 arena_ast::ExprKind::InterpolatedString(av_string_parts(arena, parts))
1827 }
1828 ExprKind::Heredoc { label, parts } => arena_ast::ExprKind::Heredoc {
1829 label: arena.alloc_str(label),
1830 parts: av_string_parts(arena, parts),
1831 },
1832 ExprKind::Nowdoc { label, value } => arena_ast::ExprKind::Nowdoc {
1833 label: arena.alloc_str(label),
1834 value: arena.alloc_str(value),
1835 },
1836 ExprKind::ShellExec(parts) => arena_ast::ExprKind::ShellExec(av_string_parts(arena, parts)),
1837 ExprKind::Bool(v) => arena_ast::ExprKind::Bool(*v),
1838 ExprKind::Null => arena_ast::ExprKind::Null,
1839 ExprKind::Variable(s) => arena_ast::ExprKind::Variable(av_namestr(arena, s)),
1840 ExprKind::VariableVariable(inner) => {
1841 arena_ast::ExprKind::VariableVariable(arena.alloc(av_expr(arena, inner)))
1842 }
1843 ExprKind::Identifier(s) => arena_ast::ExprKind::Identifier(av_namestr(arena, s)),
1844 ExprKind::Assign(a) => arena_ast::ExprKind::Assign(arena_ast::AssignExpr {
1845 target: arena.alloc(av_expr(arena, &a.target)),
1846 op: a.op,
1847 value: arena.alloc(av_expr(arena, &a.value)),
1848 by_ref: a.by_ref,
1849 }),
1850 ExprKind::Binary(b) => arena_ast::ExprKind::Binary(arena_ast::BinaryExpr {
1851 left: arena.alloc(av_expr(arena, &b.left)),
1852 op: b.op,
1853 right: arena.alloc(av_expr(arena, &b.right)),
1854 }),
1855 ExprKind::UnaryPrefix(u) => arena_ast::ExprKind::UnaryPrefix(arena_ast::UnaryPrefixExpr {
1856 op: u.op,
1857 operand: arena.alloc(av_expr(arena, &u.operand)),
1858 }),
1859 ExprKind::UnaryPostfix(u) => {
1860 arena_ast::ExprKind::UnaryPostfix(arena_ast::UnaryPostfixExpr {
1861 operand: arena.alloc(av_expr(arena, &u.operand)),
1862 op: u.op,
1863 })
1864 }
1865 ExprKind::Ternary(t) => arena_ast::ExprKind::Ternary(arena_ast::TernaryExpr {
1866 condition: arena.alloc(av_expr(arena, &t.condition)),
1867 then_expr: t
1868 .then_expr
1869 .as_ref()
1870 .map(|e| &*arena.alloc(av_expr(arena, e))),
1871 else_expr: arena.alloc(av_expr(arena, &t.else_expr)),
1872 }),
1873 ExprKind::NullCoalesce(n) => {
1874 arena_ast::ExprKind::NullCoalesce(arena_ast::NullCoalesceExpr {
1875 left: arena.alloc(av_expr(arena, &n.left)),
1876 right: arena.alloc(av_expr(arena, &n.right)),
1877 })
1878 }
1879 ExprKind::FunctionCall(f) => {
1880 arena_ast::ExprKind::FunctionCall(arena_ast::FunctionCallExpr {
1881 name: arena.alloc(av_expr(arena, &f.name)),
1882 args: av_args(arena, &f.args),
1883 })
1884 }
1885 ExprKind::Array(elems) => {
1886 let mut v = arena_ast::ArenaVec::with_capacity_in(elems.len(), arena);
1887 for e in elems.iter() {
1888 v.push(arena_ast::ArrayElement {
1889 key: e.key.as_ref().map(|k| av_expr(arena, k)),
1890 value: av_expr(arena, &e.value),
1891 unpack: e.unpack,
1892 by_ref: e.by_ref,
1893 span: e.span,
1894 });
1895 }
1896 arena_ast::ExprKind::Array(v)
1897 }
1898 ExprKind::ArrayAccess(a) => arena_ast::ExprKind::ArrayAccess(arena_ast::ArrayAccessExpr {
1899 array: arena.alloc(av_expr(arena, &a.array)),
1900 index: a.index.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))),
1901 }),
1902 ExprKind::Print(e) => arena_ast::ExprKind::Print(arena.alloc(av_expr(arena, e))),
1903 ExprKind::Parenthesized(e) => {
1904 arena_ast::ExprKind::Parenthesized(arena.alloc(av_expr(arena, e)))
1905 }
1906 ExprKind::Cast(kind, e) => arena_ast::ExprKind::Cast(*kind, arena.alloc(av_expr(arena, e))),
1907 ExprKind::ErrorSuppress(e) => {
1908 arena_ast::ExprKind::ErrorSuppress(arena.alloc(av_expr(arena, e)))
1909 }
1910 ExprKind::Isset(exprs) => arena_ast::ExprKind::Isset(av_exprs(arena, exprs)),
1911 ExprKind::Empty(e) => arena_ast::ExprKind::Empty(arena.alloc(av_expr(arena, e))),
1912 ExprKind::Include(kind, e) => {
1913 arena_ast::ExprKind::Include(*kind, arena.alloc(av_expr(arena, e)))
1914 }
1915 ExprKind::Eval(e) => arena_ast::ExprKind::Eval(arena.alloc(av_expr(arena, e))),
1916 ExprKind::Exit(e) => {
1917 arena_ast::ExprKind::Exit(e.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))))
1918 }
1919 ExprKind::MagicConst(m) => arena_ast::ExprKind::MagicConst(*m),
1920 ExprKind::Clone(e) => arena_ast::ExprKind::Clone(arena.alloc(av_expr(arena, e))),
1921 ExprKind::CloneWith(obj, props) => arena_ast::ExprKind::CloneWith(
1922 arena.alloc(av_expr(arena, obj)),
1923 arena.alloc(av_expr(arena, props)),
1924 ),
1925 ExprKind::New(n) => arena_ast::ExprKind::New(arena_ast::NewExpr {
1926 class: arena.alloc(av_expr(arena, &n.class)),
1927 args: av_args(arena, &n.args),
1928 }),
1929 ExprKind::PropertyAccess(p) => {
1930 arena_ast::ExprKind::PropertyAccess(arena_ast::PropertyAccessExpr {
1931 object: arena.alloc(av_expr(arena, &p.object)),
1932 property: arena.alloc(av_expr(arena, &p.property)),
1933 })
1934 }
1935 ExprKind::NullsafePropertyAccess(p) => {
1936 arena_ast::ExprKind::NullsafePropertyAccess(arena_ast::PropertyAccessExpr {
1937 object: arena.alloc(av_expr(arena, &p.object)),
1938 property: arena.alloc(av_expr(arena, &p.property)),
1939 })
1940 }
1941 ExprKind::MethodCall(m) => {
1942 arena_ast::ExprKind::MethodCall(arena.alloc(arena_ast::MethodCallExpr {
1943 object: arena.alloc(av_expr(arena, &m.object)),
1944 method: arena.alloc(av_expr(arena, &m.method)),
1945 args: av_args(arena, &m.args),
1946 }))
1947 }
1948 ExprKind::NullsafeMethodCall(m) => {
1949 arena_ast::ExprKind::NullsafeMethodCall(arena.alloc(arena_ast::MethodCallExpr {
1950 object: arena.alloc(av_expr(arena, &m.object)),
1951 method: arena.alloc(av_expr(arena, &m.method)),
1952 args: av_args(arena, &m.args),
1953 }))
1954 }
1955 ExprKind::StaticPropertyAccess(s) => {
1956 arena_ast::ExprKind::StaticPropertyAccess(arena_ast::StaticAccessExpr {
1957 class: arena.alloc(av_expr(arena, &s.class)),
1958 member: arena.alloc(av_expr(arena, &s.member)),
1959 })
1960 }
1961 ExprKind::StaticMethodCall(s) => {
1962 arena_ast::ExprKind::StaticMethodCall(arena.alloc(arena_ast::StaticMethodCallExpr {
1963 class: arena.alloc(av_expr(arena, &s.class)),
1964 method: arena.alloc(av_expr(arena, &s.method)),
1965 args: av_args(arena, &s.args),
1966 }))
1967 }
1968 ExprKind::StaticDynMethodCall(s) => arena_ast::ExprKind::StaticDynMethodCall(arena.alloc(
1969 arena_ast::StaticDynMethodCallExpr {
1970 class: arena.alloc(av_expr(arena, &s.class)),
1971 method: arena.alloc(av_expr(arena, &s.method)),
1972 args: av_args(arena, &s.args),
1973 },
1974 )),
1975 ExprKind::ClassConstAccess(s) => {
1976 arena_ast::ExprKind::ClassConstAccess(arena_ast::StaticAccessExpr {
1977 class: arena.alloc(av_expr(arena, &s.class)),
1978 member: arena.alloc(av_expr(arena, &s.member)),
1979 })
1980 }
1981 ExprKind::ClassConstAccessDynamic { class, member } => {
1982 arena_ast::ExprKind::ClassConstAccessDynamic {
1983 class: arena.alloc(av_expr(arena, class)),
1984 member: arena.alloc(av_expr(arena, member)),
1985 }
1986 }
1987 ExprKind::StaticPropertyAccessDynamic { class, member } => {
1988 arena_ast::ExprKind::StaticPropertyAccessDynamic {
1989 class: arena.alloc(av_expr(arena, class)),
1990 member: arena.alloc(av_expr(arena, member)),
1991 }
1992 }
1993 ExprKind::Closure(c) => arena_ast::ExprKind::Closure(arena.alloc(arena_ast::ClosureExpr {
1994 is_static: c.is_static,
1995 by_ref: c.by_ref,
1996 params: av_params(arena, &c.params),
1997 use_vars: {
1998 let mut v = arena_ast::ArenaVec::with_capacity_in(c.use_vars.len(), arena);
1999 for uv in c.use_vars.iter() {
2000 v.push(arena_ast::ClosureUseVar {
2001 name: arena.alloc_str(&uv.name),
2002 by_ref: uv.by_ref,
2003 span: uv.span,
2004 });
2005 }
2006 v
2007 },
2008 return_type: c.return_type.as_ref().map(|t| av_type_hint(arena, t)),
2009 body: av_stmts(arena, &c.body),
2010 attributes: av_attrs(arena, &c.attributes),
2011 })),
2012 ExprKind::ArrowFunction(f) => {
2013 arena_ast::ExprKind::ArrowFunction(arena.alloc(arena_ast::ArrowFunctionExpr {
2014 is_static: f.is_static,
2015 by_ref: f.by_ref,
2016 params: av_params(arena, &f.params),
2017 return_type: f.return_type.as_ref().map(|t| av_type_hint(arena, t)),
2018 body: arena.alloc(av_expr(arena, &f.body)),
2019 attributes: av_attrs(arena, &f.attributes),
2020 }))
2021 }
2022 ExprKind::Match(m) => arena_ast::ExprKind::Match(arena_ast::MatchExpr {
2023 subject: arena.alloc(av_expr(arena, &m.subject)),
2024 arms: {
2025 let mut v = arena_ast::ArenaVec::with_capacity_in(m.arms.len(), arena);
2026 for arm in m.arms.iter() {
2027 v.push(arena_ast::MatchArm {
2028 conditions: arm.conditions.as_ref().map(|conds| av_exprs(arena, conds)),
2029 body: av_expr(arena, &arm.body),
2030 span: arm.span,
2031 });
2032 }
2033 v
2034 },
2035 }),
2036 ExprKind::ThrowExpr(e) => arena_ast::ExprKind::ThrowExpr(arena.alloc(av_expr(arena, e))),
2037 ExprKind::Yield(y) => arena_ast::ExprKind::Yield(arena_ast::YieldExpr {
2038 key: y.key.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))),
2039 value: y.value.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))),
2040 is_from: y.is_from,
2041 }),
2042 ExprKind::AnonymousClass(cls) => {
2043 arena_ast::ExprKind::AnonymousClass(arena.alloc(av_class_decl(arena, cls)))
2044 }
2045 ExprKind::CallableCreate(c) => {
2046 arena_ast::ExprKind::CallableCreate(arena_ast::CallableCreateExpr {
2047 kind: match &c.kind {
2048 CallableCreateKind::Function(e) => {
2049 arena_ast::CallableCreateKind::Function(arena.alloc(av_expr(arena, e)))
2050 }
2051 CallableCreateKind::Method { object, method } => {
2052 arena_ast::CallableCreateKind::Method {
2053 object: arena.alloc(av_expr(arena, object)),
2054 method: arena.alloc(av_expr(arena, method)),
2055 }
2056 }
2057 CallableCreateKind::NullsafeMethod { object, method } => {
2058 arena_ast::CallableCreateKind::NullsafeMethod {
2059 object: arena.alloc(av_expr(arena, object)),
2060 method: arena.alloc(av_expr(arena, method)),
2061 }
2062 }
2063 CallableCreateKind::StaticMethod { class, method } => {
2064 arena_ast::CallableCreateKind::StaticMethod {
2065 class: arena.alloc(av_expr(arena, class)),
2066 method: arena.alloc(av_expr(arena, method)),
2067 }
2068 }
2069 },
2070 })
2071 }
2072 ExprKind::Omit => arena_ast::ExprKind::Omit,
2073 ExprKind::Error => arena_ast::ExprKind::Error,
2074 }
2075}
2076
2077fn av_param<'a>(arena: &'a bumpalo::Bump, p: &Param) -> arena_ast::Param<'a, 'a> {
2078 arena_ast::Param {
2079 name: av_ident(arena, &p.name),
2080 type_hint: p.type_hint.as_ref().map(|t| av_type_hint(arena, t)),
2081 default: p.default.as_ref().map(|e| av_expr(arena, e)),
2082 by_ref: p.by_ref,
2083 variadic: p.variadic,
2084 is_readonly: p.is_readonly,
2085 is_final: p.is_final,
2086 visibility: p.visibility,
2087 set_visibility: p.set_visibility,
2088 attributes: av_attrs(arena, &p.attributes),
2089 hooks: av_hooks(arena, &p.hooks),
2090 span: p.span,
2091 }
2092}
2093
2094fn av_params<'a>(
2095 arena: &'a bumpalo::Bump,
2096 params: &[Param],
2097) -> arena_ast::ArenaVec<'a, arena_ast::Param<'a, 'a>> {
2098 let mut v = arena_ast::ArenaVec::with_capacity_in(params.len(), arena);
2099 for p in params.iter() {
2100 v.push(av_param(arena, p));
2101 }
2102 v
2103}
2104
2105fn av_hook<'a>(arena: &'a bumpalo::Bump, h: &PropertyHook) -> arena_ast::PropertyHook<'a, 'a> {
2106 arena_ast::PropertyHook {
2107 kind: h.kind,
2108 body: match &h.body {
2109 PropertyHookBody::Block(stmts) => {
2110 arena_ast::PropertyHookBody::Block(av_stmts(arena, stmts))
2111 }
2112 PropertyHookBody::Expression(e) => {
2113 arena_ast::PropertyHookBody::Expression(av_expr(arena, e))
2114 }
2115 PropertyHookBody::Abstract => arena_ast::PropertyHookBody::Abstract,
2116 },
2117 is_final: h.is_final,
2118 by_ref: h.by_ref,
2119 params: av_params(arena, &h.params),
2120 attributes: av_attrs(arena, &h.attributes),
2121 span: h.span,
2122 }
2123}
2124
2125fn av_hooks<'a>(
2126 arena: &'a bumpalo::Bump,
2127 hooks: &[PropertyHook],
2128) -> arena_ast::ArenaVec<'a, arena_ast::PropertyHook<'a, 'a>> {
2129 let mut v = arena_ast::ArenaVec::with_capacity_in(hooks.len(), arena);
2130 for h in hooks.iter() {
2131 v.push(av_hook(arena, h));
2132 }
2133 v
2134}
2135
2136fn av_stmt<'a>(arena: &'a bumpalo::Bump, stmt: &Stmt) -> arena_ast::Stmt<'a, 'a> {
2137 arena_ast::Stmt {
2138 kind: av_stmt_kind(arena, &stmt.kind),
2139 span: stmt.span,
2140 }
2141}
2142
2143fn av_stmts<'a>(
2144 arena: &'a bumpalo::Bump,
2145 stmts: &[Stmt],
2146) -> arena_ast::ArenaVec<'a, arena_ast::Stmt<'a, 'a>> {
2147 let mut v = arena_ast::ArenaVec::with_capacity_in(stmts.len(), arena);
2148 for s in stmts.iter() {
2149 v.push(av_stmt(arena, s));
2150 }
2151 v
2152}
2153
2154fn av_stmt_kind<'a>(arena: &'a bumpalo::Bump, k: &StmtKind) -> arena_ast::StmtKind<'a, 'a> {
2155 match k {
2156 StmtKind::Expression(e) => arena_ast::StmtKind::Expression(arena.alloc(av_expr(arena, e))),
2157 StmtKind::Echo(exprs) => arena_ast::StmtKind::Echo(av_exprs(arena, exprs)),
2158 StmtKind::Return(e) => {
2159 arena_ast::StmtKind::Return(e.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))))
2160 }
2161 StmtKind::Block(stmts) => arena_ast::StmtKind::Block(av_stmts(arena, stmts)),
2162 StmtKind::If(s) => arena_ast::StmtKind::If(
2163 arena.alloc(arena_ast::IfStmt {
2164 condition: av_expr(arena, &s.condition),
2165 then_branch: arena.alloc(av_stmt(arena, &s.then_branch)),
2166 elseif_branches: {
2167 let mut v =
2168 arena_ast::ArenaVec::with_capacity_in(s.elseif_branches.len(), arena);
2169 for b in s.elseif_branches.iter() {
2170 v.push(arena_ast::ElseIfBranch {
2171 condition: av_expr(arena, &b.condition),
2172 body: av_stmt(arena, &b.body),
2173 span: b.span,
2174 });
2175 }
2176 v
2177 },
2178 else_branch: s
2179 .else_branch
2180 .as_ref()
2181 .map(|b| &*arena.alloc(av_stmt(arena, b))),
2182 uses_alternative: s.uses_alternative,
2183 }),
2184 ),
2185 StmtKind::While(s) => arena_ast::StmtKind::While(arena.alloc(arena_ast::WhileStmt {
2186 condition: av_expr(arena, &s.condition),
2187 body: arena.alloc(av_stmt(arena, &s.body)),
2188 uses_alternative: s.uses_alternative,
2189 })),
2190 StmtKind::For(s) => arena_ast::StmtKind::For(arena.alloc(arena_ast::ForStmt {
2191 init: av_exprs(arena, &s.init),
2192 condition: av_exprs(arena, &s.condition),
2193 update: av_exprs(arena, &s.update),
2194 body: arena.alloc(av_stmt(arena, &s.body)),
2195 uses_alternative: s.uses_alternative,
2196 })),
2197 StmtKind::Foreach(s) => arena_ast::StmtKind::Foreach(arena.alloc(arena_ast::ForeachStmt {
2198 expr: av_expr(arena, &s.expr),
2199 key: s.key.as_ref().map(|e| av_expr(arena, e)),
2200 value: av_expr(arena, &s.value),
2201 body: arena.alloc(av_stmt(arena, &s.body)),
2202 uses_alternative: s.uses_alternative,
2203 })),
2204 StmtKind::DoWhile(s) => arena_ast::StmtKind::DoWhile(arena.alloc(arena_ast::DoWhileStmt {
2205 body: arena.alloc(av_stmt(arena, &s.body)),
2206 condition: av_expr(arena, &s.condition),
2207 })),
2208 StmtKind::Function(f) => {
2209 arena_ast::StmtKind::Function(arena.alloc(av_function_decl(arena, f)))
2210 }
2211 StmtKind::Break(e) => {
2212 arena_ast::StmtKind::Break(e.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))))
2213 }
2214 StmtKind::Continue(e) => {
2215 arena_ast::StmtKind::Continue(e.as_ref().map(|e| &*arena.alloc(av_expr(arena, e))))
2216 }
2217 StmtKind::Switch(s) => arena_ast::StmtKind::Switch(arena.alloc(arena_ast::SwitchStmt {
2218 expr: av_expr(arena, &s.expr),
2219 cases: {
2220 let mut v = arena_ast::ArenaVec::with_capacity_in(s.cases.len(), arena);
2221 for c in s.cases.iter() {
2222 v.push(arena_ast::SwitchCase {
2223 value: c.value.as_ref().map(|vl| av_expr(arena, vl)),
2224 body: av_stmts(arena, &c.body),
2225 span: c.span,
2226 });
2227 }
2228 v
2229 },
2230 uses_alternative: s.uses_alternative,
2231 })),
2232 StmtKind::Goto(ident) => arena_ast::StmtKind::Goto(av_ident(arena, ident)),
2233 StmtKind::Label(s) => arena_ast::StmtKind::Label(av_str(arena, s)),
2234 StmtKind::Declare(d) => arena_ast::StmtKind::Declare(arena.alloc(arena_ast::DeclareStmt {
2235 directives: {
2236 let mut v = arena_ast::ArenaVec::with_capacity_in(d.directives.len(), arena);
2237 for (k, val) in d.directives.iter() {
2238 v.push((arena.alloc_str(k) as &str, av_expr(arena, val)));
2239 }
2240 v
2241 },
2242 body: d.body.as_ref().map(|b| &*arena.alloc(av_stmt(arena, b))),
2243 uses_alternative: d.uses_alternative,
2244 })),
2245 StmtKind::Unset(exprs) => arena_ast::StmtKind::Unset(av_exprs(arena, exprs)),
2246 StmtKind::Throw(e) => arena_ast::StmtKind::Throw(arena.alloc(av_expr(arena, e))),
2247 StmtKind::TryCatch(t) => {
2248 arena_ast::StmtKind::TryCatch(arena.alloc(arena_ast::TryCatchStmt {
2249 body: av_stmts(arena, &t.body),
2250 catches: {
2251 let mut v = arena_ast::ArenaVec::with_capacity_in(t.catches.len(), arena);
2252 for c in t.catches.iter() {
2253 let mut types = arena_ast::ArenaVec::with_capacity_in(c.types.len(), arena);
2254 for n in c.types.iter() {
2255 types.push(av_name(arena, n));
2256 }
2257 v.push(arena_ast::CatchClause {
2258 types,
2259 var: c.var.as_deref().map(|s| av_str(arena, s)),
2260 body: av_stmts(arena, &c.body),
2261 span: c.span,
2262 });
2263 }
2264 v
2265 },
2266 finally: t.finally.as_ref().map(|stmts| av_stmts(arena, stmts)),
2267 }))
2268 }
2269 StmtKind::Global(exprs) => arena_ast::StmtKind::Global(av_exprs(arena, exprs)),
2270 StmtKind::Class(cls) => arena_ast::StmtKind::Class(arena.alloc(av_class_decl(arena, cls))),
2271 StmtKind::Interface(iface) => {
2272 arena_ast::StmtKind::Interface(arena.alloc(av_interface_decl(arena, iface)))
2273 }
2274 StmtKind::Trait(tr) => arena_ast::StmtKind::Trait(arena.alloc(av_trait_decl(arena, tr))),
2275 StmtKind::Enum(en) => arena_ast::StmtKind::Enum(arena.alloc(av_enum_decl(arena, en))),
2276 StmtKind::Namespace(ns) => {
2277 arena_ast::StmtKind::Namespace(arena.alloc(arena_ast::NamespaceDecl {
2278 name: ns.name.as_ref().map(|n| av_name(arena, n)),
2279 body: match &ns.body {
2280 NamespaceBody::Braced(stmts) => {
2281 arena_ast::NamespaceBody::Braced(av_stmts(arena, stmts))
2282 }
2283 NamespaceBody::Simple => arena_ast::NamespaceBody::Simple,
2284 },
2285 }))
2286 }
2287 StmtKind::Use(u) => arena_ast::StmtKind::Use(arena.alloc(arena_ast::UseDecl {
2288 kind: u.kind,
2289 uses: {
2290 let mut v = arena_ast::ArenaVec::with_capacity_in(u.uses.len(), arena);
2291 for item in u.uses.iter() {
2292 v.push(arena_ast::UseItem {
2293 name: av_name(arena, &item.name),
2294 alias: item.alias.as_deref().map(|s| av_str(arena, s)),
2295 kind: item.kind,
2296 span: item.span,
2297 });
2298 }
2299 v
2300 },
2301 })),
2302 StmtKind::Const(items) => {
2303 let mut v = arena_ast::ArenaVec::with_capacity_in(items.len(), arena);
2304 for item in items.iter() {
2305 v.push(arena_ast::ConstItem {
2306 name: av_ident(arena, &item.name),
2307 value: av_expr(arena, &item.value),
2308 attributes: av_attrs(arena, &item.attributes),
2309 span: item.span,
2310 doc_comment: av_opt_comment(arena, &item.doc_comment),
2311 });
2312 }
2313 arena_ast::StmtKind::Const(v)
2314 }
2315 StmtKind::StaticVar(vars) => {
2316 let mut v = arena_ast::ArenaVec::with_capacity_in(vars.len(), arena);
2317 for var in vars.iter() {
2318 v.push(arena_ast::StaticVar {
2319 name: av_ident(arena, &var.name),
2320 default: var.default.as_ref().map(|e| av_expr(arena, e)),
2321 span: var.span,
2322 });
2323 }
2324 arena_ast::StmtKind::StaticVar(v)
2325 }
2326 StmtKind::HaltCompiler(s) => arena_ast::StmtKind::HaltCompiler(av_str(arena, s)),
2327 StmtKind::Nop => arena_ast::StmtKind::Nop,
2328 StmtKind::InlineHtml(s) => arena_ast::StmtKind::InlineHtml(av_str(arena, s)),
2329 StmtKind::Error => arena_ast::StmtKind::Error,
2330 }
2331}
2332
2333fn av_function_decl<'a>(
2334 arena: &'a bumpalo::Bump,
2335 f: &FunctionDecl,
2336) -> arena_ast::FunctionDecl<'a, 'a> {
2337 arena_ast::FunctionDecl {
2338 name: av_ident(arena, &f.name),
2339 params: av_params(arena, &f.params),
2340 body: av_stmts(arena, &f.body),
2341 return_type: f.return_type.as_ref().map(|t| av_type_hint(arena, t)),
2342 by_ref: f.by_ref,
2343 attributes: av_attrs(arena, &f.attributes),
2344 doc_comment: av_opt_comment(arena, &f.doc_comment),
2345 }
2346}
2347
2348fn av_class_member<'a>(
2349 arena: &'a bumpalo::Bump,
2350 m: &ClassMember,
2351) -> arena_ast::ClassMember<'a, 'a> {
2352 arena_ast::ClassMember {
2353 kind: match &m.kind {
2354 ClassMemberKind::Property(p) => {
2355 arena_ast::ClassMemberKind::Property(arena_ast::PropertyDecl {
2356 name: av_ident(arena, &p.name),
2357 visibility: p.visibility,
2358 set_visibility: p.set_visibility,
2359 is_static: p.is_static,
2360 is_readonly: p.is_readonly,
2361 type_hint: p.type_hint.as_ref().map(|t| av_type_hint(arena, t)),
2362 default: p.default.as_ref().map(|e| av_expr(arena, e)),
2363 attributes: av_attrs(arena, &p.attributes),
2364 hooks: av_hooks(arena, &p.hooks),
2365 doc_comment: av_opt_comment(arena, &p.doc_comment),
2366 })
2367 }
2368 ClassMemberKind::Method(m) => {
2369 arena_ast::ClassMemberKind::Method(arena_ast::MethodDecl {
2370 name: av_ident(arena, &m.name),
2371 visibility: m.visibility,
2372 is_static: m.is_static,
2373 is_abstract: m.is_abstract,
2374 is_final: m.is_final,
2375 by_ref: m.by_ref,
2376 params: av_params(arena, &m.params),
2377 return_type: m.return_type.as_ref().map(|t| av_type_hint(arena, t)),
2378 body: m.body.as_ref().map(|stmts| av_stmts(arena, stmts)),
2379 attributes: av_attrs(arena, &m.attributes),
2380 doc_comment: av_opt_comment(arena, &m.doc_comment),
2381 })
2382 }
2383 ClassMemberKind::ClassConst(c) => {
2384 arena_ast::ClassMemberKind::ClassConst(av_class_const(arena, c))
2385 }
2386 ClassMemberKind::TraitUse(t) => {
2387 arena_ast::ClassMemberKind::TraitUse(av_trait_use(arena, t))
2388 }
2389 },
2390 span: m.span,
2391 }
2392}
2393
2394fn av_class_members<'a>(
2395 arena: &'a bumpalo::Bump,
2396 members: &[ClassMember],
2397) -> arena_ast::ArenaVec<'a, arena_ast::ClassMember<'a, 'a>> {
2398 let mut v = arena_ast::ArenaVec::with_capacity_in(members.len(), arena);
2399 for m in members.iter() {
2400 v.push(av_class_member(arena, m));
2401 }
2402 v
2403}
2404
2405fn av_class_const<'a>(
2406 arena: &'a bumpalo::Bump,
2407 c: &ClassConstDecl,
2408) -> arena_ast::ClassConstDecl<'a, 'a> {
2409 arena_ast::ClassConstDecl {
2410 name: av_ident(arena, &c.name),
2411 visibility: c.visibility,
2412 is_final: c.is_final,
2413 type_hint: c
2414 .type_hint
2415 .as_ref()
2416 .map(|th| arena.alloc(av_type_hint(arena, th)) as &_),
2417 value: av_expr(arena, &c.value),
2418 attributes: av_attrs(arena, &c.attributes),
2419 doc_comment: av_opt_comment(arena, &c.doc_comment),
2420 }
2421}
2422
2423fn av_trait_use<'a>(arena: &'a bumpalo::Bump, t: &TraitUseDecl) -> arena_ast::TraitUseDecl<'a, 'a> {
2424 let mut traits = arena_ast::ArenaVec::with_capacity_in(t.traits.len(), arena);
2425 for n in t.traits.iter() {
2426 traits.push(av_name(arena, n));
2427 }
2428 let mut adaptations = arena_ast::ArenaVec::with_capacity_in(t.adaptations.len(), arena);
2429 for a in t.adaptations.iter() {
2430 adaptations.push(arena_ast::TraitAdaptation {
2431 kind: match &a.kind {
2432 TraitAdaptationKind::Precedence {
2433 trait_name,
2434 method,
2435 insteadof,
2436 } => {
2437 let mut instead = arena_ast::ArenaVec::with_capacity_in(insteadof.len(), arena);
2438 for n in insteadof.iter() {
2439 instead.push(av_name(arena, n));
2440 }
2441 arena_ast::TraitAdaptationKind::Precedence {
2442 trait_name: av_name(arena, trait_name),
2443 method: av_name(arena, method),
2444 insteadof: instead,
2445 }
2446 }
2447 TraitAdaptationKind::Alias {
2448 trait_name,
2449 method,
2450 new_modifier,
2451 new_name,
2452 } => arena_ast::TraitAdaptationKind::Alias {
2453 trait_name: trait_name.as_ref().map(|n| av_name(arena, n)),
2454 method: av_name(arena, method),
2455 new_modifier: *new_modifier,
2456 new_name: new_name.as_ref().map(|n| av_name(arena, n)),
2457 },
2458 },
2459 span: a.span,
2460 });
2461 }
2462 arena_ast::TraitUseDecl {
2463 traits,
2464 adaptations,
2465 }
2466}
2467
2468fn av_class_decl<'a>(arena: &'a bumpalo::Bump, cls: &ClassDecl) -> arena_ast::ClassDecl<'a, 'a> {
2469 let mut implements = arena_ast::ArenaVec::with_capacity_in(cls.implements.len(), arena);
2470 for n in cls.implements.iter() {
2471 implements.push(av_name(arena, n));
2472 }
2473 arena_ast::ClassDecl {
2474 name: cls.name.as_ref().map(|ident| av_ident(arena, ident)),
2475 modifiers: cls.modifiers.clone(),
2476 extends: cls.extends.as_ref().map(|n| av_name(arena, n)),
2477 implements,
2478 members: av_class_members(arena, &cls.members),
2479 attributes: av_attrs(arena, &cls.attributes),
2480 doc_comment: av_opt_comment(arena, &cls.doc_comment),
2481 }
2482}
2483
2484fn av_interface_decl<'a>(
2485 arena: &'a bumpalo::Bump,
2486 iface: &InterfaceDecl,
2487) -> arena_ast::InterfaceDecl<'a, 'a> {
2488 let mut extends = arena_ast::ArenaVec::with_capacity_in(iface.extends.len(), arena);
2489 for n in iface.extends.iter() {
2490 extends.push(av_name(arena, n));
2491 }
2492 arena_ast::InterfaceDecl {
2493 name: av_ident(arena, &iface.name),
2494 extends,
2495 members: av_class_members(arena, &iface.members),
2496 attributes: av_attrs(arena, &iface.attributes),
2497 doc_comment: av_opt_comment(arena, &iface.doc_comment),
2498 }
2499}
2500
2501fn av_trait_decl<'a>(arena: &'a bumpalo::Bump, tr: &TraitDecl) -> arena_ast::TraitDecl<'a, 'a> {
2502 arena_ast::TraitDecl {
2503 name: av_ident(arena, &tr.name),
2504 members: av_class_members(arena, &tr.members),
2505 attributes: av_attrs(arena, &tr.attributes),
2506 doc_comment: av_opt_comment(arena, &tr.doc_comment),
2507 }
2508}
2509
2510fn av_enum_decl<'a>(arena: &'a bumpalo::Bump, en: &EnumDecl) -> arena_ast::EnumDecl<'a, 'a> {
2511 let mut implements = arena_ast::ArenaVec::with_capacity_in(en.implements.len(), arena);
2512 for n in en.implements.iter() {
2513 implements.push(av_name(arena, n));
2514 }
2515 let mut members = arena_ast::ArenaVec::with_capacity_in(en.members.len(), arena);
2516 for m in en.members.iter() {
2517 members.push(arena_ast::EnumMember {
2518 kind: match &m.kind {
2519 EnumMemberKind::Case(c) => arena_ast::EnumMemberKind::Case(arena_ast::EnumCase {
2520 name: av_ident(arena, &c.name),
2521 value: c.value.as_ref().map(|e| av_expr(arena, e)),
2522 attributes: av_attrs(arena, &c.attributes),
2523 doc_comment: av_opt_comment(arena, &c.doc_comment),
2524 }),
2525 EnumMemberKind::Method(m) => {
2526 arena_ast::EnumMemberKind::Method(arena_ast::MethodDecl {
2527 name: av_ident(arena, &m.name),
2528 visibility: m.visibility,
2529 is_static: m.is_static,
2530 is_abstract: m.is_abstract,
2531 is_final: m.is_final,
2532 by_ref: m.by_ref,
2533 params: av_params(arena, &m.params),
2534 return_type: m.return_type.as_ref().map(|t| av_type_hint(arena, t)),
2535 body: m.body.as_ref().map(|stmts| av_stmts(arena, stmts)),
2536 attributes: av_attrs(arena, &m.attributes),
2537 doc_comment: av_opt_comment(arena, &m.doc_comment),
2538 })
2539 }
2540 EnumMemberKind::ClassConst(c) => {
2541 arena_ast::EnumMemberKind::ClassConst(av_class_const(arena, c))
2542 }
2543 EnumMemberKind::TraitUse(t) => {
2544 arena_ast::EnumMemberKind::TraitUse(av_trait_use(arena, t))
2545 }
2546 },
2547 span: m.span,
2548 });
2549 }
2550 arena_ast::EnumDecl {
2551 name: av_ident(arena, &en.name),
2552 scalar_type: en.scalar_type.as_ref().map(|n| av_name(arena, n)),
2553 implements,
2554 members,
2555 attributes: av_attrs(arena, &en.attributes),
2556 doc_comment: av_opt_comment(arena, &en.doc_comment),
2557 }
2558}