1use crate::lexer::token::Token;
2use crate::span::{LineInfo, Span};
3use serde::Serialize;
4
5pub mod locator;
6pub mod sexpr;
7pub mod symbol_table;
8pub mod visitor;
9
10pub type ExprId<'ast> = &'ast Expr<'ast>;
11pub type StmtId<'ast> = &'ast Stmt<'ast>;
12
13#[derive(Debug, Clone, Copy, Serialize)]
14pub struct ParseError {
15 pub span: Span,
16 pub message: &'static str,
17}
18
19impl ParseError {
20 pub fn to_human_readable(&self, source: &[u8]) -> String {
21 self.to_human_readable_with_path(source, None)
22 }
23
24 pub fn to_human_readable_with_path(&self, source: &[u8], path: Option<&str>) -> String {
25 let Some(LineInfo {
26 line,
27 column,
28 line_text,
29 }) = self.span.line_info(source)
30 else {
31 return format!("error: {}", self.message);
32 };
33
34 let line_str = String::from_utf8_lossy(line_text);
35 let gutter_width = line.to_string().len();
36 let padding = std::cmp::min(line_text.len(), column.saturating_sub(1));
37 let highlight_len = std::cmp::max(
38 1,
39 std::cmp::min(self.span.len(), line_text.len().saturating_sub(padding)),
40 );
41
42 let mut marker = String::new();
43 marker.push_str(&" ".repeat(padding));
44 marker.push_str(&"^".repeat(highlight_len));
45
46 let location = match path {
47 Some(path) => format!("{path}:{line}:{column}"),
48 None => format!("line {line}, column {column}"),
49 };
50
51 format!(
52 "error: {}\n --> {}\n{gutter}|\n{line_no:>width$} | {line_src}\n{gutter}| {marker}",
53 self.message,
54 location,
55 gutter = " ".repeat(gutter_width + 1),
56 line_no = line,
57 width = gutter_width,
58 line_src = line_str,
59 marker = marker,
60 )
61 }
62}
63
64#[derive(Debug, Serialize)]
65pub struct Program<'ast> {
66 pub statements: &'ast [StmtId<'ast>],
67 pub errors: &'ast [ParseError],
68 pub span: Span,
69}
70
71#[derive(Debug, Serialize)]
72pub enum Stmt<'ast> {
73 Echo {
74 exprs: &'ast [ExprId<'ast>],
75 span: Span,
76 },
77 Return {
78 expr: Option<ExprId<'ast>>,
79 span: Span,
80 },
81 If {
82 condition: ExprId<'ast>,
83 then_block: &'ast [StmtId<'ast>],
84 else_block: Option<&'ast [StmtId<'ast>]>, span: Span,
86 },
87 While {
88 condition: ExprId<'ast>,
89 body: &'ast [StmtId<'ast>],
90 span: Span,
91 },
92 DoWhile {
93 body: &'ast [StmtId<'ast>],
94 condition: ExprId<'ast>,
95 span: Span,
96 },
97 For {
98 init: &'ast [ExprId<'ast>],
99 condition: &'ast [ExprId<'ast>], loop_expr: &'ast [ExprId<'ast>],
101 body: &'ast [StmtId<'ast>],
102 span: Span,
103 },
104 Foreach {
105 expr: ExprId<'ast>,
106 key_var: Option<ExprId<'ast>>,
107 value_var: ExprId<'ast>,
108 body: &'ast [StmtId<'ast>],
109 span: Span,
110 },
111 Block {
112 statements: &'ast [StmtId<'ast>],
113 span: Span,
114 },
115 Function {
116 attributes: &'ast [AttributeGroup<'ast>],
117 name: &'ast Token,
118 by_ref: bool,
119 params: &'ast [Param<'ast>],
120 return_type: Option<&'ast Type<'ast>>,
121 body: &'ast [StmtId<'ast>],
122 doc_comment: Option<Span>,
123 span: Span,
124 },
125 Class {
126 attributes: &'ast [AttributeGroup<'ast>],
127 modifiers: &'ast [Token],
128 name: &'ast Token,
129 extends: Option<Name<'ast>>,
130 implements: &'ast [Name<'ast>],
131 members: &'ast [ClassMember<'ast>],
132 doc_comment: Option<Span>,
133 span: Span,
134 },
135 Interface {
136 attributes: &'ast [AttributeGroup<'ast>],
137 name: &'ast Token,
138 extends: &'ast [Name<'ast>],
139 members: &'ast [ClassMember<'ast>],
140 doc_comment: Option<Span>,
141 span: Span,
142 },
143 Trait {
144 attributes: &'ast [AttributeGroup<'ast>],
145 name: &'ast Token,
146 members: &'ast [ClassMember<'ast>],
147 doc_comment: Option<Span>,
148 span: Span,
149 },
150 Enum {
151 attributes: &'ast [AttributeGroup<'ast>],
152 name: &'ast Token,
153 backed_type: Option<&'ast Type<'ast>>,
154 implements: &'ast [Name<'ast>],
155 members: &'ast [ClassMember<'ast>],
156 doc_comment: Option<Span>,
157 span: Span,
158 },
159 Namespace {
160 name: Option<Name<'ast>>,
161 body: Option<&'ast [StmtId<'ast>]>,
162 span: Span,
163 },
164 Use {
165 uses: &'ast [UseItem<'ast>],
166 kind: UseKind,
167 span: Span,
168 },
169 Switch {
170 condition: ExprId<'ast>,
171 cases: &'ast [Case<'ast>],
172 span: Span,
173 },
174 Try {
175 body: &'ast [StmtId<'ast>],
176 catches: &'ast [Catch<'ast>],
177 finally: Option<&'ast [StmtId<'ast>]>,
178 span: Span,
179 },
180 Throw {
181 expr: ExprId<'ast>,
182 span: Span,
183 },
184 Const {
185 attributes: &'ast [AttributeGroup<'ast>],
186 consts: &'ast [ClassConst<'ast>],
187 doc_comment: Option<Span>,
188 span: Span,
189 },
190 Break {
191 level: Option<ExprId<'ast>>,
192 span: Span,
193 },
194 Continue {
195 level: Option<ExprId<'ast>>,
196 span: Span,
197 },
198 Global {
199 vars: &'ast [ExprId<'ast>],
200 span: Span,
201 },
202 Static {
203 vars: &'ast [StaticVar<'ast>],
204 span: Span,
205 },
206 Unset {
207 vars: &'ast [ExprId<'ast>],
208 span: Span,
209 },
210 Expression {
211 expr: ExprId<'ast>,
212 span: Span,
213 },
214 InlineHtml {
215 value: &'ast [u8],
216 span: Span,
217 },
218 Nop {
219 span: Span,
220 },
221 Label {
222 name: &'ast Token,
223 span: Span,
224 },
225 Goto {
226 label: &'ast Token,
227 span: Span,
228 },
229 Error {
230 span: Span,
231 },
232 Declare {
233 declares: &'ast [DeclareItem<'ast>],
234 body: &'ast [StmtId<'ast>],
235 span: Span,
236 },
237 HaltCompiler {
238 span: Span,
239 },
240}
241
242#[derive(Debug, Clone, Copy, Serialize)]
243pub struct StaticVar<'ast> {
244 pub var: ExprId<'ast>,
245 pub default: Option<ExprId<'ast>>,
246 pub span: Span,
247}
248
249#[derive(Debug, Clone, Copy, Serialize)]
250pub struct Param<'ast> {
251 pub attributes: &'ast [AttributeGroup<'ast>],
252 pub modifiers: &'ast [Token],
253 pub name: &'ast Token,
254 pub ty: Option<&'ast Type<'ast>>,
255 pub default: Option<ExprId<'ast>>,
256 pub by_ref: bool,
257 pub variadic: bool,
258 pub hooks: Option<&'ast [PropertyHook<'ast>]>,
259 pub span: Span,
260}
261
262#[derive(Debug, Serialize)]
263pub enum Expr<'ast> {
264 Assign {
265 var: ExprId<'ast>,
266 expr: ExprId<'ast>,
267 span: Span,
268 },
269 AssignRef {
270 var: ExprId<'ast>,
271 expr: ExprId<'ast>,
272 span: Span,
273 },
274 AssignOp {
275 var: ExprId<'ast>,
276 op: AssignOp,
277 expr: ExprId<'ast>,
278 span: Span,
279 },
280 Binary {
281 left: ExprId<'ast>,
282 op: BinaryOp,
283 right: ExprId<'ast>,
284 span: Span,
285 },
286 Unary {
287 op: UnaryOp,
288 expr: ExprId<'ast>,
289 span: Span,
290 },
291 Call {
292 func: ExprId<'ast>,
293 args: &'ast [Arg<'ast>],
294 span: Span,
295 },
296 Array {
297 items: &'ast [ArrayItem<'ast>],
298 span: Span,
299 },
300 ArrayDimFetch {
301 array: ExprId<'ast>,
302 dim: Option<ExprId<'ast>>, span: Span,
304 },
305 PropertyFetch {
306 target: ExprId<'ast>,
307 property: ExprId<'ast>, span: Span,
309 },
310 MethodCall {
311 target: ExprId<'ast>,
312 method: ExprId<'ast>,
313 args: &'ast [Arg<'ast>],
314 span: Span,
315 },
316 StaticCall {
317 class: ExprId<'ast>,
318 method: ExprId<'ast>,
319 args: &'ast [Arg<'ast>],
320 span: Span,
321 },
322 ClassConstFetch {
323 class: ExprId<'ast>,
324 constant: ExprId<'ast>,
325 span: Span,
326 },
327 New {
328 class: ExprId<'ast>,
329 args: &'ast [Arg<'ast>],
330 span: Span,
331 },
332 Variable {
333 name: Span,
334 span: Span,
335 },
336 IndirectVariable {
337 name: ExprId<'ast>,
338 span: Span,
339 },
340 Integer {
341 value: &'ast [u8],
342 span: Span,
343 },
344 Float {
345 value: &'ast [u8],
346 span: Span,
347 },
348 Boolean {
349 value: bool,
350 span: Span,
351 },
352 Null {
353 span: Span,
354 },
355 String {
356 value: &'ast [u8],
357 span: Span,
358 },
359 InterpolatedString {
360 parts: &'ast [ExprId<'ast>],
361 span: Span,
362 },
363 ShellExec {
364 parts: &'ast [ExprId<'ast>],
365 span: Span,
366 },
367 Include {
368 kind: IncludeKind,
369 expr: ExprId<'ast>,
370 span: Span,
371 },
372 MagicConst {
373 kind: MagicConstKind,
374 span: Span,
375 },
376 PostInc {
377 var: ExprId<'ast>,
378 span: Span,
379 },
380 PostDec {
381 var: ExprId<'ast>,
382 span: Span,
383 },
384 Ternary {
385 condition: ExprId<'ast>,
386 if_true: Option<ExprId<'ast>>,
387 if_false: ExprId<'ast>,
388 span: Span,
389 },
390 Match {
391 condition: ExprId<'ast>,
392 arms: &'ast [MatchArm<'ast>],
393 span: Span,
394 },
395 AnonymousClass {
396 attributes: &'ast [AttributeGroup<'ast>],
397 modifiers: &'ast [Token],
398 args: &'ast [Arg<'ast>],
399 extends: Option<Name<'ast>>,
400 implements: &'ast [Name<'ast>],
401 members: &'ast [ClassMember<'ast>],
402 span: Span,
403 },
404 Print {
405 expr: ExprId<'ast>,
406 span: Span,
407 },
408 Yield {
409 key: Option<ExprId<'ast>>,
410 value: Option<ExprId<'ast>>,
411 from: bool,
412 span: Span,
413 },
414 Cast {
415 kind: CastKind,
416 expr: ExprId<'ast>,
417 span: Span,
418 },
419 Empty {
420 expr: ExprId<'ast>,
421 span: Span,
422 },
423 Isset {
424 vars: &'ast [ExprId<'ast>],
425 span: Span,
426 },
427 Eval {
428 expr: ExprId<'ast>,
429 span: Span,
430 },
431 Die {
432 expr: Option<ExprId<'ast>>,
433 span: Span,
434 },
435 Exit {
436 expr: Option<ExprId<'ast>>,
437 span: Span,
438 },
439 Closure {
440 attributes: &'ast [AttributeGroup<'ast>],
441 is_static: bool,
442 by_ref: bool,
443 params: &'ast [Param<'ast>],
444 uses: &'ast [ClosureUse<'ast>],
445 return_type: Option<&'ast Type<'ast>>,
446 body: &'ast [StmtId<'ast>],
447 span: Span,
448 },
449 ArrowFunction {
450 attributes: &'ast [AttributeGroup<'ast>],
451 is_static: bool,
452 by_ref: bool,
453 params: &'ast [Param<'ast>],
454 return_type: Option<&'ast Type<'ast>>,
455 expr: ExprId<'ast>,
456 span: Span,
457 },
458 Clone {
459 expr: ExprId<'ast>,
460 span: Span,
461 },
462 NullsafePropertyFetch {
463 target: ExprId<'ast>,
464 property: ExprId<'ast>,
465 span: Span,
466 },
467 NullsafeMethodCall {
468 target: ExprId<'ast>,
469 method: ExprId<'ast>,
470 args: &'ast [Arg<'ast>],
471 span: Span,
472 },
473 VariadicPlaceholder {
474 span: Span,
475 },
476 Error {
477 span: Span,
478 },
479}
480
481#[derive(Debug, Clone, Copy, Serialize)]
482pub struct ClosureUse<'ast> {
483 pub var: &'ast Token,
484 pub by_ref: bool,
485 pub span: Span,
486}
487
488#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
489pub enum CastKind {
490 Int,
491 Bool,
492 Float,
493 String,
494 Array,
495 Object,
496 Unset,
497 Void,
498}
499
500#[derive(Debug, Clone, Copy, Serialize)]
501pub struct MatchArm<'ast> {
502 pub conditions: Option<&'ast [ExprId<'ast>]>, pub body: ExprId<'ast>,
504 pub span: Span,
505}
506
507#[derive(Debug, Clone, Copy, Serialize)]
508pub struct AnonymousClass<'ast> {
509 pub args: &'ast [Arg<'ast>],
510 pub extends: Option<Name<'ast>>,
511 pub implements: &'ast [Name<'ast>],
512 pub members: &'ast [ClassMember<'ast>],
513 pub span: Span,
514}
515
516#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
517pub enum UnaryOp {
518 Plus,
519 Minus,
520 Not,
521 BitNot,
522 PreInc,
523 PreDec,
524 ErrorSuppress,
525 Reference,
526}
527
528impl<'ast> Expr<'ast> {
529 pub fn span(&self) -> Span {
530 match self {
531 Expr::Assign { span, .. } => *span,
532 Expr::AssignRef { span, .. } => *span,
533 Expr::AssignOp { span, .. } => *span,
534 Expr::Binary { span, .. } => *span,
535 Expr::Unary { span, .. } => *span,
536 Expr::Call { span, .. } => *span,
537 Expr::Array { span, .. } => *span,
538 Expr::ArrayDimFetch { span, .. } => *span,
539 Expr::PropertyFetch { span, .. } => *span,
540 Expr::MethodCall { span, .. } => *span,
541 Expr::StaticCall { span, .. } => *span,
542 Expr::ClassConstFetch { span, .. } => *span,
543 Expr::New { span, .. } => *span,
544 Expr::Variable { span, .. } => *span,
545 Expr::Integer { span, .. } => *span,
546 Expr::Float { span, .. } => *span,
547 Expr::Boolean { span, .. } => *span,
548 Expr::Null { span, .. } => *span,
549 Expr::String { span, .. } => *span,
550 Expr::InterpolatedString { span, .. } => *span,
551 Expr::ShellExec { span, .. } => *span,
552 Expr::Include { span, .. } => *span,
553 Expr::MagicConst { span, .. } => *span,
554 Expr::PostInc { span, .. } => *span,
555 Expr::PostDec { span, .. } => *span,
556 Expr::Ternary { span, .. } => *span,
557 Expr::Match { span, .. } => *span,
558 Expr::AnonymousClass { span, .. } => *span,
559 Expr::Yield { span, .. } => *span,
560 Expr::Cast { span, .. } => *span,
561 Expr::Empty { span, .. } => *span,
562 Expr::Isset { span, .. } => *span,
563 Expr::Eval { span, .. } => *span,
564 Expr::Die { span, .. } => *span,
565 Expr::Exit { span, .. } => *span,
566 Expr::Closure { span, .. } => *span,
567 Expr::ArrowFunction { span, .. } => *span,
568 Expr::Clone { span, .. } => *span,
569 Expr::Print { span, .. } => *span,
570 Expr::NullsafePropertyFetch { span, .. } => *span,
571 Expr::NullsafeMethodCall { span, .. } => *span,
572 Expr::VariadicPlaceholder { span } => *span,
573 Expr::Error { span } => *span,
574 Expr::IndirectVariable { span, .. } => *span,
575 }
576 }
577}
578
579impl<'ast> Stmt<'ast> {
580 pub fn span(&self) -> Span {
581 match self {
582 Stmt::Echo { span, .. } => *span,
583 Stmt::Return { span, .. } => *span,
584 Stmt::If { span, .. } => *span,
585 Stmt::While { span, .. } => *span,
586 Stmt::DoWhile { span, .. } => *span,
587 Stmt::For { span, .. } => *span,
588 Stmt::Foreach { span, .. } => *span,
589 Stmt::Block { span, .. } => *span,
590 Stmt::Function { span, .. } => *span,
591 Stmt::Class { span, .. } => *span,
592 Stmt::Interface { span, .. } => *span,
593 Stmt::Trait { span, .. } => *span,
594 Stmt::Enum { span, .. } => *span,
595 Stmt::Namespace { span, .. } => *span,
596 Stmt::Use { span, .. } => *span,
597 Stmt::Switch { span, .. } => *span,
598 Stmt::Try { span, .. } => *span,
599 Stmt::Throw { span, .. } => *span,
600 Stmt::Const { span, .. } => *span,
601 Stmt::Break { span, .. } => *span,
602 Stmt::Continue { span, .. } => *span,
603 Stmt::Global { span, .. } => *span,
604 Stmt::Static { span, .. } => *span,
605 Stmt::Unset { span, .. } => *span,
606 Stmt::Expression { span, .. } => *span,
607 Stmt::InlineHtml { span, .. } => *span,
608 Stmt::Declare { span, .. } => *span,
609 Stmt::HaltCompiler { span } => *span,
610 Stmt::Label { span, .. } => *span,
611 Stmt::Goto { span, .. } => *span,
612 Stmt::Error { span } => *span,
613 Stmt::Nop { span } => *span,
614 }
615 }
616}
617
618#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
619pub enum BinaryOp {
620 Plus,
621 Minus,
622 Mul,
623 Div,
624 Mod,
625 Concat, Eq,
627 EqEq,
628 EqEqEq,
629 NotEq,
630 NotEqEq,
631 Lt,
632 LtEq,
633 Gt,
634 GtEq,
635 And,
636 Or,
637 BitAnd,
638 BitOr,
639 BitXor,
640 Coalesce,
641 Spaceship,
642 Pow,
643 ShiftLeft,
644 ShiftRight,
645 LogicalAnd,
646 LogicalOr,
647 LogicalXor,
648 Instanceof,
649}
650
651#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
652pub enum AssignOp {
653 Plus, Minus, Mul, Div, Mod, Concat, BitAnd, BitOr, BitXor, ShiftLeft, ShiftRight, Pow, Coalesce, }
667
668#[derive(Debug, Clone, Copy, Serialize)]
669pub struct Arg<'ast> {
670 pub name: Option<&'ast Token>,
671 pub value: ExprId<'ast>,
672 pub unpack: bool,
673 pub span: Span,
674}
675
676#[derive(Debug, Clone, Copy, Serialize)]
677pub struct ArrayItem<'ast> {
678 pub key: Option<ExprId<'ast>>,
679 pub value: ExprId<'ast>,
680 pub by_ref: bool,
681 pub unpack: bool,
682 pub span: Span,
683}
684
685#[derive(Debug, Clone, Copy, Serialize)]
686pub struct PropertyEntry<'ast> {
687 pub name: &'ast Token,
688 pub default: Option<ExprId<'ast>>,
689 pub span: Span,
690}
691
692#[derive(Debug, Clone, Copy, Serialize)]
693pub enum ClassMember<'ast> {
694 Property {
695 attributes: &'ast [AttributeGroup<'ast>],
696 modifiers: &'ast [Token],
697 ty: Option<&'ast Type<'ast>>,
698 entries: &'ast [PropertyEntry<'ast>],
699 doc_comment: Option<Span>,
700 span: Span,
701 },
702 PropertyHook {
703 attributes: &'ast [AttributeGroup<'ast>],
704 modifiers: &'ast [Token],
705 ty: Option<&'ast Type<'ast>>,
706 name: &'ast Token,
707 default: Option<ExprId<'ast>>,
708 hooks: &'ast [PropertyHook<'ast>],
709 doc_comment: Option<Span>,
710 span: Span,
711 },
712 Method {
713 attributes: &'ast [AttributeGroup<'ast>],
714 modifiers: &'ast [Token],
715 name: &'ast Token,
716 params: &'ast [Param<'ast>],
717 return_type: Option<&'ast Type<'ast>>,
718 body: &'ast [StmtId<'ast>],
719 doc_comment: Option<Span>,
720 span: Span,
721 },
722 Const {
723 attributes: &'ast [AttributeGroup<'ast>],
724 modifiers: &'ast [Token],
725 ty: Option<&'ast Type<'ast>>,
726 consts: &'ast [ClassConst<'ast>],
727 doc_comment: Option<Span>,
728 span: Span,
729 },
730 TraitUse {
731 attributes: &'ast [AttributeGroup<'ast>],
732 traits: &'ast [Name<'ast>],
733 adaptations: &'ast [TraitAdaptation<'ast>],
734 doc_comment: Option<Span>,
735 span: Span,
736 },
737 Case {
738 attributes: &'ast [AttributeGroup<'ast>],
739 name: &'ast Token,
740 value: Option<ExprId<'ast>>,
741 doc_comment: Option<Span>,
742 span: Span,
743 },
744}
745
746#[derive(Debug, Clone, Copy, Serialize)]
747pub struct Case<'ast> {
748 pub condition: Option<ExprId<'ast>>, pub body: &'ast [StmtId<'ast>],
750 pub span: Span,
751}
752
753#[derive(Debug, Clone, Copy, Serialize)]
754pub struct ClassConst<'ast> {
755 pub name: &'ast Token,
756 pub value: ExprId<'ast>,
757 pub span: Span,
758}
759
760#[derive(Debug, Clone, Copy, Serialize)]
761pub enum PropertyHookBody<'ast> {
762 None,
763 Statements(&'ast [StmtId<'ast>]),
764 Expr(ExprId<'ast>),
765}
766
767#[derive(Debug, Clone, Copy, Serialize)]
768pub struct PropertyHook<'ast> {
769 pub attributes: &'ast [AttributeGroup<'ast>],
770 pub modifiers: &'ast [Token],
771 pub name: &'ast Token,
772 pub params: &'ast [Param<'ast>],
773 pub by_ref: bool,
774 pub body: PropertyHookBody<'ast>,
775 pub span: Span,
776}
777
778#[derive(Debug, Clone, Copy, Serialize)]
779pub struct TraitMethodRef<'ast> {
780 pub trait_name: Option<Name<'ast>>,
781 pub method: &'ast Token,
782 pub span: Span,
783}
784
785#[derive(Debug, Clone, Copy, Serialize)]
786pub enum TraitAdaptation<'ast> {
787 Precedence {
788 method: TraitMethodRef<'ast>,
789 insteadof: &'ast [Name<'ast>],
790 span: Span,
791 },
792 Alias {
793 method: TraitMethodRef<'ast>,
794 alias: Option<&'ast Token>,
795 visibility: Option<&'ast Token>,
796 span: Span,
797 },
798}
799
800#[derive(Debug, Clone, Copy, Serialize)]
801pub struct Catch<'ast> {
802 pub types: &'ast [Name<'ast>], pub var: Option<&'ast Token>, pub body: &'ast [StmtId<'ast>],
805 pub span: Span,
806}
807
808#[derive(Debug, Clone, Copy, Serialize)]
809pub struct Name<'ast> {
810 pub parts: &'ast [Token],
811 pub span: Span,
812}
813
814#[derive(Debug, Clone, Copy, Serialize)]
815pub struct UseItem<'ast> {
816 pub name: Name<'ast>,
817 pub alias: Option<&'ast Token>,
818 pub kind: UseKind,
819 pub span: Span,
820}
821
822#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
823pub enum UseKind {
824 Normal,
825 Function,
826 Const,
827}
828
829#[derive(Debug, Clone, Copy, Serialize)]
830pub struct Attribute<'ast> {
831 pub name: Name<'ast>,
832 pub args: &'ast [Arg<'ast>],
833 pub span: Span,
834}
835
836#[derive(Debug, Clone, Copy, Serialize)]
837pub struct AttributeGroup<'ast> {
838 pub attributes: &'ast [Attribute<'ast>],
839 pub span: Span,
840}
841
842#[derive(Debug, Clone, Copy, Serialize)]
843pub enum Type<'ast> {
844 Simple(&'ast Token),
845 Name(Name<'ast>),
846 Union(&'ast [Type<'ast>]),
847 Intersection(&'ast [Type<'ast>]),
848 Nullable(&'ast Type<'ast>),
849}
850
851#[derive(Debug, Clone, Copy, Serialize)]
852pub struct DeclareItem<'ast> {
853 pub key: &'ast Token,
854 pub value: ExprId<'ast>,
855 pub span: Span,
856}
857
858#[derive(Debug, Clone, Copy, Serialize)]
859pub enum IncludeKind {
860 Include,
861 IncludeOnce,
862 Require,
863 RequireOnce,
864}
865
866#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
867pub enum MagicConstKind {
868 Dir,
869 File,
870 Line,
871 Function,
872 Class,
873 Trait,
874 Method,
875 Namespace,
876 Property,
877}