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)]
22pub enum NameStr<'arena, 'src> {
23 Src(&'src str),
25 Arena(&'arena str),
27}
28
29impl<'arena, 'src> NameStr<'arena, 'src> {
30 #[inline]
31 pub fn as_str(&self) -> &str {
32 match self {
33 NameStr::Src(s) => s,
34 NameStr::Arena(s) => s,
35 }
36 }
37}
38
39impl<'arena, 'src> std::ops::Deref for NameStr<'arena, 'src> {
40 type Target = str;
41 #[inline]
42 fn deref(&self) -> &str {
43 self.as_str()
44 }
45}
46
47impl<'arena, 'src> std::fmt::Debug for NameStr<'arena, 'src> {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 self.as_str().fmt(f)
50 }
51}
52
53impl<'arena, 'src> serde::Serialize for NameStr<'arena, 'src> {
54 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
55 self.as_str().serialize(serializer)
56 }
57}
58
59#[derive(Debug, Serialize)]
60pub struct Expr<'arena, 'src> {
61 pub kind: ExprKind<'arena, 'src>,
62 pub span: Span,
63}
64
65#[derive(Debug, Serialize)]
66pub enum ExprKind<'arena, 'src> {
67 Int(i64),
69
70 Float(f64),
72
73 String(&'arena str),
75
76 InterpolatedString(ArenaVec<'arena, StringPart<'arena, 'src>>),
78
79 Heredoc {
81 label: &'src str,
82 parts: ArenaVec<'arena, StringPart<'arena, 'src>>,
83 },
84
85 Nowdoc {
87 label: &'src str,
88 value: &'arena str,
89 },
90
91 ShellExec(ArenaVec<'arena, StringPart<'arena, 'src>>),
93
94 Bool(bool),
96
97 Null,
99
100 Variable(NameStr<'arena, 'src>),
102
103 VariableVariable(&'arena Expr<'arena, 'src>),
105
106 Identifier(NameStr<'arena, 'src>),
108
109 Assign(AssignExpr<'arena, 'src>),
111
112 Binary(BinaryExpr<'arena, 'src>),
114
115 UnaryPrefix(UnaryPrefixExpr<'arena, 'src>),
117
118 UnaryPostfix(UnaryPostfixExpr<'arena, 'src>),
120
121 Ternary(TernaryExpr<'arena, 'src>),
123
124 NullCoalesce(NullCoalesceExpr<'arena, 'src>),
126
127 FunctionCall(FunctionCallExpr<'arena, 'src>),
129
130 Array(ArenaVec<'arena, ArrayElement<'arena, 'src>>),
132
133 ArrayAccess(ArrayAccessExpr<'arena, 'src>),
135
136 Print(&'arena Expr<'arena, 'src>),
138
139 Parenthesized(&'arena Expr<'arena, 'src>),
141
142 Cast(CastKind, &'arena Expr<'arena, 'src>),
144
145 ErrorSuppress(&'arena Expr<'arena, 'src>),
147
148 Isset(ArenaVec<'arena, Expr<'arena, 'src>>),
150
151 Empty(&'arena Expr<'arena, 'src>),
153
154 Include(IncludeKind, &'arena Expr<'arena, 'src>),
156
157 Eval(&'arena Expr<'arena, 'src>),
159
160 Exit(Option<&'arena Expr<'arena, 'src>>),
162
163 MagicConst(MagicConstKind),
165
166 Clone(&'arena Expr<'arena, 'src>),
168
169 CloneWith(&'arena Expr<'arena, 'src>, &'arena Expr<'arena, 'src>),
171
172 New(NewExpr<'arena, 'src>),
174
175 PropertyAccess(PropertyAccessExpr<'arena, 'src>),
177
178 NullsafePropertyAccess(PropertyAccessExpr<'arena, 'src>),
180
181 MethodCall(&'arena MethodCallExpr<'arena, 'src>),
183
184 NullsafeMethodCall(&'arena MethodCallExpr<'arena, 'src>),
186
187 StaticPropertyAccess(StaticAccessExpr<'arena, 'src>),
189
190 StaticMethodCall(&'arena StaticMethodCallExpr<'arena, 'src>),
192
193 StaticDynMethodCall(&'arena StaticDynMethodCallExpr<'arena, 'src>),
195
196 ClassConstAccess(StaticAccessExpr<'arena, 'src>),
198
199 ClassConstAccessDynamic {
201 class: &'arena Expr<'arena, 'src>,
202 member: &'arena Expr<'arena, 'src>,
203 },
204
205 StaticPropertyAccessDynamic {
207 class: &'arena Expr<'arena, 'src>,
208 member: &'arena Expr<'arena, 'src>,
209 },
210
211 Closure(&'arena ClosureExpr<'arena, 'src>),
213
214 ArrowFunction(&'arena ArrowFunctionExpr<'arena, 'src>),
216
217 Match(MatchExpr<'arena, 'src>),
219
220 ThrowExpr(&'arena Expr<'arena, 'src>),
222
223 Yield(YieldExpr<'arena, 'src>),
225
226 AnonymousClass(&'arena ClassDecl<'arena, 'src>),
228
229 CallableCreate(CallableCreateExpr<'arena, 'src>),
231
232 Omit,
234
235 Error,
237}
238
239impl<'arena, 'src> Expr<'arena, 'src> {
240 pub fn name_str(&self) -> Option<&str> {
242 match &self.kind {
243 ExprKind::Variable(s) | ExprKind::Identifier(s) => Some(s.as_str()),
244 _ => None,
245 }
246 }
247}
248
249#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
250pub enum CastKind {
251 Int,
253 Float,
255 String,
257 Bool,
259 Array,
261 Object,
263 Unset,
265 Void,
267}
268
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
270pub enum IncludeKind {
271 Include,
273 IncludeOnce,
275 Require,
277 RequireOnce,
279}
280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
282pub enum MagicConstKind {
283 Class,
285 Dir,
287 File,
289 Function,
291 Line,
293 Method,
295 Namespace,
297 Trait,
299 Property,
301}
302
303#[derive(Debug, Serialize)]
306pub struct AssignExpr<'arena, 'src> {
307 pub target: &'arena Expr<'arena, 'src>,
308 pub op: AssignOp,
309 pub value: &'arena Expr<'arena, 'src>,
310 #[serde(skip_serializing_if = "is_false")]
311 pub by_ref: bool,
312}
313
314#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
315pub enum AssignOp {
316 Assign,
318 Plus,
320 Minus,
322 Mul,
324 Div,
326 Mod,
328 Pow,
330 Concat,
332 BitwiseAnd,
334 BitwiseOr,
336 BitwiseXor,
338 ShiftLeft,
340 ShiftRight,
342 Coalesce,
344}
345
346#[derive(Debug, Serialize)]
347pub struct BinaryExpr<'arena, 'src> {
348 pub left: &'arena Expr<'arena, 'src>,
349 pub op: BinaryOp,
350 pub right: &'arena Expr<'arena, 'src>,
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
354pub enum BinaryOp {
355 Add,
357 Sub,
359 Mul,
361 Div,
363 Mod,
365 Pow,
367 Concat,
369 Equal,
371 NotEqual,
373 Identical,
375 NotIdentical,
377 Less,
379 Greater,
381 LessOrEqual,
383 GreaterOrEqual,
385 Spaceship,
387 BooleanAnd,
389 BooleanOr,
391 BitwiseAnd,
393 BitwiseOr,
395 BitwiseXor,
397 ShiftLeft,
399 ShiftRight,
401 LogicalAnd,
403 LogicalOr,
405 LogicalXor,
407 Instanceof,
409 Pipe,
411}
412
413#[derive(Debug, Serialize)]
414pub struct UnaryPrefixExpr<'arena, 'src> {
415 pub op: UnaryPrefixOp,
416 pub operand: &'arena Expr<'arena, 'src>,
417}
418
419#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
420pub enum UnaryPrefixOp {
421 Negate,
423 Plus,
425 BooleanNot,
427 BitwiseNot,
429 PreIncrement,
431 PreDecrement,
433}
434
435#[derive(Debug, Serialize)]
436pub struct UnaryPostfixExpr<'arena, 'src> {
437 pub operand: &'arena Expr<'arena, 'src>,
438 pub op: UnaryPostfixOp,
439}
440
441#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
442pub enum UnaryPostfixOp {
443 PostIncrement,
445 PostDecrement,
447}
448
449#[derive(Debug, Serialize)]
450pub struct TernaryExpr<'arena, 'src> {
451 pub condition: &'arena Expr<'arena, 'src>,
452 pub then_expr: Option<&'arena Expr<'arena, 'src>>,
454 pub else_expr: &'arena Expr<'arena, 'src>,
455}
456
457#[derive(Debug, Serialize)]
458pub struct NullCoalesceExpr<'arena, 'src> {
459 pub left: &'arena Expr<'arena, 'src>,
460 pub right: &'arena Expr<'arena, 'src>,
461}
462
463#[derive(Debug, Serialize)]
464pub struct FunctionCallExpr<'arena, 'src> {
465 pub name: &'arena Expr<'arena, 'src>,
466 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
467}
468
469#[derive(Debug, Serialize)]
470pub struct ArrayElement<'arena, 'src> {
471 pub key: Option<Expr<'arena, 'src>>,
472 pub value: Expr<'arena, 'src>,
473 pub unpack: bool,
474 #[serde(skip_serializing_if = "is_false")]
475 pub by_ref: bool,
476 pub span: Span,
477}
478
479#[derive(Debug, Serialize)]
480pub struct ArrayAccessExpr<'arena, 'src> {
481 pub array: &'arena Expr<'arena, 'src>,
482 pub index: Option<&'arena Expr<'arena, 'src>>,
483}
484
485#[derive(Debug, Serialize)]
488pub struct NewExpr<'arena, 'src> {
489 pub class: &'arena Expr<'arena, 'src>,
490 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
491}
492
493#[derive(Debug, Serialize)]
494pub struct PropertyAccessExpr<'arena, 'src> {
495 pub object: &'arena Expr<'arena, 'src>,
496 pub property: &'arena Expr<'arena, 'src>,
497}
498
499#[derive(Debug, Serialize)]
500pub struct MethodCallExpr<'arena, 'src> {
501 pub object: &'arena Expr<'arena, 'src>,
502 pub method: &'arena Expr<'arena, 'src>,
503 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
504}
505
506#[derive(Debug, Serialize)]
507pub struct StaticAccessExpr<'arena, 'src> {
508 pub class: &'arena Expr<'arena, 'src>,
509 pub member: &'arena Expr<'arena, 'src>,
510}
511
512#[derive(Debug, Serialize)]
513pub struct StaticMethodCallExpr<'arena, 'src> {
514 pub class: &'arena Expr<'arena, 'src>,
515 pub method: &'arena Expr<'arena, 'src>,
516 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
517}
518
519#[derive(Debug, Serialize)]
520pub struct StaticDynMethodCallExpr<'arena, 'src> {
521 pub class: &'arena Expr<'arena, 'src>,
522 pub method: &'arena Expr<'arena, 'src>,
523 pub args: ArenaVec<'arena, Arg<'arena, 'src>>,
524}
525
526#[derive(Debug, Serialize)]
527pub struct ClosureExpr<'arena, 'src> {
528 pub is_static: bool,
529 pub by_ref: bool,
530 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
531 pub use_vars: ArenaVec<'arena, ClosureUseVar<'src>>,
532 pub return_type: Option<TypeHint<'arena, 'src>>,
533 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
534 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
535}
536
537#[derive(Debug, Clone, Serialize)]
538pub struct ClosureUseVar<'src> {
539 pub name: &'src str,
540 pub by_ref: bool,
541 pub span: Span,
542}
543
544#[derive(Debug, Serialize)]
545pub struct ArrowFunctionExpr<'arena, 'src> {
546 pub is_static: bool,
547 pub by_ref: bool,
548 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
549 pub return_type: Option<TypeHint<'arena, 'src>>,
550 pub body: &'arena Expr<'arena, 'src>,
551 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
552}
553
554#[derive(Debug, Serialize)]
555pub struct MatchExpr<'arena, 'src> {
556 pub subject: &'arena Expr<'arena, 'src>,
557 pub arms: ArenaVec<'arena, MatchArm<'arena, 'src>>,
558}
559
560#[derive(Debug, Serialize)]
561pub struct MatchArm<'arena, 'src> {
562 pub conditions: Option<ArenaVec<'arena, Expr<'arena, 'src>>>,
564 pub body: Expr<'arena, 'src>,
565 pub span: Span,
566}
567
568#[derive(Debug, Serialize)]
569pub struct YieldExpr<'arena, 'src> {
570 pub key: Option<&'arena Expr<'arena, 'src>>,
571 pub value: Option<&'arena Expr<'arena, 'src>>,
572 pub is_from: bool,
574}
575
576#[derive(Debug, Serialize)]
579pub struct CallableCreateExpr<'arena, 'src> {
580 pub kind: CallableCreateKind<'arena, 'src>,
581}
582
583#[derive(Debug, Serialize)]
584pub enum CallableCreateKind<'arena, 'src> {
585 Function(&'arena Expr<'arena, 'src>),
587 Method {
589 object: &'arena Expr<'arena, 'src>,
590 method: &'arena Expr<'arena, 'src>,
591 },
592 NullsafeMethod {
594 object: &'arena Expr<'arena, 'src>,
595 method: &'arena Expr<'arena, 'src>,
596 },
597 StaticMethod {
599 class: &'arena Expr<'arena, 'src>,
600 method: &'arena Expr<'arena, 'src>,
601 },
602}
603
604#[derive(Debug, Serialize)]
607pub enum StringPart<'arena, 'src> {
608 Literal(&'arena str),
610 Expr(Expr<'arena, 'src>),
612}