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, ClassDecl, 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)]
35pub struct NameStr<'arena, 'src>(NameStrInner<'arena, 'src>);
36
37impl<'arena, 'src> NameStr<'arena, 'src> {
38 pub fn new_in(arena: &'arena bumpalo::Bump, s: &str) -> Self {
40 Self(NameStrInner::Arena(arena.alloc_str(s)))
41 }
42
43 #[doc(hidden)]
45 #[inline]
46 pub fn __src(s: &'src str) -> Self {
47 Self(NameStrInner::Src(s))
48 }
49
50 #[doc(hidden)]
52 #[inline]
53 pub fn __arena(s: &'arena str) -> Self {
54 Self(NameStrInner::Arena(s))
55 }
56
57 #[doc(hidden)]
60 #[inline]
61 pub fn __into_arena_str(self) -> Option<&'arena str> {
62 match self.0 {
63 NameStrInner::Arena(s) => Some(s),
64 NameStrInner::Src(_) => None,
65 }
66 }
67
68 #[doc(hidden)]
71 #[inline]
72 pub fn __into_src_str(self) -> Option<&'src str> {
73 match self.0 {
74 NameStrInner::Src(s) => Some(s),
75 NameStrInner::Arena(_) => None,
76 }
77 }
78
79 #[inline]
81 pub fn as_str(&self) -> &str {
82 match self.0 {
83 NameStrInner::Src(s) | NameStrInner::Arena(s) => s,
84 }
85 }
86}
87
88impl<'arena, 'src> std::ops::Deref for NameStr<'arena, 'src> {
89 type Target = str;
90 #[inline]
91 fn deref(&self) -> &str {
92 self.as_str()
93 }
94}
95
96impl<'arena, 'src> std::fmt::Debug for NameStr<'arena, 'src> {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 self.as_str().fmt(f)
99 }
100}
101
102#[cfg(feature = "serde")]
103impl<'arena, 'src> serde::Serialize for NameStr<'arena, 'src> {
104 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
105 self.as_str().serialize(serializer)
106 }
107}
108
109#[derive(Debug)]
111#[cfg_attr(feature = "serde", derive(Serialize))]
112pub struct Expr<'arena, 'src> {
113 pub kind: ExprKind<'arena, 'src>,
115 pub span: Span,
117}
118
119#[derive(Debug)]
121#[cfg_attr(feature = "serde", derive(Serialize))]
122#[non_exhaustive]
123pub enum ExprKind<'arena, 'src> {
124 Int(i64),
126
127 Float(f64),
129
130 String(NameStr<'arena, 'src>),
133
134 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
136
137 Heredoc {
139 label: &'src str,
141 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
143 },
144
145 Nowdoc {
147 label: &'src str,
149 value: &'arena str,
151 },
152
153 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
155
156 Bool(bool),
158
159 Null,
161
162 Variable(NameStr<'arena, 'src>),
164
165 VariableVariable(&'arena Expr<'arena, 'src>),
167
168 Identifier(NameStr<'arena, 'src>),
170
171 Assign(AssignExpr<'arena, 'src>),
173
174 Binary(BinaryExpr<'arena, 'src>),
176
177 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
179
180 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
182
183 Ternary(TernaryExpr<'arena, 'src>),
185
186 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
188
189 FunctionCall(FunctionCallExpr<'arena, 'src>),
191
192 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
194
195 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
197
198 Print(&'arena Expr<'arena, 'src>),
200
201 Parenthesized(&'arena Expr<'arena, 'src>),
203
204 Cast(CastKind, &'arena Expr<'arena, 'src>),
206
207 ErrorSuppress(&'arena Expr<'arena, 'src>),
209
210 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
212
213 Empty(&'arena Expr<'arena, 'src>),
215
216 Include(IncludeKind, &'arena Expr<'arena, 'src>),
218
219 Eval(&'arena Expr<'arena, 'src>),
221
222 Exit(Option<&'arena Expr<'arena, 'src>>),
224
225 MagicConst(MagicConstKind),
227
228 Clone(&'arena Expr<'arena, 'src>),
230
231 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
233
234 New(NewExpr<'arena, 'src>),
236
237 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
239
240 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
242
243 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
245
246 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
248
249 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
251
252 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
254
255 StaticMethodCallDynamic(&'arena StaticMethodCallDynamicExpr<'arena, 'src>),
257
258 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
260
261 ClassConstAccessDynamic {
263 class: &'arena Expr<'arena, 'src>,
265 member: &'arena Expr<'arena, 'src>,
267 },
268
269 StaticPropertyAccessDynamic {
271 class: &'arena Expr<'arena, 'src>,
273 member: &'arena Expr<'arena, 'src>,
275 },
276
277 Closure(&'arena ClosureExpr<'arena, 'src>),
279
280 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
282
283 Match(MatchExpr<'arena, 'src>),
285
286 Throw(&'arena Expr<'arena, 'src>),
288
289 Yield(YieldExpr<'arena, 'src>),
291
292 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
294
295 CallableCreate(CallableCreateExpr<'arena, 'src>),
297
298 Omit,
300
301 Error,
303}
304
305impl<'arena, 'src> Expr<'arena, 'src> {
306 pub fn name_str(&self) -> Option<&str> {
308 match &self.kind {
309 ExprKind::Variable(s) | ExprKind::Identifier(s) => Some(s.as_str()),
310 _ => None,
311 }
312 }
313}
314
315#[derive(Debug, Clone, Copy, PartialEq, Eq)]
317#[cfg_attr(feature = "serde", derive(Serialize))]
318#[non_exhaustive]
319pub enum CastKind {
320 Int,
322 Float,
324 String,
326 Bool,
328 Array,
330 Object,
332 Unset,
334 Void,
336}
337
338#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340#[cfg_attr(feature = "serde", derive(Serialize))]
341#[non_exhaustive]
342pub enum IncludeKind {
343 Include,
345 IncludeOnce,
347 Require,
349 RequireOnce,
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq)]
355#[cfg_attr(feature = "serde", derive(Serialize))]
356#[non_exhaustive]
357pub enum MagicConstKind {
358 Class,
360 Dir,
362 File,
364 Function,
366 Line,
368 Method,
370 Namespace,
372 Trait,
374 Property,
376}
377
378#[derive(Debug)]
382#[cfg_attr(feature = "serde", derive(Serialize))]
383pub struct AssignExpr<'arena, 'src> {
384 pub target: &'arena Expr<'arena, 'src>,
386 pub op: AssignOp,
388 pub value: &'arena Expr<'arena, 'src>,
390 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "is_false"))]
392 pub by_ref: bool,
393}
394
395#[derive(Debug, Clone, Copy, PartialEq, Eq)]
397#[cfg_attr(feature = "serde", derive(Serialize))]
398#[non_exhaustive]
399pub enum AssignOp {
400 Assign,
402 Plus,
404 Minus,
406 Mul,
408 Div,
410 Mod,
412 Pow,
414 Concat,
416 BitwiseAnd,
418 BitwiseOr,
420 BitwiseXor,
422 ShiftLeft,
424 ShiftRight,
426 Coalesce,
428}
429
430#[derive(Debug)]
432#[cfg_attr(feature = "serde", derive(Serialize))]
433pub struct BinaryExpr<'arena, 'src> {
434 pub left: &'arena Expr<'arena, 'src>,
436 pub op: BinaryOp,
438 pub right: &'arena Expr<'arena, 'src>,
440}
441
442#[derive(Debug, Clone, Copy, PartialEq, Eq)]
444#[cfg_attr(feature = "serde", derive(Serialize))]
445#[non_exhaustive]
446pub enum BinaryOp {
447 Add,
449 Sub,
451 Mul,
453 Div,
455 Mod,
457 Pow,
459 Concat,
461 Equal,
463 NotEqual,
465 Identical,
467 NotIdentical,
469 Less,
471 Greater,
473 LessOrEqual,
475 GreaterOrEqual,
477 Spaceship,
479 BooleanAnd,
481 BooleanOr,
483 BitwiseAnd,
485 BitwiseOr,
487 BitwiseXor,
489 ShiftLeft,
491 ShiftRight,
493 LogicalAnd,
495 LogicalOr,
497 LogicalXor,
499 Instanceof,
501 Pipe,
503}
504
505#[derive(Debug)]
507#[cfg_attr(feature = "serde", derive(Serialize))]
508pub struct UnaryPrefixExpr<'arena, 'src> {
509 pub op: UnaryPrefixOp,
511 pub operand: &'arena Expr<'arena, 'src>,
513}
514
515#[derive(Debug, Clone, Copy, PartialEq, Eq)]
517#[cfg_attr(feature = "serde", derive(Serialize))]
518#[non_exhaustive]
519pub enum UnaryPrefixOp {
520 Negate,
522 Plus,
524 BooleanNot,
526 BitwiseNot,
528 PreIncrement,
530 PreDecrement,
532}
533
534#[derive(Debug)]
536#[cfg_attr(feature = "serde", derive(Serialize))]
537pub struct UnaryPostfixExpr<'arena, 'src> {
538 pub operand: &'arena Expr<'arena, 'src>,
540 pub op: UnaryPostfixOp,
542}
543
544#[derive(Debug, Clone, Copy, PartialEq, Eq)]
546#[cfg_attr(feature = "serde", derive(Serialize))]
547#[non_exhaustive]
548pub enum UnaryPostfixOp {
549 PostIncrement,
551 PostDecrement,
553}
554
555#[derive(Debug)]
557#[cfg_attr(feature = "serde", derive(Serialize))]
558pub struct TernaryExpr<'arena, 'src> {
559 pub condition: &'arena Expr<'arena, 'src>,
561 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
563 pub else_expr: &'arena Expr<'arena, 'src>,
565}
566
567#[derive(Debug)]
569#[cfg_attr(feature = "serde", derive(Serialize))]
570pub struct NullCoalesceExpr<'arena, 'src> {
571 pub left: &'arena Expr<'arena, 'src>,
573 pub right: &'arena Expr<'arena, 'src>,
575}
576
577#[derive(Debug)]
579#[cfg_attr(feature = "serde", derive(Serialize))]
580pub struct FunctionCallExpr<'arena, 'src> {
581 pub name: &'arena Expr<'arena, 'src>,
583 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
585}
586
587#[derive(Debug)]
589#[cfg_attr(feature = "serde", derive(Serialize))]
590pub struct ArrayElement<'arena, 'src> {
591 pub key: Option<Expr<'arena, 'src>>,
593 pub value: Expr<'arena, 'src>,
595 pub unpack: bool,
597 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "is_false"))]
599 pub by_ref: bool,
600 pub span: Span,
602}
603
604#[derive(Debug)]
606#[cfg_attr(feature = "serde", derive(Serialize))]
607pub struct ArrayAccessExpr<'arena, 'src> {
608 pub array: &'arena Expr<'arena, 'src>,
610 pub index: Option<&'arena Expr<'arena, 'src>>,
612}
613
614#[derive(Debug)]
618#[cfg_attr(feature = "serde", derive(Serialize))]
619pub struct NewExpr<'arena, 'src> {
620 pub class: &'arena Expr<'arena, 'src>,
622 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
624}
625
626#[derive(Debug)]
628#[cfg_attr(feature = "serde", derive(Serialize))]
629pub struct PropertyAccessExpr<'arena, 'src> {
630 pub object: &'arena Expr<'arena, 'src>,
632 pub property: &'arena Expr<'arena, 'src>,
634}
635
636#[derive(Debug)]
638#[cfg_attr(feature = "serde", derive(Serialize))]
639pub struct MethodCallExpr<'arena, 'src> {
640 pub object: &'arena Expr<'arena, 'src>,
642 pub method: &'arena Expr<'arena, 'src>,
644 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
646}
647
648#[derive(Debug)]
650#[cfg_attr(feature = "serde", derive(Serialize))]
651pub struct StaticAccessExpr<'arena, 'src> {
652 pub class: &'arena Expr<'arena, 'src>,
654 pub member: &'arena Expr<'arena, 'src>,
656}
657
658#[derive(Debug)]
660#[cfg_attr(feature = "serde", derive(Serialize))]
661pub struct StaticMethodCallExpr<'arena, 'src> {
662 pub class: &'arena Expr<'arena, 'src>,
664 pub method: &'arena Expr<'arena, 'src>,
666 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
668}
669
670#[derive(Debug)]
672#[cfg_attr(feature = "serde", derive(Serialize))]
673pub struct StaticMethodCallDynamicExpr<'arena, 'src> {
674 pub class: &'arena Expr<'arena, 'src>,
676 pub method: &'arena Expr<'arena, 'src>,
678 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
680}
681
682#[derive(Debug)]
684#[cfg_attr(feature = "serde", derive(Serialize))]
685pub struct ClosureExpr<'arena, 'src> {
686 pub is_static: bool,
688 pub by_ref: bool,
690 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
692 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
694 pub return_type: Option<TypeHint<'arena, 'src>>,
696 pub body: &'arena Block<'arena, 'src>,
698 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
700}
701
702#[derive(Debug, Clone)]
704#[cfg_attr(feature = "serde", derive(Serialize))]
705pub struct ClosureUseVar<'src> {
706 pub name: &'src str,
708 pub by_ref: bool,
710 pub span: Span,
712}
713
714#[derive(Debug)]
716#[cfg_attr(feature = "serde", derive(Serialize))]
717pub struct ArrowFunctionExpr<'arena, 'src> {
718 pub is_static: bool,
720 pub by_ref: bool,
722 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
724 pub return_type: Option<TypeHint<'arena, 'src>>,
726 pub body: &'arena Expr<'arena, 'src>,
728 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
730}
731
732#[derive(Debug)]
734#[cfg_attr(feature = "serde", derive(Serialize))]
735pub struct MatchExpr<'arena, 'src> {
736 pub subject: &'arena Expr<'arena, 'src>,
738 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
740 #[cfg_attr(feature = "serde", serde(skip))]
742 pub brace_span: Span,
743}
744
745#[derive(Debug)]
747#[cfg_attr(feature = "serde", derive(Serialize))]
748pub struct MatchArm<'arena, 'src> {
749 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
751 pub body: Expr<'arena, 'src>,
753 pub span: Span,
755}
756
757#[derive(Debug)]
759#[cfg_attr(feature = "serde", derive(Serialize))]
760pub struct YieldExpr<'arena, 'src> {
761 pub key: Option<&'arena Expr<'arena, 'src>>,
763 pub value: Option<&'arena Expr<'arena, 'src>>,
765 pub is_from: bool,
767}
768
769#[derive(Debug)]
773#[cfg_attr(feature = "serde", derive(Serialize))]
774pub struct CallableCreateExpr<'arena, 'src> {
775 pub kind: CallableCreateKind<'arena, 'src>,
777}
778
779#[derive(Debug)]
781#[cfg_attr(feature = "serde", derive(Serialize))]
782#[non_exhaustive]
783pub enum CallableCreateKind<'arena, 'src> {
784 Function(&'arena Expr<'arena, 'src>),
786 Method {
788 object: &'arena Expr<'arena, 'src>,
790 method: &'arena Expr<'arena, 'src>,
792 },
793 NullsafeMethod {
795 object: &'arena Expr<'arena, 'src>,
797 method: &'arena Expr<'arena, 'src>,
799 },
800 StaticMethod {
802 class: &'arena Expr<'arena, 'src>,
804 method: &'arena Expr<'arena, 'src>,
806 },
807}
808
809#[derive(Debug)]
813#[cfg_attr(feature = "serde", derive(Serialize))]
814#[non_exhaustive]
815pub enum StringPart<'arena, 'src> {
816 Literal(&'arena str),
818 Expr(Expr<'arena, 'src>),
820}