1#[cfg(feature = "serde")]
2use serde::Serialize;
3
4use crate::Span;
5
6use super::{ArenaVec, Attribute, Block, Comment, Expr, Ident, Name, TypeHint};
7
8#[derive(Debug)]
10#[cfg_attr(feature = "serde", derive(Serialize))]
11#[non_exhaustive]
12pub struct FunctionDecl<'arena, 'src> {
13 pub name: Ident<'src>,
15 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
17 pub body: &'arena Block<'arena, 'src>,
19 pub return_type: Option<TypeHint<'arena, 'src>>,
21 pub by_ref: bool,
23 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
25 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
32 pub doc_comment: Option<Comment<'src>>,
33}
34
35impl<'arena, 'src> FunctionDecl<'arena, 'src> {
36 pub fn new(
39 arena: &'arena bumpalo::Bump,
40 name: Ident<'src>,
41 body: &'arena Block<'arena, 'src>,
42 ) -> Self {
43 Self {
44 name,
45 params: ArenaVec::new_in(arena),
46 body,
47 return_type: None,
48 by_ref: false,
49 attributes: ArenaVec::new_in(arena),
50 doc_comment: None,
51 }
52 }
53}
54
55#[derive(Debug)]
57#[cfg_attr(feature = "serde", derive(Serialize))]
58#[non_exhaustive]
59pub struct Param<'arena, 'src> {
60 pub name: Ident<'src>,
62 pub type_hint: Option<TypeHint<'arena, 'src>>,
64 pub default: Option<Expr<'arena, 'src>>,
66 pub by_ref: bool,
68 pub variadic: bool,
70 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
72 pub modifiers: Modifiers,
73 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
75 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "ArenaVec::is_empty"))]
77 pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
78 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
83 pub doc_comment: Option<Comment<'src>>,
84 pub span: Span,
86}
87
88impl<'arena, 'src> Param<'arena, 'src> {
89 pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>, span: Span) -> Self {
94 Self {
95 name,
96 type_hint: None,
97 default: None,
98 by_ref: false,
99 variadic: false,
100 modifiers: Modifiers::new(),
101 attributes: ArenaVec::new_in(arena),
102 hooks: ArenaVec::new_in(arena),
103 doc_comment: None,
104 span,
105 }
106 }
107}
108
109#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
112#[cfg_attr(feature = "serde", derive(Serialize))]
113#[non_exhaustive]
114pub struct Modifiers {
115 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
117 pub visibility: Option<Visibility>,
118 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
120 pub set_visibility: Option<Visibility>,
121 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
123 pub is_static: bool,
124 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
126 pub is_abstract: bool,
127 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
129 pub is_final: bool,
130 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
132 pub is_readonly: bool,
133}
134
135impl Modifiers {
136 pub const fn new() -> Self {
140 Self {
141 visibility: None,
142 set_visibility: None,
143 is_static: false,
144 is_abstract: false,
145 is_final: false,
146 is_readonly: false,
147 }
148 }
149
150 pub fn is_empty(&self) -> bool {
152 *self == Self::new()
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq)]
158#[cfg_attr(feature = "serde", derive(Serialize))]
159#[non_exhaustive]
160pub enum Visibility {
161 Public,
163 Protected,
165 Private,
167}
168
169#[derive(Debug)]
171#[cfg_attr(feature = "serde", derive(Serialize))]
172pub struct ClassBody<'arena, 'src> {
173 pub members: ArenaVec<'arena, ClassMember<'arena, 'src>>,
175 #[cfg_attr(feature = "serde", serde(skip))]
177 pub span: Span,
178}
179
180#[derive(Debug)]
182#[cfg_attr(feature = "serde", derive(Serialize))]
183#[non_exhaustive]
184pub struct ClassDecl<'arena, 'src> {
185 pub name: Option<Ident<'src>>,
187 pub modifiers: ClassModifiers,
189 pub extends: Option<Name<'arena, 'src>>,
191 pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
193 #[cfg_attr(feature = "serde", serde(flatten))]
195 pub body: ClassBody<'arena, 'src>,
196 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
198 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
200 pub doc_comment: Option<Comment<'src>>,
201}
202
203impl<'arena, 'src> ClassDecl<'arena, 'src> {
204 pub fn new(
207 arena: &'arena bumpalo::Bump,
208 name: Option<Ident<'src>>,
209 body: ClassBody<'arena, 'src>,
210 ) -> Self {
211 Self {
212 name,
213 modifiers: ClassModifiers::default(),
214 extends: None,
215 implements: ArenaVec::new_in(arena),
216 body,
217 attributes: ArenaVec::new_in(arena),
218 doc_comment: None,
219 }
220 }
221}
222
223#[derive(Debug, Clone, Default)]
225#[cfg_attr(feature = "serde", derive(Serialize))]
226#[non_exhaustive]
227pub struct ClassModifiers {
228 pub is_abstract: bool,
230 pub is_final: bool,
232 pub is_readonly: bool,
234}
235
236#[derive(Debug)]
238#[cfg_attr(feature = "serde", derive(Serialize))]
239pub struct ClassMember<'arena, 'src> {
240 pub kind: ClassMemberKind<'arena, 'src>,
242 pub span: Span,
244}
245
246#[derive(Debug)]
248#[cfg_attr(feature = "serde", derive(Serialize))]
249#[non_exhaustive]
250pub enum ClassMemberKind<'arena, 'src> {
251 Property(PropertyDecl<'arena, 'src>),
253 Method(MethodDecl<'arena, 'src>),
255 ClassConst(ClassConstDecl<'arena, 'src>),
257 TraitUse(TraitUseDecl<'arena, 'src>),
259}
260
261#[derive(Debug)]
263#[cfg_attr(feature = "serde", derive(Serialize))]
264#[non_exhaustive]
265pub struct PropertyDecl<'arena, 'src> {
266 pub name: Ident<'src>,
268 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
270 pub modifiers: Modifiers,
271 pub type_hint: Option<TypeHint<'arena, 'src>>,
273 pub default: Option<Expr<'arena, 'src>>,
275 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
277 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "ArenaVec::is_empty"))]
279 pub hooks: ArenaVec<'arena, PropertyHook<'arena, 'src>>,
280 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
282 pub doc_comment: Option<Comment<'src>>,
283}
284
285impl<'arena, 'src> PropertyDecl<'arena, 'src> {
286 pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
289 Self {
290 name,
291 modifiers: Modifiers::new(),
292 type_hint: None,
293 default: None,
294 attributes: ArenaVec::new_in(arena),
295 hooks: ArenaVec::new_in(arena),
296 doc_comment: None,
297 }
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303#[cfg_attr(feature = "serde", derive(Serialize))]
304#[non_exhaustive]
305pub enum PropertyHookKind {
306 Get,
308 Set,
310}
311
312#[derive(Debug)]
314#[cfg_attr(feature = "serde", derive(Serialize))]
315#[non_exhaustive]
316pub enum PropertyHookBody<'arena, 'src> {
317 Block(&'arena Block<'arena, 'src>),
319 Expression(Expr<'arena, 'src>),
321 Abstract,
323}
324
325#[derive(Debug)]
327#[cfg_attr(feature = "serde", derive(Serialize))]
328#[non_exhaustive]
329pub struct PropertyHook<'arena, 'src> {
330 pub kind: PropertyHookKind,
332 pub body: PropertyHookBody<'arena, 'src>,
334 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
336 pub modifiers: Modifiers,
337 pub by_ref: bool,
339 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
341 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
343 pub span: Span,
345}
346
347impl<'arena, 'src> PropertyHook<'arena, 'src> {
348 pub fn new(
351 arena: &'arena bumpalo::Bump,
352 kind: PropertyHookKind,
353 body: PropertyHookBody<'arena, 'src>,
354 span: Span,
355 ) -> Self {
356 Self {
357 kind,
358 body,
359 modifiers: Modifiers::new(),
360 by_ref: false,
361 params: ArenaVec::new_in(arena),
362 attributes: ArenaVec::new_in(arena),
363 span,
364 }
365 }
366}
367
368#[derive(Debug)]
370#[cfg_attr(feature = "serde", derive(Serialize))]
371#[non_exhaustive]
372pub struct MethodDecl<'arena, 'src> {
373 pub name: Ident<'src>,
375 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
377 pub modifiers: Modifiers,
378 pub by_ref: bool,
380 pub params: ArenaVec<'arena, Param<'arena, 'src>>,
382 pub return_type: Option<TypeHint<'arena, 'src>>,
384 pub body: Option<&'arena Block<'arena, 'src>>,
386 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
388 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
390 pub doc_comment: Option<Comment<'src>>,
391}
392
393impl<'arena, 'src> MethodDecl<'arena, 'src> {
394 pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
398 Self {
399 name,
400 modifiers: Modifiers::new(),
401 by_ref: false,
402 params: ArenaVec::new_in(arena),
403 return_type: None,
404 body: None,
405 attributes: ArenaVec::new_in(arena),
406 doc_comment: None,
407 }
408 }
409}
410
411#[derive(Debug)]
413#[cfg_attr(feature = "serde", derive(Serialize))]
414#[non_exhaustive]
415pub struct ClassConstDecl<'arena, 'src> {
416 pub name: Ident<'src>,
418 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Modifiers::is_empty"))]
420 pub modifiers: Modifiers,
421 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
423 pub type_hint: Option<&'arena TypeHint<'arena, 'src>>,
424 pub value: Expr<'arena, 'src>,
426 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
428 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
430 pub doc_comment: Option<Comment<'src>>,
431}
432
433impl<'arena, 'src> ClassConstDecl<'arena, 'src> {
434 pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>, value: Expr<'arena, 'src>) -> Self {
437 Self {
438 name,
439 modifiers: Modifiers::new(),
440 type_hint: None,
441 value,
442 attributes: ArenaVec::new_in(arena),
443 doc_comment: None,
444 }
445 }
446}
447
448#[derive(Debug)]
450#[cfg_attr(feature = "serde", derive(Serialize))]
451#[non_exhaustive]
452pub struct TraitUseDecl<'arena, 'src> {
453 pub traits: ArenaVec<'arena, Name<'arena, 'src>>,
455 pub adaptations: ArenaVec<'arena, TraitAdaptation<'arena, 'src>>,
457 #[cfg_attr(feature = "serde", serde(skip))]
460 #[doc(hidden)]
461 pub adaptations_brace_span: Option<Span>,
462 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
464 pub doc_comment: Option<Comment<'src>>,
465}
466
467impl<'arena, 'src> TraitUseDecl<'arena, 'src> {
468 pub fn new(arena: &'arena bumpalo::Bump, traits: ArenaVec<'arena, Name<'arena, 'src>>) -> Self {
471 Self {
472 traits,
473 adaptations: ArenaVec::new_in(arena),
474 adaptations_brace_span: None,
475 doc_comment: None,
476 }
477 }
478}
479
480#[derive(Debug)]
482#[cfg_attr(feature = "serde", derive(Serialize))]
483pub struct TraitAdaptation<'arena, 'src> {
484 pub kind: TraitAdaptationKind<'arena, 'src>,
486 pub span: Span,
488}
489
490#[derive(Debug)]
492#[cfg_attr(feature = "serde", derive(Serialize))]
493#[non_exhaustive]
494pub enum TraitAdaptationKind<'arena, 'src> {
495 Precedence {
497 trait_name: Name<'arena, 'src>,
499 method: Name<'arena, 'src>,
501 insteadof: ArenaVec<'arena, Name<'arena, 'src>>,
503 },
504 Alias {
506 trait_name: Option<Name<'arena, 'src>>,
508 method: Name<'arena, 'src>,
510 new_modifier: Option<Visibility>,
512 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "super::is_false"))]
514 is_final: bool,
515 new_name: Option<Name<'arena, 'src>>,
517 },
518}
519
520#[derive(Debug)]
522#[cfg_attr(feature = "serde", derive(Serialize))]
523#[non_exhaustive]
524pub struct InterfaceDecl<'arena, 'src> {
525 pub name: Ident<'src>,
527 pub extends: ArenaVec<'arena, Name<'arena, 'src>>,
529 #[cfg_attr(feature = "serde", serde(flatten))]
531 pub body: ClassBody<'arena, 'src>,
532 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
534 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
536 pub doc_comment: Option<Comment<'src>>,
537}
538
539impl<'arena, 'src> InterfaceDecl<'arena, 'src> {
540 pub fn new(
543 arena: &'arena bumpalo::Bump,
544 name: Ident<'src>,
545 body: ClassBody<'arena, 'src>,
546 ) -> Self {
547 Self {
548 name,
549 extends: ArenaVec::new_in(arena),
550 body,
551 attributes: ArenaVec::new_in(arena),
552 doc_comment: None,
553 }
554 }
555}
556
557#[derive(Debug)]
559#[cfg_attr(feature = "serde", derive(Serialize))]
560#[non_exhaustive]
561pub struct TraitDecl<'arena, 'src> {
562 pub name: Ident<'src>,
564 #[cfg_attr(feature = "serde", serde(flatten))]
566 pub body: ClassBody<'arena, 'src>,
567 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
569 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
571 pub doc_comment: Option<Comment<'src>>,
572}
573
574impl<'arena, 'src> TraitDecl<'arena, 'src> {
575 pub fn new(
578 arena: &'arena bumpalo::Bump,
579 name: Ident<'src>,
580 body: ClassBody<'arena, 'src>,
581 ) -> Self {
582 Self {
583 name,
584 body,
585 attributes: ArenaVec::new_in(arena),
586 doc_comment: None,
587 }
588 }
589}
590
591#[derive(Debug)]
593#[cfg_attr(feature = "serde", derive(Serialize))]
594pub struct EnumBody<'arena, 'src> {
595 pub members: ArenaVec<'arena, EnumMember<'arena, 'src>>,
597 #[cfg_attr(feature = "serde", serde(skip))]
599 pub span: Span,
600}
601
602#[derive(Debug)]
604#[cfg_attr(feature = "serde", derive(Serialize))]
605#[non_exhaustive]
606pub struct EnumDecl<'arena, 'src> {
607 pub name: Ident<'src>,
609 pub scalar_type: Option<Name<'arena, 'src>>,
611 pub implements: ArenaVec<'arena, Name<'arena, 'src>>,
613 #[cfg_attr(feature = "serde", serde(flatten))]
615 pub body: EnumBody<'arena, 'src>,
616 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
618 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
620 pub doc_comment: Option<Comment<'src>>,
621}
622
623impl<'arena, 'src> EnumDecl<'arena, 'src> {
624 pub fn new(
627 arena: &'arena bumpalo::Bump,
628 name: Ident<'src>,
629 body: EnumBody<'arena, 'src>,
630 ) -> Self {
631 Self {
632 name,
633 scalar_type: None,
634 implements: ArenaVec::new_in(arena),
635 body,
636 attributes: ArenaVec::new_in(arena),
637 doc_comment: None,
638 }
639 }
640}
641
642#[derive(Debug)]
644#[cfg_attr(feature = "serde", derive(Serialize))]
645pub struct EnumMember<'arena, 'src> {
646 pub kind: EnumMemberKind<'arena, 'src>,
648 pub span: Span,
650}
651
652#[derive(Debug)]
654#[cfg_attr(feature = "serde", derive(Serialize))]
655#[non_exhaustive]
656pub enum EnumMemberKind<'arena, 'src> {
657 Case(EnumCase<'arena, 'src>),
659 Method(MethodDecl<'arena, 'src>),
661 ClassConst(ClassConstDecl<'arena, 'src>),
663 TraitUse(TraitUseDecl<'arena, 'src>),
665}
666
667#[derive(Debug)]
669#[cfg_attr(feature = "serde", derive(Serialize))]
670#[non_exhaustive]
671pub struct EnumCase<'arena, 'src> {
672 pub name: Ident<'src>,
674 pub value: Option<Expr<'arena, 'src>>,
676 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
678 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
680 pub doc_comment: Option<Comment<'src>>,
681}
682
683impl<'arena, 'src> EnumCase<'arena, 'src> {
684 pub fn new(arena: &'arena bumpalo::Bump, name: Ident<'src>) -> Self {
687 Self {
688 name,
689 value: None,
690 attributes: ArenaVec::new_in(arena),
691 doc_comment: None,
692 }
693 }
694}