1#[cfg(feature = "serde")]
2use serde::Serialize;
3
4use crate::Span;
5
6#[cfg(feature = "serde")]
7use super::is_false;
8use super::{ArenaVec, Arg, Attribute, Block, ByteStr, ClassDecl, Ident, Name, Param, TypeHint};
9
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11enum NameStrInner<'arena, 'src> {
12 Src(&'src str),
13 Arena(&'arena str),
14}
15
16#[derive(Clone, Copy, PartialEq, Eq, Hash)]
34pub struct NameStr<'arena, 'src>(NameStrInner<'arena, 'src>);
35
36impl<'arena, 'src> NameStr<'arena, 'src> {
37 pub fn new_in(arena: &'arena bumpalo::Bump, s: &str) -> Self {
39 Self(NameStrInner::Arena(arena.alloc_str(s)))
40 }
41
42 #[inline]
44 pub fn from_source(s: &'src str) -> Self {
45 Self(NameStrInner::Src(s))
46 }
47
48 #[inline]
50 pub fn from_arena(s: &'arena str) -> Self {
51 Self(NameStrInner::Arena(s))
52 }
53
54 #[inline]
55 pub(crate) fn into_src_str(self) -> Option<&'src str> {
56 match self.0 {
57 NameStrInner::Src(s) => Some(s),
58 NameStrInner::Arena(_) => None,
59 }
60 }
61
62 #[inline]
64 pub fn as_str(&self) -> &str {
65 match self.0 {
66 NameStrInner::Src(s) | NameStrInner::Arena(s) => s,
67 }
68 }
69}
70
71impl<'arena, 'src> std::ops::Deref for NameStr<'arena, 'src> {
72 type Target = str;
73 #[inline]
74 fn deref(&self) -> &str {
75 self.as_str()
76 }
77}
78
79impl<'arena, 'src> std::fmt::Debug for NameStr<'arena, 'src> {
80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 self.as_str().fmt(f)
82 }
83}
84
85#[cfg(feature = "serde")]
86impl<'arena, 'src> serde::Serialize for NameStr<'arena, 'src> {
87 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
88 self.as_str().serialize(serializer)
89 }
90}
91
92#[derive(Debug)]
94#[cfg_attr(feature = "serde", derive(Serialize))]
95pub struct Expr<'arena, 'src> {
96 pub kind: ExprKind<'arena, 'src>,
98 pub span: Span,
100}
101
102#[derive(Debug)]
104#[cfg_attr(feature = "serde", derive(Serialize))]
105#[non_exhaustive]
106pub enum ExprKind<'arena, 'src> {
107 Int(i64),
109
110 Float(f64),
112
113 String(ByteStr<'arena, 'src>),
116
117 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
119
120 Heredoc {
122 label: &'src str,
124 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
126 },
127
128 Nowdoc {
130 label: &'src str,
132 value: &'arena str,
134 },
135
136 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
138
139 Bool(bool),
141
142 Null,
144
145 Variable(NameStr<'arena, 'src>),
147
148 VariableVariable(&'arena Expr<'arena, 'src>),
150
151 Identifier(NameStr<'arena, 'src>),
153
154 Name(Name<'arena, 'src>),
157
158 Assign(AssignExpr<'arena, 'src>),
160
161 Binary(BinaryExpr<'arena, 'src>),
163
164 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
166
167 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
169
170 Ternary(TernaryExpr<'arena, 'src>),
172
173 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
175
176 FunctionCall(FunctionCallExpr<'arena, 'src>),
178
179 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
181
182 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
184
185 Print(&'arena Expr<'arena, 'src>),
187
188 Parenthesized(&'arena Expr<'arena, 'src>),
190
191 Cast(CastKind, &'arena Expr<'arena, 'src>),
193
194 ErrorSuppress(&'arena Expr<'arena, 'src>),
196
197 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
199
200 Empty(&'arena Expr<'arena, 'src>),
202
203 Include(IncludeKind, &'arena Expr<'arena, 'src>),
205
206 Eval(&'arena Expr<'arena, 'src>),
208
209 Exit(Option<&'arena Expr<'arena, 'src>>),
211
212 MagicConst(MagicConstKind),
214
215 Clone(&'arena Expr<'arena, 'src>),
217
218 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
220
221 New(NewExpr<'arena, 'src>),
223
224 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
226
227 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
229
230 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
232
233 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
235
236 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
238
239 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
241
242 StaticMethodCallDynamic(&'arena StaticMethodCallDynamicExpr<'arena, 'src>),
244
245 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
247
248 ClassConstAccessDynamic {
250 class: &'arena Expr<'arena, 'src>,
252 member: &'arena Expr<'arena, 'src>,
254 },
255
256 StaticPropertyAccessDynamic {
258 class: &'arena Expr<'arena, 'src>,
260 member: &'arena Expr<'arena, 'src>,
262 },
263
264 Closure(&'arena ClosureExpr<'arena, 'src>),
266
267 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
269
270 Match(MatchExpr<'arena, 'src>),
272
273 Throw(&'arena Expr<'arena, 'src>),
275
276 Yield(YieldExpr<'arena, 'src>),
278
279 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
281
282 CallableCreate(CallableCreateExpr<'arena, 'src>),
284
285 Omit,
287
288 Error,
290}
291
292impl<'arena, 'src> Expr<'arena, 'src> {
293 pub fn name_str(&self) -> Option<&str> {
295 match &self.kind {
296 ExprKind::Variable(s) | ExprKind::Identifier(s) => Some(s.as_str()),
297 _ => None,
298 }
299 }
300}
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq)]
304#[cfg_attr(feature = "serde", derive(Serialize))]
305#[non_exhaustive]
306pub enum CastKind {
307 Int,
309 Float,
311 String,
313 Bool,
315 Array,
317 Object,
319 Unset,
321 Void,
323}
324
325#[derive(Debug, Clone, Copy, PartialEq, Eq)]
327#[cfg_attr(feature = "serde", derive(Serialize))]
328#[non_exhaustive]
329pub enum IncludeKind {
330 Include,
332 IncludeOnce,
334 Require,
336 RequireOnce,
338}
339
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
342#[cfg_attr(feature = "serde", derive(Serialize))]
343#[non_exhaustive]
344pub enum MagicConstKind {
345 Class,
347 Dir,
349 File,
351 Function,
353 Line,
355 Method,
357 Namespace,
359 Trait,
361 Property,
363}
364
365#[derive(Debug)]
369#[cfg_attr(feature = "serde", derive(Serialize))]
370pub struct AssignExpr<'arena, 'src> {
371 pub target: &'arena Expr<'arena, 'src>,
373 pub op: AssignOp,
375 pub value: &'arena Expr<'arena, 'src>,
377 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "is_false"))]
379 pub by_ref: bool,
380}
381
382#[derive(Debug, Clone, Copy, PartialEq, Eq)]
384#[cfg_attr(feature = "serde", derive(Serialize))]
385#[non_exhaustive]
386pub enum AssignOp {
387 Assign,
389 Plus,
391 Minus,
393 Mul,
395 Div,
397 Mod,
399 Pow,
401 Concat,
403 BitwiseAnd,
405 BitwiseOr,
407 BitwiseXor,
409 ShiftLeft,
411 ShiftRight,
413 Coalesce,
415}
416
417#[derive(Debug)]
419#[cfg_attr(feature = "serde", derive(Serialize))]
420pub struct BinaryExpr<'arena, 'src> {
421 pub left: &'arena Expr<'arena, 'src>,
423 pub op: BinaryOp,
425 pub right: &'arena Expr<'arena, 'src>,
427}
428
429#[derive(Debug, Clone, Copy, PartialEq, Eq)]
431#[cfg_attr(feature = "serde", derive(Serialize))]
432#[non_exhaustive]
433pub enum BinaryOp {
434 Add,
436 Sub,
438 Mul,
440 Div,
442 Mod,
444 Pow,
446 Concat,
448 Equal,
450 NotEqual,
452 Identical,
454 NotIdentical,
456 Less,
458 Greater,
460 LessOrEqual,
462 GreaterOrEqual,
464 Spaceship,
466 BooleanAnd,
468 BooleanOr,
470 BitwiseAnd,
472 BitwiseOr,
474 BitwiseXor,
476 ShiftLeft,
478 ShiftRight,
480 LogicalAnd,
482 LogicalOr,
484 LogicalXor,
486 Instanceof,
488 Pipe,
490}
491
492#[derive(Debug)]
494#[cfg_attr(feature = "serde", derive(Serialize))]
495pub struct UnaryPrefixExpr<'arena, 'src> {
496 pub op: UnaryPrefixOp,
498 pub operand: &'arena Expr<'arena, 'src>,
500}
501
502#[derive(Debug, Clone, Copy, PartialEq, Eq)]
504#[cfg_attr(feature = "serde", derive(Serialize))]
505#[non_exhaustive]
506pub enum UnaryPrefixOp {
507 Negate,
509 Plus,
511 BooleanNot,
513 BitwiseNot,
515 PreIncrement,
517 PreDecrement,
519}
520
521#[derive(Debug)]
523#[cfg_attr(feature = "serde", derive(Serialize))]
524pub struct UnaryPostfixExpr<'arena, 'src> {
525 pub operand: &'arena Expr<'arena, 'src>,
527 pub op: UnaryPostfixOp,
529}
530
531#[derive(Debug, Clone, Copy, PartialEq, Eq)]
533#[cfg_attr(feature = "serde", derive(Serialize))]
534#[non_exhaustive]
535pub enum UnaryPostfixOp {
536 PostIncrement,
538 PostDecrement,
540}
541
542#[derive(Debug)]
544#[cfg_attr(feature = "serde", derive(Serialize))]
545pub struct TernaryExpr<'arena, 'src> {
546 pub condition: &'arena Expr<'arena, 'src>,
548 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
550 pub else_expr: &'arena Expr<'arena, 'src>,
552}
553
554#[derive(Debug)]
556#[cfg_attr(feature = "serde", derive(Serialize))]
557pub struct NullCoalesceExpr<'arena, 'src> {
558 pub left: &'arena Expr<'arena, 'src>,
560 pub right: &'arena Expr<'arena, 'src>,
562}
563
564#[derive(Debug)]
566#[cfg_attr(feature = "serde", derive(Serialize))]
567pub struct FunctionCallExpr<'arena, 'src> {
568 pub name: &'arena Expr<'arena, 'src>,
570 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
572}
573
574#[derive(Debug)]
576#[cfg_attr(feature = "serde", derive(Serialize))]
577pub struct ArrayElement<'arena, 'src> {
578 pub key: Option<Expr<'arena, 'src>>,
580 pub kind: ArrayElementKind<'arena, 'src>,
582 pub span: Span,
584}
585
586#[derive(Debug)]
588#[cfg_attr(feature = "serde", derive(Serialize))]
589#[non_exhaustive]
590pub enum ArrayElementKind<'arena, 'src> {
591 Value(Expr<'arena, 'src>),
593 Spread(Expr<'arena, 'src>),
595 ByRef(Expr<'arena, 'src>),
597}
598
599impl<'arena, 'src> ArrayElement<'arena, 'src> {
600 pub fn value(&self) -> &Expr<'arena, 'src> {
602 match &self.kind {
603 ArrayElementKind::Value(e)
604 | ArrayElementKind::Spread(e)
605 | ArrayElementKind::ByRef(e) => e,
606 }
607 }
608
609 pub fn value_mut(&mut self) -> &mut Expr<'arena, 'src> {
611 match &mut self.kind {
612 ArrayElementKind::Value(e)
613 | ArrayElementKind::Spread(e)
614 | ArrayElementKind::ByRef(e) => e,
615 }
616 }
617
618 pub fn is_spread(&self) -> bool {
620 matches!(self.kind, ArrayElementKind::Spread(_))
621 }
622
623 pub fn is_by_ref(&self) -> bool {
625 matches!(self.kind, ArrayElementKind::ByRef(_))
626 }
627}
628
629#[derive(Debug)]
631#[cfg_attr(feature = "serde", derive(Serialize))]
632pub struct ArrayAccessExpr<'arena, 'src> {
633 pub array: &'arena Expr<'arena, 'src>,
635 pub index: Option<&'arena Expr<'arena, 'src>>,
637}
638
639#[derive(Debug)]
643#[cfg_attr(feature = "serde", derive(Serialize))]
644pub struct NewExpr<'arena, 'src> {
645 pub class: &'arena Expr<'arena, 'src>,
647 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
649}
650
651#[derive(Debug)]
653#[cfg_attr(feature = "serde", derive(Serialize))]
654pub struct PropertyAccessExpr<'arena, 'src> {
655 pub object: &'arena Expr<'arena, 'src>,
657 pub property: &'arena Expr<'arena, 'src>,
659}
660
661#[derive(Debug)]
663#[cfg_attr(feature = "serde", derive(Serialize))]
664pub struct MethodCallExpr<'arena, 'src> {
665 pub object: &'arena Expr<'arena, 'src>,
667 pub method: &'arena Expr<'arena, 'src>,
669 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
671}
672
673#[derive(Debug)]
675#[cfg_attr(feature = "serde", derive(Serialize))]
676pub struct StaticAccessExpr<'arena, 'src> {
677 pub class: &'arena Expr<'arena, 'src>,
679 pub member: &'arena Expr<'arena, 'src>,
681}
682
683#[derive(Debug)]
685#[cfg_attr(feature = "serde", derive(Serialize))]
686pub struct StaticMethodCallExpr<'arena, 'src> {
687 pub class: &'arena Expr<'arena, 'src>,
689 pub method: &'arena Expr<'arena, 'src>,
691 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
693}
694
695#[derive(Debug)]
697#[cfg_attr(feature = "serde", derive(Serialize))]
698pub struct StaticMethodCallDynamicExpr<'arena, 'src> {
699 pub class: &'arena Expr<'arena, 'src>,
701 pub method: &'arena Expr<'arena, 'src>,
703 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
705}
706
707#[derive(Debug)]
709#[cfg_attr(feature = "serde", derive(Serialize))]
710#[non_exhaustive]
711pub struct ClosureExpr<'arena, 'src> {
712 pub is_static: bool,
714 pub by_ref: bool,
716 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
718 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
720 pub return_type: Option<TypeHint<'arena, 'src>>,
722 pub body: &'arena Block<'arena, 'src>,
724 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
726}
727
728impl<'arena, 'src> ClosureExpr<'arena, 'src> {
729 pub fn new(arena: &'arena bumpalo::Bump, body: &'arena Block<'arena, 'src>) -> Self {
732 Self {
733 is_static: false,
734 by_ref: false,
735 params: ArenaVec::new_in(arena),
736 use_vars: ArenaVec::new_in(arena),
737 return_type: None,
738 body,
739 attributes: ArenaVec::new_in(arena),
740 }
741 }
742}
743
744#[derive(Debug, Clone)]
746#[cfg_attr(feature = "serde", derive(Serialize))]
747pub struct ClosureUseVar<'src> {
748 pub name: Ident<'src>,
750 pub by_ref: bool,
752 pub span: Span,
754}
755
756#[derive(Debug)]
758#[cfg_attr(feature = "serde", derive(Serialize))]
759#[non_exhaustive]
760pub struct ArrowFunctionExpr<'arena, 'src> {
761 pub is_static: bool,
763 pub by_ref: bool,
765 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
767 pub return_type: Option<TypeHint<'arena, 'src>>,
769 pub body: &'arena Expr<'arena, 'src>,
771 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
773}
774
775impl<'arena, 'src> ArrowFunctionExpr<'arena, 'src> {
776 pub fn new(arena: &'arena bumpalo::Bump, body: &'arena Expr<'arena, 'src>) -> Self {
779 Self {
780 is_static: false,
781 by_ref: false,
782 params: ArenaVec::new_in(arena),
783 return_type: None,
784 body,
785 attributes: ArenaVec::new_in(arena),
786 }
787 }
788}
789
790#[derive(Debug)]
792#[cfg_attr(feature = "serde", derive(Serialize))]
793#[non_exhaustive]
794pub struct MatchExpr<'arena, 'src> {
795 pub subject: &'arena Expr<'arena, 'src>,
797 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
799 #[cfg_attr(feature = "serde", serde(skip))]
801 #[doc(hidden)]
802 pub brace_span: Span,
803}
804
805impl<'arena, 'src> MatchExpr<'arena, 'src> {
806 pub fn new(
809 subject: &'arena Expr<'arena, 'src>,
810 arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
811 brace_span: Span,
812 ) -> Self {
813 Self {
814 subject,
815 arms,
816 brace_span,
817 }
818 }
819}
820
821#[derive(Debug)]
823#[cfg_attr(feature = "serde", derive(Serialize))]
824pub struct MatchArm<'arena, 'src> {
825 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
827 pub body: Expr<'arena, 'src>,
829 pub span: Span,
831}
832
833#[derive(Debug)]
835#[cfg_attr(feature = "serde", derive(Serialize))]
836pub struct YieldExpr<'arena, 'src> {
837 pub key: Option<&'arena Expr<'arena, 'src>>,
839 pub value: Option<&'arena Expr<'arena, 'src>>,
841 pub is_from: bool,
843}
844
845#[derive(Debug)]
849#[cfg_attr(feature = "serde", derive(Serialize))]
850pub struct CallableCreateExpr<'arena, 'src> {
851 pub kind: CallableCreateKind<'arena, 'src>,
853}
854
855#[derive(Debug)]
857#[cfg_attr(feature = "serde", derive(Serialize))]
858#[non_exhaustive]
859pub enum CallableCreateKind<'arena, 'src> {
860 Function(&'arena Expr<'arena, 'src>),
862 Method {
864 object: &'arena Expr<'arena, 'src>,
866 method: &'arena Expr<'arena, 'src>,
868 },
869 NullsafeMethod {
871 object: &'arena Expr<'arena, 'src>,
873 method: &'arena Expr<'arena, 'src>,
875 },
876 StaticMethod {
878 class: &'arena Expr<'arena, 'src>,
880 method: &'arena Expr<'arena, 'src>,
882 },
883}
884
885#[derive(Debug)]
889#[cfg_attr(feature = "serde", derive(Serialize))]
890#[non_exhaustive]
891pub enum StringPart<'arena, 'src> {
892 Literal(ByteStr<'arena, 'src>),
894 Expr(Expr<'arena, 'src>),
896}