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 #[inline]
57 pub fn as_str(&self) -> &str {
58 match self.0 {
59 NameStrInner::Src(s) | NameStrInner::Arena(s) => s,
60 }
61 }
62}
63
64impl<'arena, 'src> std::ops::Deref for NameStr<'arena, 'src> {
65 type Target = str;
66 #[inline]
67 fn deref(&self) -> &str {
68 self.as_str()
69 }
70}
71
72impl<'arena, 'src> std::fmt::Debug for NameStr<'arena, 'src> {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 self.as_str().fmt(f)
75 }
76}
77
78impl<'arena, 'src> serde::Serialize for NameStr<'arena, 'src> {
79 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
80 self.as_str().serialize(serializer)
81 }
82}
83
84#[derive(Debug, Serialize)]
85pub struct Expr<'arena, 'src> {
86 pub kind: ExprKind<'arena, 'src>,
87 pub span: Span,
88}
89
90#[derive(Debug, Serialize)]
91pub enum ExprKind<'arena, 'src> {
92 Int(i64),
94
95 Float(f64),
97
98 String(&'arena str),
100
101 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
103
104 Heredoc {
106 label: &'src str,
107 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
108 },
109
110 Nowdoc {
112 label: &'src str,
113 value: &'arena str,
114 },
115
116 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
118
119 Bool(bool),
121
122 Null,
124
125 Variable(NameStr<'arena, 'src>),
127
128 VariableVariable(&'arena Expr<'arena, 'src>),
130
131 Identifier(NameStr<'arena, 'src>),
133
134 Assign(AssignExpr<'arena, 'src>),
136
137 Binary(BinaryExpr<'arena, 'src>),
139
140 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
142
143 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
145
146 Ternary(TernaryExpr<'arena, 'src>),
148
149 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
151
152 FunctionCall(FunctionCallExpr<'arena, 'src>),
154
155 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
157
158 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
160
161 Print(&'arena Expr<'arena, 'src>),
163
164 Parenthesized(&'arena Expr<'arena, 'src>),
166
167 Cast(CastKind, &'arena Expr<'arena, 'src>),
169
170 ErrorSuppress(&'arena Expr<'arena, 'src>),
172
173 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
175
176 Empty(&'arena Expr<'arena, 'src>),
178
179 Include(IncludeKind, &'arena Expr<'arena, 'src>),
181
182 Eval(&'arena Expr<'arena, 'src>),
184
185 Exit(Option<&'arena Expr<'arena, 'src>>),
187
188 MagicConst(MagicConstKind),
190
191 Clone(&'arena Expr<'arena, 'src>),
193
194 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
196
197 New(NewExpr<'arena, 'src>),
199
200 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
202
203 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
205
206 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
208
209 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
211
212 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
214
215 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
217
218 StaticDynMethodCall(&'arena StaticDynMethodCallExpr<'arena, 'src>),
220
221 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
223
224 ClassConstAccessDynamic {
226 class: &'arena Expr<'arena, 'src>,
227 member: &'arena Expr<'arena, 'src>,
228 },
229
230 StaticPropertyAccessDynamic {
232 class: &'arena Expr<'arena, 'src>,
233 member: &'arena Expr<'arena, 'src>,
234 },
235
236 Closure(&'arena ClosureExpr<'arena, 'src>),
238
239 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
241
242 Match(MatchExpr<'arena, 'src>),
244
245 ThrowExpr(&'arena Expr<'arena, 'src>),
247
248 Yield(YieldExpr<'arena, 'src>),
250
251 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
253
254 CallableCreate(CallableCreateExpr<'arena, 'src>),
256
257 Omit,
259
260 Error,
262}
263
264impl<'arena, 'src> Expr<'arena, 'src> {
265 pub fn name_str(&self) -> Option<&str> {
267 match &self.kind {
268 ExprKind::Variable(s) | ExprKind::Identifier(s) => Some(s.as_str()),
269 _ => None,
270 }
271 }
272}
273
274#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
275pub enum CastKind {
276 Int,
278 Float,
280 String,
282 Bool,
284 Array,
286 Object,
288 Unset,
290 Void,
292}
293
294#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
295pub enum IncludeKind {
296 Include,
298 IncludeOnce,
300 Require,
302 RequireOnce,
304}
305
306#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
307pub enum MagicConstKind {
308 Class,
310 Dir,
312 File,
314 Function,
316 Line,
318 Method,
320 Namespace,
322 Trait,
324 Property,
326}
327
328#[derive(Debug, Serialize)]
331pub struct AssignExpr<'arena, 'src> {
332 pub target: &'arena Expr<'arena, 'src>,
333 pub op: AssignOp,
334 pub value: &'arena Expr<'arena, 'src>,
335 #[serde(skip_serializing_if = "is_false")]
336 pub by_ref: bool,
337}
338
339#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
340pub enum AssignOp {
341 Assign,
343 Plus,
345 Minus,
347 Mul,
349 Div,
351 Mod,
353 Pow,
355 Concat,
357 BitwiseAnd,
359 BitwiseOr,
361 BitwiseXor,
363 ShiftLeft,
365 ShiftRight,
367 Coalesce,
369}
370
371#[derive(Debug, Serialize)]
372pub struct BinaryExpr<'arena, 'src> {
373 pub left: &'arena Expr<'arena, 'src>,
374 pub op: BinaryOp,
375 pub right: &'arena Expr<'arena, 'src>,
376}
377
378#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
379pub enum BinaryOp {
380 Add,
382 Sub,
384 Mul,
386 Div,
388 Mod,
390 Pow,
392 Concat,
394 Equal,
396 NotEqual,
398 Identical,
400 NotIdentical,
402 Less,
404 Greater,
406 LessOrEqual,
408 GreaterOrEqual,
410 Spaceship,
412 BooleanAnd,
414 BooleanOr,
416 BitwiseAnd,
418 BitwiseOr,
420 BitwiseXor,
422 ShiftLeft,
424 ShiftRight,
426 LogicalAnd,
428 LogicalOr,
430 LogicalXor,
432 Instanceof,
434 Pipe,
436}
437
438#[derive(Debug, Serialize)]
439pub struct UnaryPrefixExpr<'arena, 'src> {
440 pub op: UnaryPrefixOp,
441 pub operand: &'arena Expr<'arena, 'src>,
442}
443
444#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
445pub enum UnaryPrefixOp {
446 Negate,
448 Plus,
450 BooleanNot,
452 BitwiseNot,
454 PreIncrement,
456 PreDecrement,
458}
459
460#[derive(Debug, Serialize)]
461pub struct UnaryPostfixExpr<'arena, 'src> {
462 pub operand: &'arena Expr<'arena, 'src>,
463 pub op: UnaryPostfixOp,
464}
465
466#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
467pub enum UnaryPostfixOp {
468 PostIncrement,
470 PostDecrement,
472}
473
474#[derive(Debug, Serialize)]
475pub struct TernaryExpr<'arena, 'src> {
476 pub condition: &'arena Expr<'arena, 'src>,
477 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
479 pub else_expr: &'arena Expr<'arena, 'src>,
480}
481
482#[derive(Debug, Serialize)]
483pub struct NullCoalesceExpr<'arena, 'src> {
484 pub left: &'arena Expr<'arena, 'src>,
485 pub right: &'arena Expr<'arena, 'src>,
486}
487
488#[derive(Debug, Serialize)]
489pub struct FunctionCallExpr<'arena, 'src> {
490 pub name: &'arena Expr<'arena, 'src>,
491 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
492}
493
494#[derive(Debug, Serialize)]
495pub struct ArrayElement<'arena, 'src> {
496 pub key: Option<Expr<'arena, 'src>>,
497 pub value: Expr<'arena, 'src>,
498 pub unpack: bool,
499 #[serde(skip_serializing_if = "is_false")]
500 pub by_ref: bool,
501 pub span: Span,
502}
503
504#[derive(Debug, Serialize)]
505pub struct ArrayAccessExpr<'arena, 'src> {
506 pub array: &'arena Expr<'arena, 'src>,
507 pub index: Option<&'arena Expr<'arena, 'src>>,
508}
509
510#[derive(Debug, Serialize)]
513pub struct NewExpr<'arena, 'src> {
514 pub class: &'arena Expr<'arena, 'src>,
515 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
516}
517
518#[derive(Debug, Serialize)]
519pub struct PropertyAccessExpr<'arena, 'src> {
520 pub object: &'arena Expr<'arena, 'src>,
521 pub property: &'arena Expr<'arena, 'src>,
522}
523
524#[derive(Debug, Serialize)]
525pub struct MethodCallExpr<'arena, 'src> {
526 pub object: &'arena Expr<'arena, 'src>,
527 pub method: &'arena Expr<'arena, 'src>,
528 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
529}
530
531#[derive(Debug, Serialize)]
532pub struct StaticAccessExpr<'arena, 'src> {
533 pub class: &'arena Expr<'arena, 'src>,
534 pub member: &'arena Expr<'arena, 'src>,
535}
536
537#[derive(Debug, Serialize)]
538pub struct StaticMethodCallExpr<'arena, 'src> {
539 pub class: &'arena Expr<'arena, 'src>,
540 pub method: &'arena Expr<'arena, 'src>,
541 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
542}
543
544#[derive(Debug, Serialize)]
545pub struct StaticDynMethodCallExpr<'arena, 'src> {
546 pub class: &'arena Expr<'arena, 'src>,
547 pub method: &'arena Expr<'arena, 'src>,
548 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
549}
550
551#[derive(Debug, Serialize)]
552pub struct ClosureExpr<'arena, 'src> {
553 pub is_static: bool,
554 pub by_ref: bool,
555 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
556 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
557 pub return_type: Option<TypeHint<'arena, 'src>>,
558 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
559 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
560}
561
562#[derive(Debug, Clone, Serialize)]
563pub struct ClosureUseVar<'src> {
564 pub name: &'src str,
565 pub by_ref: bool,
566 pub span: Span,
567}
568
569#[derive(Debug, Serialize)]
570pub struct ArrowFunctionExpr<'arena, 'src> {
571 pub is_static: bool,
572 pub by_ref: bool,
573 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
574 pub return_type: Option<TypeHint<'arena, 'src>>,
575 pub body: &'arena Expr<'arena, 'src>,
576 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
577}
578
579#[derive(Debug, Serialize)]
580pub struct MatchExpr<'arena, 'src> {
581 pub subject: &'arena Expr<'arena, 'src>,
582 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
583}
584
585#[derive(Debug, Serialize)]
586pub struct MatchArm<'arena, 'src> {
587 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
589 pub body: Expr<'arena, 'src>,
590 pub span: Span,
591}
592
593#[derive(Debug, Serialize)]
594pub struct YieldExpr<'arena, 'src> {
595 pub key: Option<&'arena Expr<'arena, 'src>>,
596 pub value: Option<&'arena Expr<'arena, 'src>>,
597 pub is_from: bool,
599}
600
601#[derive(Debug, Serialize)]
604pub struct CallableCreateExpr<'arena, 'src> {
605 pub kind: CallableCreateKind<'arena, 'src>,
606}
607
608#[derive(Debug, Serialize)]
609pub enum CallableCreateKind<'arena, 'src> {
610 Function(&'arena Expr<'arena, 'src>),
612 Method {
614 object: &'arena Expr<'arena, 'src>,
615 method: &'arena Expr<'arena, 'src>,
616 },
617 NullsafeMethod {
619 object: &'arena Expr<'arena, 'src>,
620 method: &'arena Expr<'arena, 'src>,
621 },
622 StaticMethod {
624 class: &'arena Expr<'arena, 'src>,
625 method: &'arena Expr<'arena, 'src>,
626 },
627}
628
629#[derive(Debug, Serialize)]
632pub enum StringPart<'arena, 'src> {
633 Literal(&'arena str),
635 Expr(Expr<'arena, 'src>),
637}