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