Skip to main content

java_lang/ast/
item.rs

1//! Item types (class, interface, enum, record, module declarations).
2
3use crate::{ident::Ident, span::Span};
4
5use super::{
6    Comment,
7    attribute::Annotation,
8    expr::Expr,
9    generics::TypeParameters,
10    stmt::{Block, Stmt},
11    ty::Type,
12};
13
14/// A top-level type declaration or semicolon.
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub enum TypeDecl {
17    Class(ClassDecl),
18    Interface(InterfaceDecl),
19    Enum(EnumDecl),
20    Record(RecordDecl),
21    AnnotationType(AnnotationInterfaceDecl),
22    /// A standalone semicolon in the top level.
23    Empty(Span),
24}
25
26impl TypeDecl {
27    pub fn span(&self) -> Span {
28        match self {
29            Self::Class(c) => c.span(),
30            Self::Interface(i) => i.span(),
31            Self::Enum(e) => e.span(),
32            Self::Record(r) => r.span(),
33            Self::AnnotationType(a) => a.span(),
34            Self::Empty(s) => *s,
35        }
36    }
37}
38
39/// A class declaration.
40#[derive(Debug, Clone, PartialEq, Eq, Hash)]
41pub struct ClassDecl {
42    pub doc_comment: Vec<Comment>,
43    pub modifiers: Vec<Modifier>,
44    pub class_span: Span,
45    pub name: Ident,
46    pub type_params: Option<TypeParameters>,
47    pub extends_clause: Option<ExtendsClause>,
48    pub implements_clause: Option<ImplementsClause>,
49    pub permits_clause: Option<PermitsClause>,
50    pub body: ClassBodyDeclList,
51}
52
53impl ClassDecl {
54    pub fn span(&self) -> Span {
55        let code_start = self.modifiers.first().map_or(self.class_span, |m| m.span());
56        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
57        start.join(self.body.brace_span.1)
58    }
59}
60
61/// An interface declaration.
62#[derive(Debug, Clone, PartialEq, Eq, Hash)]
63pub struct InterfaceDecl {
64    pub doc_comment: Vec<Comment>,
65    pub modifiers: Vec<Modifier>,
66    pub interface_span: Span,
67    pub name: Ident,
68    pub type_params: Option<TypeParameters>,
69    pub extends_clause: Option<InterfaceExtendsClause>,
70    pub permits_clause: Option<PermitsClause>,
71    pub body: InterfaceBody,
72}
73
74impl InterfaceDecl {
75    pub fn span(&self) -> Span {
76        let code_start = self
77            .modifiers
78            .first()
79            .map_or(self.interface_span, |m| m.span());
80        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
81        start.join(self.body.brace_span.1)
82    }
83}
84
85/// An enum declaration.
86#[derive(Debug, Clone, PartialEq, Eq, Hash)]
87pub struct EnumDecl {
88    pub doc_comment: Vec<Comment>,
89    pub modifiers: Vec<Modifier>,
90    pub enum_span: Span,
91    pub name: Ident,
92    pub implements_clause: Option<ImplementsClause>,
93    pub body: EnumBody,
94}
95
96impl EnumDecl {
97    pub fn span(&self) -> Span {
98        let code_start = self.modifiers.first().map_or(self.enum_span, |m| m.span());
99        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
100        start.join(self.body.brace_span.1)
101    }
102}
103
104/// A record declaration (Java 16+).
105#[derive(Debug, Clone, PartialEq, Eq, Hash)]
106pub struct RecordDecl {
107    pub doc_comment: Vec<Comment>,
108    pub modifiers: Vec<Modifier>,
109    pub record_span: Span,
110    pub name: Ident,
111    pub type_params: Option<TypeParameters>,
112    pub components: RecordComponents,
113    pub implements_clause: Option<ImplementsClause>,
114    pub body: RecordBody,
115}
116
117impl RecordDecl {
118    pub fn span(&self) -> Span {
119        let code_start = self
120            .modifiers
121            .first()
122            .map_or(self.record_span, |m| m.span());
123        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
124        start.join(self.body.brace_span.1)
125    }
126}
127
128/// A module declaration.
129#[derive(Debug, Clone, PartialEq, Eq, Hash)]
130pub struct ModuleDecl {
131    pub doc_comment: Vec<Comment>,
132    pub annotations: Vec<Annotation>,
133    pub open_span: Option<Span>,
134    pub module_span: Span,
135    pub name: crate::ast::path::Path,
136    pub brace_span: (Span, Span),
137    pub directives: Vec<ModuleDirective>,
138}
139
140impl ModuleDecl {
141    pub fn span(&self) -> Span {
142        let code_start = self
143            .annotations
144            .first()
145            .map_or(self.module_span, |a| a.span());
146        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
147        start.join(self.brace_span.1)
148    }
149}
150
151/// A module directive.
152#[derive(Debug, Clone, PartialEq, Eq, Hash)]
153pub enum ModuleDirective {
154    Requires {
155        requires_span: Span,
156        modifiers: Vec<RequiresModifier>,
157        module: crate::ast::path::Path,
158        semi_span: Span,
159    },
160    Exports {
161        exports_span: Span,
162        pkg: crate::ast::path::Path,
163        to_modules: Option<(Span, Vec<crate::ast::path::Path>)>,
164        semi_span: Span,
165    },
166    Opens {
167        opens_span: Span,
168        pkg: crate::ast::path::Path,
169        to_modules: Option<(Span, Vec<crate::ast::path::Path>)>,
170        semi_span: Span,
171    },
172    Uses {
173        uses_span: Span,
174        ty: Type,
175        semi_span: Span,
176    },
177    Provides {
178        provides_span: Span,
179        ty: Type,
180        with_span: Span,
181        impls: Vec<Type>,
182        semi_span: Span,
183    },
184}
185
186/// Requires modifier: `transitive`, `static`.
187#[derive(Debug, Clone, PartialEq, Eq, Hash)]
188pub enum RequiresModifier {
189    Transitive(Span),
190    Static(Span),
191}
192
193/// A modifier (keyword or annotation).
194#[derive(Debug, Clone, PartialEq, Eq, Hash)]
195pub enum Modifier {
196    /// `public`
197    Public(Span),
198    /// `protected`
199    Protected(Span),
200    /// `private`
201    Private(Span),
202    /// `static`
203    Static(Span),
204    /// `abstract`
205    Abstract(Span),
206    /// `final`
207    Final(Span),
208    /// `synchronized`
209    Synchronized(Span),
210    /// `native`
211    Native(Span),
212    /// `strictfp`
213    Strictfp(Span),
214    /// `transient`
215    Transient(Span),
216    /// `volatile`
217    Volatile(Span),
218    /// `default`
219    Default(Span),
220    /// `sealed`
221    Sealed(Span),
222    /// `non-sealed`
223    NonSealed(Span),
224    /// An annotation
225    Annotation(Annotation),
226}
227
228impl Modifier {
229    pub fn span(&self) -> Span {
230        match self {
231            Self::Public(s)
232            | Self::Protected(s)
233            | Self::Private(s)
234            | Self::Static(s)
235            | Self::Abstract(s)
236            | Self::Final(s)
237            | Self::Synchronized(s)
238            | Self::Native(s)
239            | Self::Strictfp(s)
240            | Self::Transient(s)
241            | Self::Volatile(s)
242            | Self::Default(s)
243            | Self::Sealed(s)
244            | Self::NonSealed(s) => *s,
245            Self::Annotation(a) => a.span(),
246        }
247    }
248
249    /// Check if this modifier is an access modifier.
250    pub fn is_access_modifier(&self) -> bool {
251        matches!(
252            self,
253            Self::Public(_) | Self::Protected(_) | Self::Private(_)
254        )
255    }
256
257    /// Check if this modifier is an annotation.
258    pub fn is_annotation(&self) -> bool {
259        matches!(self, Self::Annotation(_))
260    }
261}
262
263/// An `extends` clause: `extends SuperClass`.
264#[derive(Debug, Clone, PartialEq, Eq, Hash)]
265pub struct ExtendsClause {
266    pub extends_span: Span,
267    pub supertype: Type,
268}
269
270/// An `implements` clause: `implements Interface1, Interface2`.
271#[derive(Debug, Clone, PartialEq, Eq, Hash)]
272pub struct ImplementsClause {
273    pub implements_span: Span,
274    pub supertypes: Vec<Type>,
275}
276
277/// An interface extends clause: `extends Interface1, Interface2`.
278#[derive(Debug, Clone, PartialEq, Eq, Hash)]
279pub struct InterfaceExtendsClause {
280    pub extends_span: Span,
281    pub supertypes: Vec<Type>,
282}
283
284/// A `permits` clause: `permits Sub1, Sub2`.
285#[derive(Debug, Clone, PartialEq, Eq, Hash)]
286pub struct PermitsClause {
287    pub permits_span: Span,
288    pub types: Vec<Type>,
289}
290
291/// Class body: `{ members }`.
292#[derive(Debug, Clone, PartialEq, Eq, Hash)]
293pub struct ClassBodyDeclList {
294    pub brace_span: (Span, Span),
295    pub declarations: Vec<ClassBodyDecl>,
296}
297
298/// A declaration inside a class body.
299#[derive(Debug, Clone, PartialEq, Eq, Hash)]
300pub enum ClassBodyDecl {
301    /// A field declaration.
302    Field(FieldDecl),
303    /// A method declaration.
304    Method(MethodDecl),
305    /// A constructor declaration.
306    Constructor(ConstructorDecl),
307    /// A static initializer block: `static { ... }`.
308    StaticInit(StaticInit),
309    /// An instance initializer block: `{ ... }`.
310    InstanceInit(InstanceInit),
311    /// A nested class declaration.
312    Class(ClassDecl),
313    /// A nested interface declaration.
314    Interface(InterfaceDecl),
315    /// A nested enum declaration.
316    Enum(EnumDecl),
317    /// A nested record declaration.
318    Record(RecordDecl),
319    /// A nested annotation type declaration.
320    AnnotationType(AnnotationInterfaceDecl),
321    /// A semicolon (empty declaration).
322    Empty(Span),
323}
324
325impl ClassBodyDecl {
326    pub fn span(&self) -> Span {
327        match self {
328            Self::Field(f) => f.span(),
329            Self::Method(m) => m.span(),
330            Self::Constructor(c) => c.span(),
331            Self::StaticInit(s) => s.span(),
332            Self::InstanceInit(i) => i.span(),
333            Self::Class(c) => c.span(),
334            Self::Interface(i) => i.span(),
335            Self::Enum(e) => e.span(),
336            Self::Record(r) => r.span(),
337            Self::AnnotationType(a) => a.span(),
338            Self::Empty(s) => *s,
339        }
340    }
341}
342
343/// A field declaration: `[modifiers] type name [= expr] [, name [= expr]] ;`.
344#[derive(Debug, Clone, PartialEq, Eq, Hash)]
345pub struct FieldDecl {
346    pub doc_comment: Vec<Comment>,
347    pub modifiers: Vec<Modifier>,
348    pub ty: Type,
349    pub declarators: Vec<super::stmt::VariableDeclarator>,
350    pub semi_span: Span,
351}
352
353impl FieldDecl {
354    pub fn span(&self) -> Span {
355        let start = self.doc_comment.first().map_or(self.semi_span, |c| c.span);
356        start.join(self.semi_span)
357    }
358}
359
360/// A method declaration.
361#[derive(Debug, Clone, PartialEq, Eq, Hash)]
362pub struct MethodDecl {
363    pub doc_comment: Vec<Comment>,
364    pub modifiers: Vec<Modifier>,
365    pub type_params: Option<TypeParameters>,
366    pub return_type: MethodReturnType,
367    pub name: Ident,
368    pub receiver_param: Option<ReceiverParameter>,
369    pub params: Vec<FormalParameter>,
370    pub paren_span: (Span, Span),
371    pub throws_clause: Option<ThrowsClause>,
372    pub body: Option<Block>,
373}
374
375impl MethodDecl {
376    pub fn span(&self) -> Span {
377        let end = match &self.body {
378            Some(b) => b.brace_span.1,
379            None => self.paren_span.1,
380        };
381        let code_start = self
382            .modifiers
383            .first()
384            .map_or(self.name.span(), |m| m.span());
385        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
386        start.join(end)
387    }
388}
389
390/// The return type of a method.
391#[derive(Debug, Clone, PartialEq, Eq, Hash)]
392pub enum MethodReturnType {
393    /// A declared return type.
394    Type(Type),
395    /// `void`
396    Void(Span),
397}
398
399impl From<Type> for MethodReturnType {
400    fn from(ty: Type) -> Self {
401        match ty {
402            Type::Void(span) => MethodReturnType::Void(span),
403            other => MethodReturnType::Type(other),
404        }
405    }
406}
407
408/// A receiver parameter: `Type [name.] this`.
409#[derive(Debug, Clone, PartialEq, Eq, Hash)]
410pub struct ReceiverParameter {
411    pub annotations: Vec<Annotation>,
412    pub ty: Type,
413    pub name: Option<Ident>,
414    pub dot_span: Option<Span>,
415    pub this_span: Span,
416}
417
418/// A formal parameter of a method or constructor.
419#[derive(Debug, Clone, PartialEq, Eq, Hash)]
420pub enum FormalParameter {
421    /// A normal parameter: `[final] Type name`.
422    Normal {
423        modifiers: Vec<Modifier>,
424        ty: Type,
425        name: Option<Ident>, // None for unnamed (Java 21+)
426    },
427    /// A varargs parameter: `Type... name`.
428    VarArgs {
429        modifiers: Vec<Modifier>,
430        ty: Type,
431        ellipsis_span: Span,
432        name: Option<Ident>,
433    },
434}
435
436/// A throws clause: `throws Type1, Type2`.
437#[derive(Debug, Clone, PartialEq, Eq, Hash)]
438pub struct ThrowsClause {
439    pub throws_span: Span,
440    pub types: Vec<Type>,
441}
442
443/// A constructor declaration.
444#[derive(Debug, Clone, PartialEq, Eq, Hash)]
445pub struct ConstructorDecl {
446    pub doc_comment: Vec<Comment>,
447    pub modifiers: Vec<Modifier>,
448    pub type_params: Option<TypeParameters>,
449    pub name: Ident,
450    pub receiver_param: Option<ReceiverParameter>,
451    pub params: Vec<FormalParameter>,
452    pub paren_span: (Span, Span),
453    pub throws_clause: Option<ThrowsClause>,
454    pub body: ConstructorBody,
455}
456
457impl ConstructorDecl {
458    pub fn span(&self) -> Span {
459        let code_start = self
460            .modifiers
461            .first()
462            .map_or(self.name.span(), |m| m.span());
463        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
464        start.join(self.body.brace_span.1)
465    }
466}
467
468/// A constructor body.
469#[derive(Debug, Clone, PartialEq, Eq, Hash)]
470pub struct ConstructorBody {
471    pub brace_span: (Span, Span),
472    pub explicit_constructor_call: Option<ExplicitConstructorCall>,
473    pub stmts: Vec<Stmt>,
474}
475
476/// An explicit constructor invocation: `this(args)` or `super(args)`.
477#[derive(Debug, Clone, PartialEq, Eq, Hash)]
478pub enum ExplicitConstructorCall {
479    This {
480        type_args: Option<crate::ast::path::TypeArguments>,
481        this_span: Span,
482        paren_span: (Span, Span),
483        args: Vec<Expr>,
484        semi_span: Span,
485    },
486    Super {
487        type_args: Option<crate::ast::path::TypeArguments>,
488        super_span: Span,
489        paren_span: (Span, Span),
490        args: Vec<Expr>,
491        semi_span: Span,
492    },
493    SuperFromExpr {
494        target: Box<Expr>,
495        dot_span: Span,
496        type_args: Option<crate::ast::path::TypeArguments>,
497        super_span: Span,
498        paren_span: (Span, Span),
499        args: Vec<Expr>,
500        semi_span: Span,
501    },
502}
503
504/// A static initializer.
505#[derive(Debug, Clone, PartialEq, Eq, Hash)]
506pub struct StaticInit {
507    pub static_span: Span,
508    pub block: Block,
509}
510
511impl StaticInit {
512    pub fn span(&self) -> Span {
513        self.static_span.join(self.block.brace_span.1)
514    }
515}
516
517/// An instance initializer.
518#[derive(Debug, Clone, PartialEq, Eq, Hash)]
519pub struct InstanceInit {
520    pub block: Block,
521}
522
523impl InstanceInit {
524    pub fn span(&self) -> Span {
525        self.block.span()
526    }
527}
528
529/// An interface body: `{ members }`.
530#[derive(Debug, Clone, PartialEq, Eq, Hash)]
531pub struct InterfaceBody {
532    pub brace_span: (Span, Span),
533    pub members: Vec<InterfaceMemberDecl>,
534}
535
536/// A member declaration inside an interface.
537#[derive(Debug, Clone, PartialEq, Eq, Hash)]
538pub enum InterfaceMemberDecl {
539    Field(FieldDecl),
540    Method(MethodDecl),
541    Class(ClassDecl),
542    Interface(InterfaceDecl),
543    Enum(EnumDecl),
544    Record(RecordDecl),
545    AnnotationInterface(AnnotationInterfaceDecl),
546    Empty(Span),
547}
548
549/// An annotation interface declaration: `@interface Name { ... }`.
550#[derive(Debug, Clone, PartialEq, Eq, Hash)]
551pub struct AnnotationInterfaceDecl {
552    pub doc_comment: Vec<Comment>,
553    pub modifiers: Vec<Modifier>,
554    pub at_span: Span,
555    pub interface_span: Span,
556    pub name: Ident,
557    pub body: AnnotationInterfaceBody,
558}
559
560impl AnnotationInterfaceDecl {
561    pub fn span(&self) -> Span {
562        let code_start = self.modifiers.first().map_or(self.at_span, |m| m.span());
563        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
564        start.join(self.body.brace_span.1)
565    }
566}
567
568/// Annotation interface body.
569#[derive(Debug, Clone, PartialEq, Eq, Hash)]
570pub struct AnnotationInterfaceBody {
571    pub brace_span: (Span, Span),
572    pub members: Vec<AnnotationInterfaceMember>,
573}
574
575/// A member of an annotation interface.
576#[derive(Debug, Clone, PartialEq, Eq, Hash)]
577pub enum AnnotationInterfaceMember {
578    /// An annotation element: `Type name() [default value];`
579    Element(AnnotationElement),
580    /// A constant field.
581    Field(FieldDecl),
582    /// A nested class.
583    Class(ClassDecl),
584    /// A nested interface.
585    Interface(InterfaceDecl),
586    /// A nested enum.
587    Enum(EnumDecl),
588    /// A nested record.
589    Record(RecordDecl),
590    /// A nested annotation interface.
591    AnnotationInterface(AnnotationInterfaceDecl),
592    Empty(Span),
593}
594
595/// An annotation element declaration.
596#[derive(Debug, Clone, PartialEq, Eq, Hash)]
597pub struct AnnotationElement {
598    pub modifiers: Vec<Modifier>,
599    pub ty: Type,
600    pub name: Ident,
601    pub paren_span: (Span, Span),
602    pub dims: Vec<super::ty::ArrayDim>,
603    pub default_value: Option<(Span, super::attribute::ElementValue)>,
604    pub semi_span: Span,
605}
606
607/// Enum body: `{ constants [,] [members] }`.
608#[derive(Debug, Clone, PartialEq, Eq, Hash)]
609pub struct EnumBody {
610    pub brace_span: (Span, Span),
611    pub constants: Vec<EnumConstant>,
612    pub comma_span: Option<Span>,
613    pub members: Vec<ClassBodyDecl>,
614}
615
616/// An enum constant: `NAME[(args)] [{ class body }]`.
617#[derive(Debug, Clone, PartialEq, Eq, Hash)]
618pub struct EnumConstant {
619    pub annotations: Vec<Annotation>,
620    pub name: Ident,
621    pub paren_span: Option<(Span, Span)>,
622    pub args: Vec<Expr>,
623    pub body: Option<ClassBodyDeclList>,
624}
625
626/// Record components: `(Type name, Type name, ...)`.
627#[derive(Debug, Clone, PartialEq, Eq, Hash)]
628pub struct RecordComponents {
629    pub paren_span: (Span, Span),
630    pub components: Vec<RecordComponent>,
631}
632
633/// A single record component.
634#[derive(Debug, Clone, PartialEq, Eq, Hash)]
635pub enum RecordComponent {
636    Normal {
637        annotations: Vec<Annotation>,
638        ty: Type,
639        name: Ident,
640    },
641    VarArgs {
642        annotations: Vec<Annotation>,
643        ty: Type,
644        ellipsis_span: Span,
645        name: Ident,
646    },
647}
648
649/// Record body: `{ members }`.
650#[derive(Debug, Clone, PartialEq, Eq, Hash)]
651pub struct RecordBody {
652    pub brace_span: (Span, Span),
653    pub members: Vec<RecordBodyDecl>,
654}
655
656/// A member of a record body.
657#[derive(Debug, Clone, PartialEq, Eq, Hash)]
658pub enum RecordBodyDecl {
659    Field(FieldDecl),
660    Method(MethodDecl),
661    Constructor(ConstructorDecl),
662    InstanceInit(InstanceInit),
663    StaticInit(StaticInit),
664    Class(ClassDecl),
665    Interface(InterfaceDecl),
666    Enum(EnumDecl),
667    Record(RecordDecl),
668    /// A compact constructor: `public Name { ... }`.
669    CompactConstructor(CompactConstructorDecl),
670    Empty(Span),
671}
672
673/// A compact constructor declaration for records.
674#[derive(Debug, Clone, PartialEq, Eq, Hash)]
675pub struct CompactConstructorDecl {
676    pub doc_comment: Vec<Comment>,
677    pub modifiers: Vec<Modifier>,
678    pub name: Ident,
679    pub body: ConstructorBody,
680}