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 span: Span,
776}
777
778#[derive(Debug, Serialize)]
779pub struct StaticVar<'arena, 'src> {
780 pub name: &'src str,
781 pub default: Option<Expr<'arena, 'src>>,
782 pub span: Span,
783}
784
785#[derive(Debug, Serialize)]
790pub struct Expr<'arena, 'src> {
791 pub kind: ExprKind<'arena, 'src>,
792 pub span: Span,
793}
794
795#[derive(Debug, Serialize)]
796pub enum ExprKind<'arena, 'src> {
797 Int(i64),
799
800 Float(f64),
802
803 String(Cow<'src, str>),
805
806 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
808
809 Heredoc {
811 label: &'src str,
812 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
813 },
814
815 Nowdoc {
817 label: &'src str,
818 value: Cow<'src, str>,
819 },
820
821 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
823
824 Bool(bool),
826
827 Null,
829
830 Variable(Cow<'src, str>),
832
833 VariableVariable(&'arena Expr<'arena, 'src>),
835
836 Identifier(Cow<'src, str>),
838
839 Assign(AssignExpr<'arena, 'src>),
841
842 Binary(BinaryExpr<'arena, 'src>),
844
845 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
847
848 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
850
851 Ternary(TernaryExpr<'arena, 'src>),
853
854 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
856
857 FunctionCall(FunctionCallExpr<'arena, 'src>),
859
860 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
862
863 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
865
866 Print(&'arena Expr<'arena, 'src>),
868
869 Parenthesized(&'arena Expr<'arena, 'src>),
871
872 Cast(CastKind, &'arena Expr<'arena, 'src>),
874
875 ErrorSuppress(&'arena Expr<'arena, 'src>),
877
878 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
880
881 Empty(&'arena Expr<'arena, 'src>),
883
884 Include(IncludeKind, &'arena Expr<'arena, 'src>),
886
887 Eval(&'arena Expr<'arena, 'src>),
889
890 Exit(Option<&'arena Expr<'arena, 'src>>),
892
893 MagicConst(MagicConstKind),
895
896 Clone(&'arena Expr<'arena, 'src>),
898
899 New(NewExpr<'arena, 'src>),
901
902 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
904
905 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
907
908 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
910
911 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
913
914 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
916
917 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
919
920 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
922
923 ClassConstAccessDynamic {
925 class: &'arena Expr<'arena, 'src>,
926 member: &'arena Expr<'arena, 'src>,
927 },
928
929 StaticPropertyAccessDynamic {
931 class: &'arena Expr<'arena, 'src>,
932 member: &'arena Expr<'arena, 'src>,
933 },
934
935 Closure(&'arena ClosureExpr<'arena, 'src>),
937
938 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
940
941 Match(MatchExpr<'arena, 'src>),
943
944 ThrowExpr(&'arena Expr<'arena, 'src>),
946
947 Yield(YieldExpr<'arena, 'src>),
949
950 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
952
953 CallableCreate(CallableCreateExpr<'arena, 'src>),
955
956 Error,
958}
959
960#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
961pub enum CastKind {
962 Int,
963 Float,
964 String,
965 Bool,
966 Array,
967 Object,
968 Unset,
969 Void,
970}
971
972#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
973pub enum IncludeKind {
974 Include,
975 IncludeOnce,
976 Require,
977 RequireOnce,
978}
979
980#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
981pub enum MagicConstKind {
982 Class,
983 Dir,
984 File,
985 Function,
986 Line,
987 Method,
988 Namespace,
989 Trait,
990 Property,
991}
992
993#[derive(Debug, Serialize)]
996pub struct AssignExpr<'arena, 'src> {
997 pub target: &'arena Expr<'arena, 'src>,
998 pub op: AssignOp,
999 pub value: &'arena Expr<'arena, 'src>,
1000}
1001
1002#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1003pub enum AssignOp {
1004 Assign,
1005 Plus,
1006 Minus,
1007 Mul,
1008 Div,
1009 Mod,
1010 Pow,
1011 Concat,
1012 BitwiseAnd,
1013 BitwiseOr,
1014 BitwiseXor,
1015 ShiftLeft,
1016 ShiftRight,
1017 Coalesce,
1018}
1019
1020#[derive(Debug, Serialize)]
1021pub struct BinaryExpr<'arena, 'src> {
1022 pub left: &'arena Expr<'arena, 'src>,
1023 pub op: BinaryOp,
1024 pub right: &'arena Expr<'arena, 'src>,
1025}
1026
1027#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1028pub enum BinaryOp {
1029 Add,
1030 Sub,
1031 Mul,
1032 Div,
1033 Mod,
1034 Pow,
1035 Concat,
1036 Equal,
1037 NotEqual,
1038 Identical,
1039 NotIdentical,
1040 Less,
1041 Greater,
1042 LessOrEqual,
1043 GreaterOrEqual,
1044 Spaceship,
1045 BooleanAnd,
1046 BooleanOr,
1047 BitwiseAnd,
1048 BitwiseOr,
1049 BitwiseXor,
1050 ShiftLeft,
1051 ShiftRight,
1052 LogicalAnd,
1053 LogicalOr,
1054 LogicalXor,
1055 Instanceof,
1056 Pipe,
1057}
1058
1059#[derive(Debug, Serialize)]
1060pub struct UnaryPrefixExpr<'arena, 'src> {
1061 pub op: UnaryPrefixOp,
1062 pub operand: &'arena Expr<'arena, 'src>,
1063}
1064
1065#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1066pub enum UnaryPrefixOp {
1067 Negate,
1068 Plus,
1069 BooleanNot,
1070 BitwiseNot,
1071 PreIncrement,
1072 PreDecrement,
1073}
1074
1075#[derive(Debug, Serialize)]
1076pub struct UnaryPostfixExpr<'arena, 'src> {
1077 pub operand: &'arena Expr<'arena, 'src>,
1078 pub op: UnaryPostfixOp,
1079}
1080
1081#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1082pub enum UnaryPostfixOp {
1083 PostIncrement,
1084 PostDecrement,
1085}
1086
1087#[derive(Debug, Serialize)]
1088pub struct TernaryExpr<'arena, 'src> {
1089 pub condition: &'arena Expr<'arena, 'src>,
1090 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
1092 pub else_expr: &'arena Expr<'arena, 'src>,
1093}
1094
1095#[derive(Debug, Serialize)]
1096pub struct NullCoalesceExpr<'arena, 'src> {
1097 pub left: &'arena Expr<'arena, 'src>,
1098 pub right: &'arena Expr<'arena, 'src>,
1099}
1100
1101#[derive(Debug, Serialize)]
1102pub struct FunctionCallExpr<'arena, 'src> {
1103 pub name: &'arena Expr<'arena, 'src>,
1104 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1105}
1106
1107#[derive(Debug, Serialize)]
1108pub struct ArrayElement<'arena, 'src> {
1109 pub key: Option<Expr<'arena, 'src>>,
1110 pub value: Expr<'arena, 'src>,
1111 pub unpack: bool,
1112 pub span: Span,
1113}
1114
1115#[derive(Debug, Serialize)]
1116pub struct ArrayAccessExpr<'arena, 'src> {
1117 pub array: &'arena Expr<'arena, 'src>,
1118 pub index: Option<&'arena Expr<'arena, 'src>>,
1119}
1120
1121#[derive(Debug, Serialize)]
1124pub struct NewExpr<'arena, 'src> {
1125 pub class: &'arena Expr<'arena, 'src>,
1126 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1127}
1128
1129#[derive(Debug, Serialize)]
1130pub struct PropertyAccessExpr<'arena, 'src> {
1131 pub object: &'arena Expr<'arena, 'src>,
1132 pub property: &'arena Expr<'arena, 'src>,
1133}
1134
1135#[derive(Debug, Serialize)]
1136pub struct MethodCallExpr<'arena, 'src> {
1137 pub object: &'arena Expr<'arena, 'src>,
1138 pub method: &'arena Expr<'arena, 'src>,
1139 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1140}
1141
1142#[derive(Debug, Serialize)]
1143pub struct StaticAccessExpr<'arena, 'src> {
1144 pub class: &'arena Expr<'arena, 'src>,
1145 pub member: Cow<'src, str>,
1146}
1147
1148#[derive(Debug, Serialize)]
1149pub struct StaticMethodCallExpr<'arena, 'src> {
1150 pub class: &'arena Expr<'arena, 'src>,
1151 pub method: Cow<'src, str>,
1152 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
1153}
1154
1155#[derive(Debug, Serialize)]
1156pub struct ClosureExpr<'arena, 'src> {
1157 pub is_static: bool,
1158 pub by_ref: bool,
1159 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
1160 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
1161 pub return_type: Option<TypeHint<'arena, 'src>>,
1162 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
1163 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
1164}
1165
1166#[derive(Debug, Clone, Serialize)]
1167pub struct ClosureUseVar<'src> {
1168 pub name: &'src str,
1169 pub by_ref: bool,
1170 pub span: Span,
1171}
1172
1173#[derive(Debug, Serialize)]
1174pub struct ArrowFunctionExpr<'arena, 'src> {
1175 pub is_static: bool,
1176 pub by_ref: bool,
1177 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
1178 pub return_type: Option<TypeHint<'arena, 'src>>,
1179 pub body: &'arena Expr<'arena, 'src>,
1180 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
1181}
1182
1183#[derive(Debug, Serialize)]
1184pub struct MatchExpr<'arena, 'src> {
1185 pub subject: &'arena Expr<'arena, 'src>,
1186 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
1187}
1188
1189#[derive(Debug, Serialize)]
1190pub struct MatchArm<'arena, 'src> {
1191 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
1193 pub body: Expr<'arena, 'src>,
1194 pub span: Span,
1195}
1196
1197#[derive(Debug, Serialize)]
1198pub struct YieldExpr<'arena, 'src> {
1199 pub key: Option<&'arena Expr<'arena, 'src>>,
1200 pub value: Option<&'arena Expr<'arena, 'src>>,
1201}
1202
1203#[derive(Debug, Serialize)]
1206pub struct CallableCreateExpr<'arena, 'src> {
1207 pub kind: CallableCreateKind<'arena, 'src>,
1208}
1209
1210#[derive(Debug, Serialize)]
1211pub enum CallableCreateKind<'arena, 'src> {
1212 Function(&'arena Expr<'arena, 'src>),
1214 Method {
1216 object: &'arena Expr<'arena, 'src>,
1217 method: &'arena Expr<'arena, 'src>,
1218 },
1219 NullsafeMethod {
1221 object: &'arena Expr<'arena, 'src>,
1222 method: &'arena Expr<'arena, 'src>,
1223 },
1224 StaticMethod {
1226 class: &'arena Expr<'arena, 'src>,
1227 method: Cow<'src, str>,
1228 },
1229}
1230
1231#[derive(Debug, Serialize)]
1234pub enum StringPart<'arena, 'src> {
1235 Literal(Cow<'src, str>),
1236 Expr(Expr<'arena, 'src>),
1237}