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
399/// A receiver parameter: `Type [name.] this`.
400#[derive(Debug, Clone, PartialEq, Eq, Hash)]
401pub struct ReceiverParameter {
402    pub annotations: Vec<Annotation>,
403    pub ty: Type,
404    pub name: Option<Ident>,
405    pub dot_span: Option<Span>,
406    pub this_span: Span,
407}
408
409/// A formal parameter of a method or constructor.
410#[derive(Debug, Clone, PartialEq, Eq, Hash)]
411pub enum FormalParameter {
412    /// A normal parameter: `[final] Type name`.
413    Normal {
414        modifiers: Vec<Modifier>,
415        ty: Type,
416        name: Option<Ident>, // None for unnamed (Java 21+)
417    },
418    /// A varargs parameter: `Type... name`.
419    VarArgs {
420        modifiers: Vec<Modifier>,
421        ty: Type,
422        ellipsis_span: Span,
423        name: Option<Ident>,
424    },
425}
426
427/// A throws clause: `throws Type1, Type2`.
428#[derive(Debug, Clone, PartialEq, Eq, Hash)]
429pub struct ThrowsClause {
430    pub throws_span: Span,
431    pub types: Vec<Type>,
432}
433
434/// A constructor declaration.
435#[derive(Debug, Clone, PartialEq, Eq, Hash)]
436pub struct ConstructorDecl {
437    pub doc_comment: Vec<Comment>,
438    pub modifiers: Vec<Modifier>,
439    pub type_params: Option<TypeParameters>,
440    pub name: Ident,
441    pub receiver_param: Option<ReceiverParameter>,
442    pub params: Vec<FormalParameter>,
443    pub paren_span: (Span, Span),
444    pub throws_clause: Option<ThrowsClause>,
445    pub body: ConstructorBody,
446}
447
448impl ConstructorDecl {
449    pub fn span(&self) -> Span {
450        let code_start = self
451            .modifiers
452            .first()
453            .map_or(self.name.span(), |m| m.span());
454        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
455        start.join(self.body.brace_span.1)
456    }
457}
458
459/// A constructor body.
460#[derive(Debug, Clone, PartialEq, Eq, Hash)]
461pub struct ConstructorBody {
462    pub brace_span: (Span, Span),
463    pub explicit_constructor_call: Option<ExplicitConstructorCall>,
464    pub stmts: Vec<Stmt>,
465}
466
467/// An explicit constructor invocation: `this(args)` or `super(args)`.
468#[derive(Debug, Clone, PartialEq, Eq, Hash)]
469pub enum ExplicitConstructorCall {
470    This {
471        type_args: Option<crate::ast::path::TypeArguments>,
472        this_span: Span,
473        paren_span: (Span, Span),
474        args: Vec<Expr>,
475        semi_span: Span,
476    },
477    Super {
478        type_args: Option<crate::ast::path::TypeArguments>,
479        super_span: Span,
480        paren_span: (Span, Span),
481        args: Vec<Expr>,
482        semi_span: Span,
483    },
484    SuperFromExpr {
485        target: Box<Expr>,
486        dot_span: Span,
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}
494
495/// A static initializer.
496#[derive(Debug, Clone, PartialEq, Eq, Hash)]
497pub struct StaticInit {
498    pub static_span: Span,
499    pub block: Block,
500}
501
502impl StaticInit {
503    pub fn span(&self) -> Span {
504        self.static_span.join(self.block.brace_span.1)
505    }
506}
507
508/// An instance initializer.
509#[derive(Debug, Clone, PartialEq, Eq, Hash)]
510pub struct InstanceInit {
511    pub block: Block,
512}
513
514impl InstanceInit {
515    pub fn span(&self) -> Span {
516        self.block.span()
517    }
518}
519
520/// An interface body: `{ members }`.
521#[derive(Debug, Clone, PartialEq, Eq, Hash)]
522pub struct InterfaceBody {
523    pub brace_span: (Span, Span),
524    pub members: Vec<InterfaceMemberDecl>,
525}
526
527/// A member declaration inside an interface.
528#[derive(Debug, Clone, PartialEq, Eq, Hash)]
529pub enum InterfaceMemberDecl {
530    Field(FieldDecl),
531    Method(MethodDecl),
532    Class(ClassDecl),
533    Interface(InterfaceDecl),
534    Enum(EnumDecl),
535    Record(RecordDecl),
536    AnnotationInterface(AnnotationInterfaceDecl),
537    Empty(Span),
538}
539
540/// An annotation interface declaration: `@interface Name { ... }`.
541#[derive(Debug, Clone, PartialEq, Eq, Hash)]
542pub struct AnnotationInterfaceDecl {
543    pub doc_comment: Vec<Comment>,
544    pub modifiers: Vec<Modifier>,
545    pub at_span: Span,
546    pub interface_span: Span,
547    pub name: Ident,
548    pub body: AnnotationInterfaceBody,
549}
550
551impl AnnotationInterfaceDecl {
552    pub fn span(&self) -> Span {
553        let code_start = self.modifiers.first().map_or(self.at_span, |m| m.span());
554        let start = self.doc_comment.first().map_or(code_start, |c| c.span);
555        start.join(self.body.brace_span.1)
556    }
557}
558
559/// Annotation interface body.
560#[derive(Debug, Clone, PartialEq, Eq, Hash)]
561pub struct AnnotationInterfaceBody {
562    pub brace_span: (Span, Span),
563    pub members: Vec<AnnotationInterfaceMember>,
564}
565
566/// A member of an annotation interface.
567#[derive(Debug, Clone, PartialEq, Eq, Hash)]
568pub enum AnnotationInterfaceMember {
569    /// An annotation element: `Type name() [default value];`
570    Element(AnnotationElement),
571    /// A constant field.
572    Field(FieldDecl),
573    /// A nested class.
574    Class(ClassDecl),
575    /// A nested interface.
576    Interface(InterfaceDecl),
577    /// A nested enum.
578    Enum(EnumDecl),
579    /// A nested record.
580    Record(RecordDecl),
581    /// A nested annotation interface.
582    AnnotationInterface(AnnotationInterfaceDecl),
583    Empty(Span),
584}
585
586/// An annotation element declaration.
587#[derive(Debug, Clone, PartialEq, Eq, Hash)]
588pub struct AnnotationElement {
589    pub modifiers: Vec<Modifier>,
590    pub ty: Type,
591    pub name: Ident,
592    pub paren_span: (Span, Span),
593    pub dims: Vec<super::ty::ArrayDim>,
594    pub default_value: Option<(Span, super::attribute::ElementValue)>,
595    pub semi_span: Span,
596}
597
598/// Enum body: `{ constants [,] [members] }`.
599#[derive(Debug, Clone, PartialEq, Eq, Hash)]
600pub struct EnumBody {
601    pub brace_span: (Span, Span),
602    pub constants: Vec<EnumConstant>,
603    pub comma_span: Option<Span>,
604    pub members: Vec<ClassBodyDecl>,
605}
606
607/// An enum constant: `NAME[(args)] [{ class body }]`.
608#[derive(Debug, Clone, PartialEq, Eq, Hash)]
609pub struct EnumConstant {
610    pub annotations: Vec<Annotation>,
611    pub name: Ident,
612    pub paren_span: Option<(Span, Span)>,
613    pub args: Vec<Expr>,
614    pub body: Option<ClassBodyDeclList>,
615}
616
617/// Record components: `(Type name, Type name, ...)`.
618#[derive(Debug, Clone, PartialEq, Eq, Hash)]
619pub struct RecordComponents {
620    pub paren_span: (Span, Span),
621    pub components: Vec<RecordComponent>,
622}
623
624/// A single record component.
625#[derive(Debug, Clone, PartialEq, Eq, Hash)]
626pub enum RecordComponent {
627    Normal {
628        annotations: Vec<Annotation>,
629        ty: Type,
630        name: Ident,
631    },
632    VarArgs {
633        annotations: Vec<Annotation>,
634        ty: Type,
635        ellipsis_span: Span,
636        name: Ident,
637    },
638}
639
640/// Record body: `{ members }`.
641#[derive(Debug, Clone, PartialEq, Eq, Hash)]
642pub struct RecordBody {
643    pub brace_span: (Span, Span),
644    pub members: Vec<RecordBodyDecl>,
645}
646
647/// A member of a record body.
648#[derive(Debug, Clone, PartialEq, Eq, Hash)]
649pub enum RecordBodyDecl {
650    Field(FieldDecl),
651    Method(MethodDecl),
652    Constructor(ConstructorDecl),
653    InstanceInit(InstanceInit),
654    StaticInit(StaticInit),
655    Class(ClassDecl),
656    Interface(InterfaceDecl),
657    Enum(EnumDecl),
658    Record(RecordDecl),
659    /// A compact constructor: `public Name { ... }`.
660    CompactConstructor(CompactConstructorDecl),
661    Empty(Span),
662}
663
664/// A compact constructor declaration for records.
665#[derive(Debug, Clone, PartialEq, Eq, Hash)]
666pub struct CompactConstructorDecl {
667    pub doc_comment: Vec<Comment>,
668    pub modifiers: Vec<Modifier>,
669    pub name: Ident,
670    pub body: ConstructorBody,
671}