1use std::borrow::Cow;
2
3use serde::Serialize;
4
5use crate::Span;
6
7pub struct ArenaVec<'arena, T>(bumpalo::collections::Vec<'arena, T>);
9
10impl<'arena, T> ArenaVec<'arena, T> {
11 #[inline]
12 pub fn new_in(arena: &'arena bumpalo::Bump) -> Self {
13 Self(bumpalo::collections::Vec::new_in(arena))
14 }
15 #[inline]
16 pub fn with_capacity_in(cap: usize, arena: &'arena bumpalo::Bump) -> Self {
17 Self(bumpalo::collections::Vec::with_capacity_in(cap, arena))
18 }
19 #[inline]
20 pub fn push(&mut self, val: T) {
21 self.0.push(val)
22 }
23 #[inline]
24 pub fn is_empty(&self) -> bool {
25 self.0.is_empty()
26 }
27 #[inline]
28 pub fn len(&self) -> usize {
29 self.0.len()
30 }
31 #[inline]
32 pub fn last(&self) -> Option<&T> {
33 self.0.last()
34 }
35}
36
37impl<'arena, T> IntoIterator for ArenaVec<'arena, T> {
38 type Item = T;
39 type IntoIter = bumpalo::collections::vec::IntoIter<'arena, T>;
40 #[inline]
41 fn into_iter(self) -> Self::IntoIter {
42 self.0.into_iter()
43 }
44}
45
46impl<'arena, T> std::ops::Deref for ArenaVec<'arena, T> {
47 type Target = [T];
48 #[inline]
49 fn deref(&self) -> &[T] {
50 &self.0
51 }
52}
53
54impl<'arena, T> std::ops::DerefMut for ArenaVec<'arena, T> {
55 #[inline]
56 fn deref_mut(&mut self) -> &mut [T] {
57 &mut self.0
58 }
59}
60
61impl<'arena, T: serde::Serialize> serde::Serialize for ArenaVec<'arena, T> {
62 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
63 self.0.as_slice().serialize(s)
64 }
65}
66
67impl<'arena, T: std::fmt::Debug> std::fmt::Debug for ArenaVec<'arena, T> {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 self.0.as_slice().fmt(f)
70 }
71}
72
73#[derive(Debug, Serialize)]
75pub struct Program<'arena, 'src> {
76 pub stmts: ArenaVec<'arena, Stmt<'arena, 'src>>,
77 pub span: Span,
78}
79
80pub enum Name<'arena, 'src> {
93 Simple { value: &'src str, span: Span },
96 Complex {
98 parts: ArenaVec<'arena, &'src str>,
99 kind: NameKind,
100 span: Span,
101 },
102}
103
104impl<'arena, 'src> Name<'arena, 'src> {
105 #[inline]
106 pub fn span(&self) -> Span {
107 match self {
108 Self::Simple { span, .. } | Self::Complex { span, .. } => *span,
109 }
110 }
111
112 #[inline]
113 pub fn kind(&self) -> NameKind {
114 match self {
115 Self::Simple { .. } => NameKind::Unqualified,
116 Self::Complex { kind, .. } => *kind,
117 }
118 }
119
120 #[inline]
123 pub fn to_string_repr(&self) -> Cow<'src, str> {
124 match self {
125 Self::Simple { value, .. } => Cow::Borrowed(value),
126 Self::Complex { parts, kind, .. } => {
127 let joined = parts.join("\\");
128 if *kind == NameKind::FullyQualified {
129 Cow::Owned(format!("\\{}", joined))
130 } else {
131 Cow::Owned(joined)
132 }
133 }
134 }
135 }
136
137 #[inline]
140 pub fn join_parts(&self) -> Cow<'src, str> {
141 match self {
142 Self::Simple { value, .. } => Cow::Borrowed(value),
143 Self::Complex { parts, .. } => Cow::Owned(parts.join("\\")),
144 }
145 }
146
147 #[inline]
150 pub fn parts_slice(&self) -> &[&'src str] {
151 match self {
152 Self::Simple { value, .. } => std::slice::from_ref(value),
153 Self::Complex { parts, .. } => parts,
154 }
155 }
156}
157
158impl<'arena, 'src> std::fmt::Debug for Name<'arena, 'src> {
159 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160 match self {
161 Self::Simple { value, span } => f
162 .debug_struct("Name")
163 .field("parts", &std::slice::from_ref(value))
164 .field("kind", &NameKind::Unqualified)
165 .field("span", span)
166 .finish(),
167 Self::Complex { parts, kind, span } => f
168 .debug_struct("Name")
169 .field("parts", parts)
170 .field("kind", kind)
171 .field("span", span)
172 .finish(),
173 }
174 }
175}
176
177impl<'arena, 'src> serde::Serialize for Name<'arena, 'src> {
178 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
179 use serde::ser::SerializeStruct;
180 let mut st = s.serialize_struct("Name", 3)?;
181 match self {
182 Self::Simple { value, span } => {
183 st.serialize_field("parts", std::slice::from_ref(value))?;
184 st.serialize_field("kind", &NameKind::Unqualified)?;
185 st.serialize_field("span", span)?;
186 }
187 Self::Complex { parts, kind, span } => {
188 st.serialize_field("parts", parts)?;
189 st.serialize_field("kind", kind)?;
190 st.serialize_field("span", span)?;
191 }
192 }
193 st.end()
194 }
195}
196
197#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
198pub enum NameKind {
199 Unqualified,
200 Qualified,
201 FullyQualified,
202 Relative,
203}
204
205#[repr(u8)]
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
209pub enum BuiltinType {
210 Int,
211 Integer,
212 Float,
213 Double,
214 String,
215 Bool,
216 Boolean,
217 Void,
218 Never,
219 Mixed,
220 Object,
221 Iterable,
222 Callable,
223 Array,
224 Self_,
225 Parent_,
226 Static,
227 Null,
228 True,
229 False,
230}
231
232impl BuiltinType {
233 #[inline]
235 pub fn as_str(self) -> &'static str {
236 match self {
237 Self::Int => "int",
238 Self::Integer => "integer",
239 Self::Float => "float",
240 Self::Double => "double",
241 Self::String => "string",
242 Self::Bool => "bool",
243 Self::Boolean => "boolean",
244 Self::Void => "void",
245 Self::Never => "never",
246 Self::Mixed => "mixed",
247 Self::Object => "object",
248 Self::Iterable => "iterable",
249 Self::Callable => "callable",
250 Self::Array => "array",
251 Self::Self_ => "self",
252 Self::Parent_ => "parent",
253 Self::Static => "static",
254 Self::Null => "null",
255 Self::True => "true",
256 Self::False => "false",
257 }
258 }
259}
260
261#[derive(Debug, Serialize)]
262pub struct TypeHint<'arena, 'src> {
263 pub kind: TypeHintKind<'arena, 'src>,
264 pub span: Span,
265}
266
267#[derive(Debug)]
275pub enum TypeHintKind<'arena, 'src> {
276 Named(Name<'arena, 'src>),
277 Keyword(BuiltinType, Span),
279 Nullable(&'arena TypeHint<'arena, 'src>),
280 Union(ArenaVec<'arena, TypeHint<'arena, 'src>>),
281 Intersection(ArenaVec<'arena, TypeHint<'arena, 'src>>),
282}
283
284impl<'arena, 'src> serde::Serialize for TypeHintKind<'arena, 'src> {
285 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
286 match self {
287 Self::Named(name) => s.serialize_newtype_variant("TypeHintKind", 0, "Named", name),
289 Self::Nullable(inner) => {
290 s.serialize_newtype_variant("TypeHintKind", 2, "Nullable", inner)
291 }
292 Self::Union(types) => s.serialize_newtype_variant("TypeHintKind", 3, "Union", types),
293 Self::Intersection(types) => {
294 s.serialize_newtype_variant("TypeHintKind", 4, "Intersection", types)
295 }
296 Self::Keyword(builtin, span) => {
299 struct BuiltinNameRepr<'a>(&'a BuiltinType, &'a Span);
300 impl serde::Serialize for BuiltinNameRepr<'_> {
301 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
302 use serde::ser::SerializeStruct;
303 let mut st = s.serialize_struct("Name", 3)?;
304 st.serialize_field("parts", &[self.0.as_str()])?;
305 st.serialize_field("kind", &NameKind::Unqualified)?;
306 st.serialize_field("span", self.1)?;
307 st.end()
308 }
309 }
310 s.serialize_newtype_variant(
311 "TypeHintKind",
312 0,
313 "Named",
314 &BuiltinNameRepr(builtin, span),
315 )
316 }
317 }
318 }
319}
320
321#[derive(Debug, Serialize)]
326pub struct Arg<'arena, 'src> {
327 pub name: Option<Cow<'src, str>>,
328 pub value: Expr<'arena, 'src>,
329 pub unpack: bool,
330 pub span: Span,
331}
332
333#[derive(Debug, Serialize)]
338pub struct Attribute<'arena, 'src> {
339 pub name: Name<'arena, 'src>,
340 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
341 pub span: Span,
342}
343
344#[derive(Debug, Serialize)]
349pub struct Stmt<'arena, 'src> {
350 pub kind: StmtKind<'arena, 'src>,
351 pub span: Span,
352}
353
354#[derive(Debug, Serialize)]
355pub enum StmtKind<'arena, 'src> {
356 Expression(&'arena Expr<'arena, 'src>),
358
359 Echo(ArenaVec<'arena, Expr<'arena, 'src>>),
361
362 Return(Option<&'arena Expr<'arena, 'src>>),
364
365 Block(ArenaVec<'arena, Stmt<'arena, 'src>>),
367
368 If(&'arena IfStmt<'arena, 'src>),
370
371 While(&'arena WhileStmt<'arena, 'src>),
373
374 For(&'arena ForStmt<'arena, 'src>),
376
377 Foreach(&'arena ForeachStmt<'arena, 'src>),
379
380 DoWhile(&'arena DoWhileStmt<'arena, 'src>),
382
383 Function(&'arena FunctionDecl<'arena, 'src>),
385
386 Break(Option<&'arena Expr<'arena, 'src>>),
388
389 Continue(Option<&'arena Expr<'arena, 'src>>),
391
392 Switch(&'arena SwitchStmt<'arena, 'src>),
394
395 Goto(&'src str),
397
398 Label(&'src str),
400
401 Declare(&'arena DeclareStmt<'arena, 'src>),
403
404 Unset(ArenaVec<'arena, Expr<'arena, 'src>>),
406
407 Throw(&'arena Expr<'arena, 'src>),
409
410 TryCatch(&'arena TryCatchStmt<'arena, 'src>),
412
413 Global(ArenaVec<'arena, Expr<'arena, 'src>>),
415
416 Class(&'arena ClassDecl<'arena, 'src>),
418
419 Interface(&'arena InterfaceDecl<'arena, 'src>),
421
422 Trait(&'arena TraitDecl<'arena, 'src>),
424
425 Enum(&'arena EnumDecl<'arena, 'src>),
427
428 Namespace(&'arena NamespaceDecl<'arena, 'src>),
430
431 Use(&'arena UseDecl<'arena, 'src>),
433
434 Const(ArenaVec<'arena, ConstItem<'arena, 'src>>),
436
437 StaticVar(ArenaVec<'arena, StaticVar<'arena, 'src>>),
439
440 HaltCompiler(&'src str),
442
443 Nop,
445
446 InlineHtml(&'src str),
448
449 Error,
451}
452
453#[derive(Debug, Serialize)]
454pub struct IfStmt<'arena, 'src> {
455 pub condition: Expr<'arena, 'src>,
456 pub then_branch: &'arena Stmt<'arena, 'src>,
457 pub elseif_branches: ArenaVec<'arena, ElseIfBranch<'arena, 'src>>,
458 pub else_branch: Option<&'arena Stmt<'arena, 'src>>,
459}
460
461#[derive(Debug, Serialize)]
462pub struct ElseIfBranch<'arena, 'src> {
463 pub condition: Expr<'arena, 'src>,
464 pub body: Stmt<'arena, 'src>,
465 pub span: Span,
466}
467
468#[derive(Debug, Serialize)]
469pub struct WhileStmt<'arena, 'src> {
470 pub condition: Expr<'arena, 'src>,
471 pub body: &'arena Stmt<'arena, 'src>,
472}
473
474#[derive(Debug, Serialize)]
475pub struct ForStmt<'arena, 'src> {
476 pub init: ArenaVec<'arena, Expr<'arena, 'src>>,
477 pub condition: ArenaVec<'arena, Expr<'arena, 'src>>,
478 pub update: ArenaVec<'arena, Expr<'arena, 'src>>,
479 pub body: &'arena Stmt<'arena, 'src>,
480}
481
482#[derive(Debug, Serialize)]
483pub struct ForeachStmt<'arena, 'src> {
484 pub expr: Expr<'arena, 'src>,
485 pub key: Option<Expr<'arena, 'src>>,
486 pub value: Expr<'arena, 'src>,
487 pub body: &'arena Stmt<'arena, 'src>,
488}
489
490#[derive(Debug, Serialize)]
491pub struct DoWhileStmt<'arena, 'src> {
492 pub body: &'arena Stmt<'arena, 'src>,
493 pub condition: Expr<'arena, 'src>,
494}
495
496#[derive(Debug, Serialize)]
497pub struct FunctionDecl<'arena, 'src> {
498 pub name: &'src str,
499 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
500 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
501 pub return_type: Option<TypeHint<'arena, 'src>>,
502 pub by_ref: bool,
503 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
504}
505
506#[derive(Debug, Serialize)]
507pub struct Param<'arena, 'src> {
508 pub name: &'src str,
509 pub type_hint: Option<TypeHint<'arena, 'src>>,
510 pub default: Option<Expr<'arena, 'src>>,
511 pub by_ref: bool,
512 pub variadic: bool,
513 pub visibility: Option<Visibility>,
514 pub set_visibility: Option<Visibility>,
515 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
516 #[serde(skip_serializing_if = "ArenaVec::is_empty")]
517 pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
518 pub span: Span,
519}
520
521#[derive(Debug, Serialize)]
522pub struct SwitchStmt<'arena, 'src> {
523 pub expr: Expr<'arena, 'src>,
524 pub cases: ArenaVec<'arena, SwitchCase<'arena, 'src>>,
525}
526
527#[derive(Debug, Serialize)]
528pub struct SwitchCase<'arena, 'src> {
529 pub value: Option<Expr<'arena, 'src>>,
530 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
531 pub span: Span,
532}
533
534#[derive(Debug, Serialize)]
535pub struct TryCatchStmt<'arena, 'src> {
536 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
537 pub catches: ArenaVec<'arena, CatchClause<'arena, 'src>>,
538 pub finally: Option<ArenaVec<'arena, Stmt<'arena, 'src>>>,
539}
540
541#[derive(Debug, Serialize)]
542pub struct CatchClause<'arena, 'src> {
543 pub types: ArenaVec<'arena, Name<'arena, 'src>>,
544 pub var: Option<&'src str>,
545 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
546 pub span: Span,
547}
548
549#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
554pub enum Visibility {
555 Public,
556 Protected,
557 Private,
558}
559
560#[derive(Debug, Serialize)]
561pub struct ClassDecl<'arena, 'src> {
562 pub name: Option<&'src str>,
563 pub modifiers: ClassModifiers,
564 pub extends: Option<Name<'arena, 'src>>,
565 pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
566 pub members: ArenaVec<'arena, ClassMember<'arena, 'src>>,
567 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
568}
569
570#[derive(Debug, Clone, Serialize, Default)]
571pub struct ClassModifiers {
572 pub is_abstract: bool,
573 pub is_final: bool,
574 pub is_readonly: bool,
575}
576
577#[derive(Debug, Serialize)]
578pub struct ClassMember<'arena, 'src> {
579 pub kind: ClassMemberKind<'arena, 'src>,
580 pub span: Span,
581}
582
583#[derive(Debug, Serialize)]
584pub enum ClassMemberKind<'arena, 'src> {
585 Property(PropertyDecl<'arena, 'src>),
586 Method(MethodDecl<'arena, 'src>),
587 ClassConst(ClassConstDecl<'arena, 'src>),
588 TraitUse(TraitUseDecl<'arena, 'src>),
589}
590
591#[derive(Debug, Serialize)]
592pub struct PropertyDecl<'arena, 'src> {
593 pub name: &'src str,
594 pub visibility: Option<Visibility>,
595 pub set_visibility: Option<Visibility>,
596 pub is_static: bool,
597 pub is_readonly: bool,
598 pub type_hint: Option<TypeHint<'arena, 'src>>,
599 pub default: Option<Expr<'arena, 'src>>,
600 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
601 #[serde(skip_serializing_if = "ArenaVec::is_empty")]
602 pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
603}
604
605#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
606pub enum PropertyHookKind {
607 Get,
608 Set,
609}
610
611#[derive(Debug, Serialize)]
612pub enum PropertyHookBody<'arena, 'src> {
613 Block(ArenaVec<'arena, Stmt<'arena, 'src>>),
614 Expression(Expr<'arena, 'src>),
615 Abstract,
616}
617
618#[derive(Debug, Serialize)]
619pub struct PropertyHook<'arena, 'src> {
620 pub kind: PropertyHookKind,
621 pub body: PropertyHookBody<'arena, 'src>,
622 pub is_final: bool,
623 pub by_ref: bool,
624 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
625 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
626 pub span: Span,
627}
628
629#[derive(Debug, Serialize)]
630pub struct MethodDecl<'arena, 'src> {
631 pub name: &'src str,
632 pub visibility: Option<Visibility>,
633 pub is_static: bool,
634 pub is_abstract: bool,
635 pub is_final: bool,
636 pub by_ref: bool,
637 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
638 pub return_type: Option<TypeHint<'arena, 'src>>,
639 pub body: Option<ArenaVec<'arena, Stmt<'arena, 'src>>>,
640 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
641}
642
643#[derive(Debug, Serialize)]
644pub struct ClassConstDecl<'arena, 'src> {
645 pub name: &'src str,
646 pub visibility: Option<Visibility>,
647 #[serde(skip_serializing_if = "Option::is_none")]
648 pub type_hint: Option<&'arena TypeHint<'arena, 'src>>,
649 pub value: Expr<'arena, 'src>,
650 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
651}
652
653#[derive(Debug, Serialize)]
654pub struct TraitUseDecl<'arena, 'src> {
655 pub traits: ArenaVec<'arena, Name<'arena, 'src>>,
656 pub adaptations: ArenaVec<'arena, TraitAdaptation<'arena, 'src>>,
657}
658
659#[derive(Debug, Serialize)]
660pub struct TraitAdaptation<'arena, 'src> {
661 pub kind: TraitAdaptationKind<'arena, 'src>,
662 pub span: Span,
663}
664
665#[derive(Debug, Serialize)]
666pub enum TraitAdaptationKind<'arena, 'src> {
667 Precedence {
669 trait_name: Name<'arena, 'src>,
670 method: &'src str,
671 insteadof: ArenaVec<'arena, Name<'arena, 'src>>,
672 },
673 Alias {
675 trait_name: Option<Name<'arena, 'src>>,
676 method: Cow<'src, str>,
677 new_modifier: Option<Visibility>,
678 new_name: Option<&'src str>,
679 },
680}
681
682#[derive(Debug, Serialize)]
683pub struct InterfaceDecl<'arena, 'src> {
684 pub name: &'src str,
685 pub extends: ArenaVec<'arena, Name<'arena, 'src>>,
686 pub members: ArenaVec<'arena, ClassMember<'arena, 'src>>,
687 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
688}
689
690#[derive(Debug, Serialize)]
691pub struct TraitDecl<'arena, 'src> {
692 pub name: &'src str,
693 pub members: ArenaVec<'arena, ClassMember<'arena, 'src>>,
694 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
695}
696
697#[derive(Debug, Serialize)]
698pub struct EnumDecl<'arena, 'src> {
699 pub name: &'src str,
700 pub scalar_type: Option<Name<'arena, 'src>>,
701 pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
702 pub members: ArenaVec<'arena, EnumMember<'arena, 'src>>,
703 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
704}
705
706#[derive(Debug, Serialize)]
707pub struct EnumMember<'arena, 'src> {
708 pub kind: EnumMemberKind<'arena, 'src>,
709 pub span: Span,
710}
711
712#[derive(Debug, Serialize)]
713pub enum EnumMemberKind<'arena, 'src> {
714 Case(EnumCase<'arena, 'src>),
715 Method(MethodDecl<'arena, 'src>),
716 ClassConst(ClassConstDecl<'arena, 'src>),
717 TraitUse(TraitUseDecl<'arena, 'src>),
718}
719
720#[derive(Debug, Serialize)]
721pub struct EnumCase<'arena, 'src> {
722 pub name: &'src str,
723 pub value: Option<Expr<'arena, 'src>>,
724 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
725}
726
727#[derive(Debug, Serialize)]
732pub struct NamespaceDecl<'arena, 'src> {
733 pub name: Option<Name<'arena, 'src>>,
734 pub body: NamespaceBody<'arena, 'src>,
735}
736
737#[derive(Debug, Serialize)]
738pub enum NamespaceBody<'arena, 'src> {
739 Braced(ArenaVec<'arena, Stmt<'arena, 'src>>),
740 Simple,
741}
742
743#[derive(Debug, Serialize)]
744pub struct DeclareStmt<'arena, 'src> {
745 pub directives: ArenaVec<'arena, (&'src str, Expr<'arena, 'src>)>,
746 pub body: Option<&'arena Stmt<'arena, 'src>>,
747}
748
749#[derive(Debug, Serialize)]
750pub struct UseDecl<'arena, 'src> {
751 pub kind: UseKind,
752 pub uses: ArenaVec<'arena, UseItem<'arena, 'src>>,
753}
754
755#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
756pub enum UseKind {
757 Normal,
758 Function,
759 Const,
760}
761
762#[derive(Debug, Serialize)]
763pub struct UseItem<'arena, 'src> {
764 pub name: Name<'arena, 'src>,
765 pub alias: Option<&'src str>,
766 #[serde(skip_serializing_if = "Option::is_none")]
767 pub kind: Option<UseKind>,
768 pub span: Span,
769}
770
771#[derive(Debug, Serialize)]
772pub struct ConstItem<'arena, 'src> {
773 pub name: &'src str,
774 pub value: Expr<'arena, 'src>,
775 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
776 pub span: Span,
777}
778
779#[derive(Debug, Serialize)]
780pub struct StaticVar<'arena, 'src> {
781 pub name: &'src str,
782 pub default: Option<Expr<'arena, 'src>>,
783 pub span: Span,
784}
785
786#[derive(Debug, Serialize)]
791pub struct Expr<'arena, 'src> {
792 pub kind: ExprKind<'arena, 'src>,
793 pub span: Span,
794}
795
796#[derive(Debug, Serialize)]
797pub enum ExprKind<'arena, 'src> {
798 Int(i64),
800
801 Float(f64),
803
804 String(Cow<'src, str>),
806
807 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
809
810 Heredoc {
812 label: &'src str,
813 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
814 },
815
816 Nowdoc {
818 label: &'src str,
819 value: Cow<'src, str>,
820 },
821
822 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
824
825 Bool(bool),
827
828 Null,
830
831 Variable(Cow<'src, str>),
833
834 VariableVariable(&'arena Expr<'arena, 'src>),
836
837 Identifier(Cow<'src, str>),
839
840 Assign(AssignExpr<'arena, 'src>),
842
843 Binary(BinaryExpr<'arena, 'src>),
845
846 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
848
849 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
851
852 Ternary(TernaryExpr<'arena, 'src>),
854
855 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
857
858 FunctionCall(FunctionCallExpr<'arena, 'src>),
860
861 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
863
864 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
866
867 Print(&'arena Expr<'arena, 'src>),
869
870 Parenthesized(&'arena Expr<'arena, 'src>),
872
873 Cast(CastKind, &'arena Expr<'arena, 'src>),
875
876 ErrorSuppress(&'arena Expr<'arena, 'src>),
878
879 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
881
882 Empty(&'arena Expr<'arena, 'src>),
884
885 Include(IncludeKind, &'arena Expr<'arena, 'src>),
887
888 Eval(&'arena Expr<'arena, 'src>),
890
891 Exit(Option<&'arena Expr<'arena, 'src>>),
893
894 MagicConst(MagicConstKind),
896
897 Clone(&'arena Expr<'arena, 'src>),
899
900 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
902
903 New(NewExpr<'arena, 'src>),
905
906 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
908
909 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
911
912 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
914
915 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
917
918 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
920
921 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
923
924 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
926
927 ClassConstAccessDynamic {
929 class: &'arena Expr<'arena, 'src>,
930 member: &'arena Expr<'arena, 'src>,
931 },
932
933 StaticPropertyAccessDynamic {
935 class: &'arena Expr<'arena, 'src>,
936 member: &'arena Expr<'arena, 'src>,
937 },
938
939 Closure(&'arena ClosureExpr<'arena, 'src>),
941
942 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
944
945 Match(MatchExpr<'arena, 'src>),
947
948 ThrowExpr(&'arena Expr<'arena, 'src>),
950
951 Yield(YieldExpr<'arena, 'src>),
953
954 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
956
957 CallableCreate(CallableCreateExpr<'arena, 'src>),
959
960 Error,
962}
963
964#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
965pub enum CastKind {
966 Int,
967 Float,
968 String,
969 Bool,
970 Array,
971 Object,
972 Unset,
973 Void,
974}
975
976#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
977pub enum IncludeKind {
978 Include,
979 IncludeOnce,
980 Require,
981 RequireOnce,
982}
983
984#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
985pub enum MagicConstKind {
986 Class,
987 Dir,
988 File,
989 Function,
990 Line,
991 Method,
992 Namespace,
993 Trait,
994 Property,
995}
996
997#[derive(Debug, Serialize)]
1000pub struct AssignExpr<'arena, 'src> {
1001 pub target: &'arena Expr<'arena, 'src>,
1002 pub op: AssignOp,
1003 pub value: &'arena Expr<'arena, 'src>,
1004}
1005
1006#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1007pub enum AssignOp {
1008 Assign,
1009 Plus,
1010 Minus,
1011 Mul,
1012 Div,
1013 Mod,
1014 Pow,
1015 Concat,
1016 BitwiseAnd,
1017 BitwiseOr,
1018 BitwiseXor,
1019 ShiftLeft,
1020 ShiftRight,
1021 Coalesce,
1022}
1023
1024#[derive(Debug, Serialize)]
1025pub struct BinaryExpr<'arena, 'src> {
1026 pub left: &'arena Expr<'arena, 'src>,
1027 pub op: BinaryOp,
1028 pub right: &'arena Expr<'arena, 'src>,
1029}
1030
1031#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1032pub enum BinaryOp {
1033 Add,
1034 Sub,
1035 Mul,
1036 Div,
1037 Mod,
1038 Pow,
1039 Concat,
1040 Equal,
1041 NotEqual,
1042 Identical,
1043 NotIdentical,
1044 Less,
1045 Greater,
1046 LessOrEqual,
1047 GreaterOrEqual,
1048 Spaceship,
1049 BooleanAnd,
1050 BooleanOr,
1051 BitwiseAnd,
1052 BitwiseOr,
1053 BitwiseXor,
1054 ShiftLeft,
1055 ShiftRight,
1056 LogicalAnd,
1057 LogicalOr,
1058 LogicalXor,
1059 Instanceof,
1060 Pipe,
1061}
1062
1063#[derive(Debug, Serialize)]
1064pub struct UnaryPrefixExpr<'arena, 'src> {
1065 pub op: UnaryPrefixOp,
1066 pub operand: &'arena Expr<'arena, 'src>,
1067}
1068
1069#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1070pub enum UnaryPrefixOp {
1071 Negate,
1072 Plus,
1073 BooleanNot,
1074 BitwiseNot,
1075 PreIncrement,
1076 PreDecrement,
1077}
1078
1079#[derive(Debug, Serialize)]
1080pub struct UnaryPostfixExpr<'arena, 'src> {
1081 pub operand: &'arena Expr<'arena, 'src>,
1082 pub op: UnaryPostfixOp,
1083}
1084
1085#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1086pub enum UnaryPostfixOp {
1087 PostIncrement,
1088 PostDecrement,
1089}
1090
1091#[derive(Debug, Serialize)]
1092pub struct TernaryExpr<'arena, 'src> {
1093 pub condition: &'arena Expr<'arena, 'src>,
1094 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
1096 pub else_expr: &'arena Expr<'arena, 'src>,
1097}
1098
1099#[derive(Debug, Serialize)]
1100pub struct NullCoalesceExpr<'arena, 'src> {
1101 pub left: &'arena Expr<'arena, 'src>,
1102 pub right: &'arena Expr<'arena, 'src>,
1103}
1104
1105#[derive(Debug, Serialize)]
1106pub struct FunctionCallExpr<'arena, 'src> {
1107 pub name: &'arena Expr<'arena, 'src>,
1108 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1109}
1110
1111#[derive(Debug, Serialize)]
1112pub struct ArrayElement<'arena, 'src> {
1113 pub key: Option<Expr<'arena, 'src>>,
1114 pub value: Expr<'arena, 'src>,
1115 pub unpack: bool,
1116 pub span: Span,
1117}
1118
1119#[derive(Debug, Serialize)]
1120pub struct ArrayAccessExpr<'arena, 'src> {
1121 pub array: &'arena Expr<'arena, 'src>,
1122 pub index: Option<&'arena Expr<'arena, 'src>>,
1123}
1124
1125#[derive(Debug, Serialize)]
1128pub struct NewExpr<'arena, 'src> {
1129 pub class: &'arena Expr<'arena, 'src>,
1130 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1131}
1132
1133#[derive(Debug, Serialize)]
1134pub struct PropertyAccessExpr<'arena, 'src> {
1135 pub object: &'arena Expr<'arena, 'src>,
1136 pub property: &'arena Expr<'arena, 'src>,
1137}
1138
1139#[derive(Debug, Serialize)]
1140pub struct MethodCallExpr<'arena, 'src> {
1141 pub object: &'arena Expr<'arena, 'src>,
1142 pub method: &'arena Expr<'arena, 'src>,
1143 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1144}
1145
1146#[derive(Debug, Serialize)]
1147pub struct StaticAccessExpr<'arena, 'src> {
1148 pub class: &'arena Expr<'arena, 'src>,
1149 pub member: Cow<'src, str>,
1150}
1151
1152#[derive(Debug, Serialize)]
1153pub struct StaticMethodCallExpr<'arena, 'src> {
1154 pub class: &'arena Expr<'arena, 'src>,
1155 pub method: Cow<'src, str>,
1156 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1157}
1158
1159#[derive(Debug, Serialize)]
1160pub struct ClosureExpr<'arena, 'src> {
1161 pub is_static: bool,
1162 pub by_ref: bool,
1163 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
1164 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
1165 pub return_type: Option<TypeHint<'arena, 'src>>,
1166 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
1167 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
1168}
1169
1170#[derive(Debug, Clone, Serialize)]
1171pub struct ClosureUseVar<'src> {
1172 pub name: &'src str,
1173 pub by_ref: bool,
1174 pub span: Span,
1175}
1176
1177#[derive(Debug, Serialize)]
1178pub struct ArrowFunctionExpr<'arena, 'src> {
1179 pub is_static: bool,
1180 pub by_ref: bool,
1181 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
1182 pub return_type: Option<TypeHint<'arena, 'src>>,
1183 pub body: &'arena Expr<'arena, 'src>,
1184 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
1185}
1186
1187#[derive(Debug, Serialize)]
1188pub struct MatchExpr<'arena, 'src> {
1189 pub subject: &'arena Expr<'arena, 'src>,
1190 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
1191}
1192
1193#[derive(Debug, Serialize)]
1194pub struct MatchArm<'arena, 'src> {
1195 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
1197 pub body: Expr<'arena, 'src>,
1198 pub span: Span,
1199}
1200
1201#[derive(Debug, Serialize)]
1202pub struct YieldExpr<'arena, 'src> {
1203 pub key: Option<&'arena Expr<'arena, 'src>>,
1204 pub value: Option<&'arena Expr<'arena, 'src>>,
1205}
1206
1207#[derive(Debug, Serialize)]
1210pub struct CallableCreateExpr<'arena, 'src> {
1211 pub kind: CallableCreateKind<'arena, 'src>,
1212}
1213
1214#[derive(Debug, Serialize)]
1215pub enum CallableCreateKind<'arena, 'src> {
1216 Function(&'arena Expr<'arena, 'src>),
1218 Method {
1220 object: &'arena Expr<'arena, 'src>,
1221 method: &'arena Expr<'arena, 'src>,
1222 },
1223 NullsafeMethod {
1225 object: &'arena Expr<'arena, 'src>,
1226 method: &'arena Expr<'arena, 'src>,
1227 },
1228 StaticMethod {
1230 class: &'arena Expr<'arena, 'src>,
1231 method: Cow<'src, str>,
1232 },
1233}
1234
1235#[derive(Debug, Serialize)]
1238pub enum StringPart<'arena, 'src> {
1239 Literal(Cow<'src, str>),
1240 Expr(Expr<'arena, 'src>),
1241}