1use serde::Serialize;
2
3use crate::Span;
4
5use super::{is_false, ArenaVec, Arg, Attribute, ClassDecl, Param, Stmt, TypeHint};
6
7#[derive(Clone, Copy, PartialEq, Eq, Hash)]
8enum NameStrInner<'arena, 'src> {
9 Src(&'src str),
10 Arena(&'arena str),
11}
12
13#[derive(Clone, Copy, PartialEq, Eq, Hash)]
28pub struct NameStr<'arena, 'src>(NameStrInner<'arena, 'src>);
29
30impl<'arena, 'src> NameStr<'arena, 'src> {
31 #[doc(hidden)]
33 #[inline]
34 pub fn __src(s: &'src str) -> Self {
35 Self(NameStrInner::Src(s))
36 }
37
38 #[doc(hidden)]
40 #[inline]
41 pub fn __arena(s: &'arena str) -> Self {
42 Self(NameStrInner::Arena(s))
43 }
44
45 #[doc(hidden)]
48 #[inline]
49 pub fn __into_arena_str(self) -> Option<&'arena str> {
50 match self.0 {
51 NameStrInner::Arena(s) => Some(s),
52 NameStrInner::Src(_) => None,
53 }
54 }
55
56 #[doc(hidden)]
59 #[inline]
60 pub fn __into_src_str(self) -> Option<&'src str> {
61 match self.0 {
62 NameStrInner::Src(s) => Some(s),
63 NameStrInner::Arena(_) => None,
64 }
65 }
66
67 #[inline]
68 pub fn as_str(&self) -> &str {
69 match self.0 {
70 NameStrInner::Src(s) | NameStrInner::Arena(s) => s,
71 }
72 }
73}
74
75impl<'arena, 'src> std::ops::Deref for NameStr<'arena, 'src> {
76 type Target = str;
77 #[inline]
78 fn deref(&self) -> &str {
79 self.as_str()
80 }
81}
82
83impl<'arena, 'src> std::fmt::Debug for NameStr<'arena, 'src> {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 self.as_str().fmt(f)
86 }
87}
88
89impl<'arena, 'src> serde::Serialize for NameStr<'arena, 'src> {
90 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
91 self.as_str().serialize(serializer)
92 }
93}
94
95#[derive(Debug, Serialize)]
96pub struct Expr<'arena, 'src> {
97 pub kind: ExprKind<'arena, 'src>,
98 pub span: Span,
99}
100
101#[derive(Debug, Serialize)]
102pub enum ExprKind<'arena, 'src> {
103 Int(i64),
105
106 Float(f64),
108
109 String(&'arena str),
111
112 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
114
115 Heredoc {
117 label: &'src str,
118 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
119 },
120
121 Nowdoc {
123 label: &'src str,
124 value: &'arena str,
125 },
126
127 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
129
130 Bool(bool),
132
133 Null,
135
136 Variable(NameStr<'arena, 'src>),
138
139 VariableVariable(&'arena Expr<'arena, 'src>),
141
142 Identifier(NameStr<'arena, 'src>),
144
145 Assign(AssignExpr<'arena, 'src>),
147
148 Binary(BinaryExpr<'arena, 'src>),
150
151 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
153
154 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
156
157 Ternary(TernaryExpr<'arena, 'src>),
159
160 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
162
163 FunctionCall(FunctionCallExpr<'arena, 'src>),
165
166 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
168
169 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
171
172 Print(&'arena Expr<'arena, 'src>),
174
175 Parenthesized(&'arena Expr<'arena, 'src>),
177
178 Cast(CastKind, &'arena Expr<'arena, 'src>),
180
181 ErrorSuppress(&'arena Expr<'arena, 'src>),
183
184 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
186
187 Empty(&'arena Expr<'arena, 'src>),
189
190 Include(IncludeKind, &'arena Expr<'arena, 'src>),
192
193 Eval(&'arena Expr<'arena, 'src>),
195
196 Exit(Option<&'arena Expr<'arena, 'src>>),
198
199 MagicConst(MagicConstKind),
201
202 Clone(&'arena Expr<'arena, 'src>),
204
205 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
207
208 New(NewExpr<'arena, 'src>),
210
211 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
213
214 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
216
217 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
219
220 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
222
223 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
225
226 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
228
229 StaticDynMethodCall(&'arena StaticDynMethodCallExpr<'arena, 'src>),
231
232 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
234
235 ClassConstAccessDynamic {
237 class: &'arena Expr<'arena, 'src>,
238 member: &'arena Expr<'arena, 'src>,
239 },
240
241 StaticPropertyAccessDynamic {
243 class: &'arena Expr<'arena, 'src>,
244 member: &'arena Expr<'arena, 'src>,
245 },
246
247 Closure(&'arena ClosureExpr<'arena, 'src>),
249
250 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
252
253 Match(MatchExpr<'arena, 'src>),
255
256 ThrowExpr(&'arena Expr<'arena, 'src>),
258
259 Yield(YieldExpr<'arena, 'src>),
261
262 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
264
265 CallableCreate(CallableCreateExpr<'arena, 'src>),
267
268 Omit,
270
271 Error,
273}
274
275impl<'arena, 'src> Expr<'arena, 'src> {
276 pub fn name_str(&self) -> Option<&str> {
278 match &self.kind {
279 ExprKind::Variable(s) | ExprKind::Identifier(s) => Some(s.as_str()),
280 _ => None,
281 }
282 }
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
286pub enum CastKind {
287 Int,
289 Float,
291 String,
293 Bool,
295 Array,
297 Object,
299 Unset,
301 Void,
303}
304
305#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
306pub enum IncludeKind {
307 Include,
309 IncludeOnce,
311 Require,
313 RequireOnce,
315}
316
317#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
318pub enum MagicConstKind {
319 Class,
321 Dir,
323 File,
325 Function,
327 Line,
329 Method,
331 Namespace,
333 Trait,
335 Property,
337}
338
339#[derive(Debug, Serialize)]
342pub struct AssignExpr<'arena, 'src> {
343 pub target: &'arena Expr<'arena, 'src>,
344 pub op: AssignOp,
345 pub value: &'arena Expr<'arena, 'src>,
346 #[serde(skip_serializing_if = "is_false")]
347 pub by_ref: bool,
348}
349
350#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
351pub enum AssignOp {
352 Assign,
354 Plus,
356 Minus,
358 Mul,
360 Div,
362 Mod,
364 Pow,
366 Concat,
368 BitwiseAnd,
370 BitwiseOr,
372 BitwiseXor,
374 ShiftLeft,
376 ShiftRight,
378 Coalesce,
380}
381
382#[derive(Debug, Serialize)]
383pub struct BinaryExpr<'arena, 'src> {
384 pub left: &'arena Expr<'arena, 'src>,
385 pub op: BinaryOp,
386 pub right: &'arena Expr<'arena, 'src>,
387}
388
389#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
390pub enum BinaryOp {
391 Add,
393 Sub,
395 Mul,
397 Div,
399 Mod,
401 Pow,
403 Concat,
405 Equal,
407 NotEqual,
409 Identical,
411 NotIdentical,
413 Less,
415 Greater,
417 LessOrEqual,
419 GreaterOrEqual,
421 Spaceship,
423 BooleanAnd,
425 BooleanOr,
427 BitwiseAnd,
429 BitwiseOr,
431 BitwiseXor,
433 ShiftLeft,
435 ShiftRight,
437 LogicalAnd,
439 LogicalOr,
441 LogicalXor,
443 Instanceof,
445 Pipe,
447}
448
449#[derive(Debug, Serialize)]
450pub struct UnaryPrefixExpr<'arena, 'src> {
451 pub op: UnaryPrefixOp,
452 pub operand: &'arena Expr<'arena, 'src>,
453}
454
455#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
456pub enum UnaryPrefixOp {
457 Negate,
459 Plus,
461 BooleanNot,
463 BitwiseNot,
465 PreIncrement,
467 PreDecrement,
469}
470
471#[derive(Debug, Serialize)]
472pub struct UnaryPostfixExpr<'arena, 'src> {
473 pub operand: &'arena Expr<'arena, 'src>,
474 pub op: UnaryPostfixOp,
475}
476
477#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
478pub enum UnaryPostfixOp {
479 PostIncrement,
481 PostDecrement,
483}
484
485#[derive(Debug, Serialize)]
486pub struct TernaryExpr<'arena, 'src> {
487 pub condition: &'arena Expr<'arena, 'src>,
488 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
490 pub else_expr: &'arena Expr<'arena, 'src>,
491}
492
493#[derive(Debug, Serialize)]
494pub struct NullCoalesceExpr<'arena, 'src> {
495 pub left: &'arena Expr<'arena, 'src>,
496 pub right: &'arena Expr<'arena, 'src>,
497}
498
499#[derive(Debug, Serialize)]
500pub struct FunctionCallExpr<'arena, 'src> {
501 pub name: &'arena Expr<'arena, 'src>,
502 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
503}
504
505#[derive(Debug, Serialize)]
506pub struct ArrayElement<'arena, 'src> {
507 pub key: Option<Expr<'arena, 'src>>,
508 pub value: Expr<'arena, 'src>,
509 pub unpack: bool,
510 #[serde(skip_serializing_if = "is_false")]
511 pub by_ref: bool,
512 pub span: Span,
513}
514
515#[derive(Debug, Serialize)]
516pub struct ArrayAccessExpr<'arena, 'src> {
517 pub array: &'arena Expr<'arena, 'src>,
518 pub index: Option<&'arena Expr<'arena, 'src>>,
519}
520
521#[derive(Debug, Serialize)]
524pub struct NewExpr<'arena, 'src> {
525 pub class: &'arena Expr<'arena, 'src>,
526 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
527}
528
529#[derive(Debug, Serialize)]
530pub struct PropertyAccessExpr<'arena, 'src> {
531 pub object: &'arena Expr<'arena, 'src>,
532 pub property: &'arena Expr<'arena, 'src>,
533}
534
535#[derive(Debug, Serialize)]
536pub struct MethodCallExpr<'arena, 'src> {
537 pub object: &'arena Expr<'arena, 'src>,
538 pub method: &'arena Expr<'arena, 'src>,
539 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
540}
541
542#[derive(Debug, Serialize)]
543pub struct StaticAccessExpr<'arena, 'src> {
544 pub class: &'arena Expr<'arena, 'src>,
545 pub member: &'arena Expr<'arena, 'src>,
546}
547
548#[derive(Debug, Serialize)]
549pub struct StaticMethodCallExpr<'arena, 'src> {
550 pub class: &'arena Expr<'arena, 'src>,
551 pub method: &'arena Expr<'arena, 'src>,
552 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
553}
554
555#[derive(Debug, Serialize)]
556pub struct StaticDynMethodCallExpr<'arena, 'src> {
557 pub class: &'arena Expr<'arena, 'src>,
558 pub method: &'arena Expr<'arena, 'src>,
559 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
560}
561
562#[derive(Debug, Serialize)]
563pub struct ClosureExpr<'arena, 'src> {
564 pub is_static: bool,
565 pub by_ref: bool,
566 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
567 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
568 pub return_type: Option<TypeHint<'arena, 'src>>,
569 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
570 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
571}
572
573#[derive(Debug, Clone, Serialize)]
574pub struct ClosureUseVar<'src> {
575 pub name: &'src str,
576 pub by_ref: bool,
577 pub span: Span,
578}
579
580#[derive(Debug, Serialize)]
581pub struct ArrowFunctionExpr<'arena, 'src> {
582 pub is_static: bool,
583 pub by_ref: bool,
584 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
585 pub return_type: Option<TypeHint<'arena, 'src>>,
586 pub body: &'arena Expr<'arena, 'src>,
587 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
588}
589
590#[derive(Debug, Serialize)]
591pub struct MatchExpr<'arena, 'src> {
592 pub subject: &'arena Expr<'arena, 'src>,
593 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
594}
595
596#[derive(Debug, Serialize)]
597pub struct MatchArm<'arena, 'src> {
598 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
600 pub body: Expr<'arena, 'src>,
601 pub span: Span,
602}
603
604#[derive(Debug, Serialize)]
605pub struct YieldExpr<'arena, 'src> {
606 pub key: Option<&'arena Expr<'arena, 'src>>,
607 pub value: Option<&'arena Expr<'arena, 'src>>,
608 pub is_from: bool,
610}
611
612#[derive(Debug, Serialize)]
615pub struct CallableCreateExpr<'arena, 'src> {
616 pub kind: CallableCreateKind<'arena, 'src>,
617}
618
619#[derive(Debug, Serialize)]
620pub enum CallableCreateKind<'arena, 'src> {
621 Function(&'arena Expr<'arena, 'src>),
623 Method {
625 object: &'arena Expr<'arena, 'src>,
626 method: &'arena Expr<'arena, 'src>,
627 },
628 NullsafeMethod {
630 object: &'arena Expr<'arena, 'src>,
631 method: &'arena Expr<'arena, 'src>,
632 },
633 StaticMethod {
635 class: &'arena Expr<'arena, 'src>,
636 method: &'arena Expr<'arena, 'src>,
637 },
638}
639
640#[derive(Debug, Serialize)]
643pub enum StringPart<'arena, 'src> {
644 Literal(&'arena str),
646 Expr(Expr<'arena, 'src>),
648}