Skip to main content

java_lang/ast/
compilation_unit.rs

1//! Compilation unit (top-level Java file structure).
2
3use crate::{ast::path::Path, ident::Ident, span::Span};
4
5use super::{Comment, attribute::Annotation, item::TypeDecl};
6
7/// A Java compilation unit (a single source file).
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct CompilationUnit {
10    /// The package declaration, if present.
11    pub package: Option<PackageDecl>,
12    /// Import declarations.
13    pub imports: Vec<ImportDecl>,
14    /// Top-level type declarations.
15    pub type_decls: Vec<TypeDecl>,
16    /// The module declaration, if present (for module-info.java).
17    pub module: Option<super::item::ModuleDecl>,
18    /// All comments in the source file.
19    pub comments: Vec<Comment>,
20}
21
22impl CompilationUnit {
23    /// Get the span of the entire compilation unit.
24    pub fn span(&self) -> Span {
25        let start = match &self.package {
26            Some(pkg) => pkg.span,
27            None => match self.imports.first() {
28                Some(imp) => imp.span(),
29                None => match self.type_decls.first() {
30                    Some(decl) => decl.span(),
31                    None => match &self.module {
32                        Some(m) => m.span(),
33                        None => Span::call_site(),
34                    },
35                },
36            },
37        };
38        let end = match self.type_decls.last() {
39            Some(decl) => decl.span(),
40            None => match self.module {
41                Some(ref m) => m.span(),
42                None => match self.imports.last() {
43                    Some(imp) => imp.span(),
44                    None => start,
45                },
46            },
47        };
48        start.join(end)
49    }
50}
51
52/// A package declaration: `package com.example.foo;`.
53#[derive(Debug, Clone, PartialEq, Eq, Hash)]
54pub struct PackageDecl {
55    pub annotations: Vec<Annotation>,
56    pub package_span: Span,
57    pub name: Path,
58    pub semi_span: Span,
59    pub span: Span,
60}
61
62/// An import declaration.
63#[derive(Debug, Clone, PartialEq, Eq, Hash)]
64pub enum ImportDecl {
65    /// Single type import: `import java.util.List;`
66    SingleType {
67        import_span: Span,
68        path: Path,
69        semi_span: Span,
70    },
71    /// Type import on demand: `import java.util.*;`
72    TypeOnDemand {
73        import_span: Span,
74        path: Path,
75        star_span: Span,
76        semi_span: Span,
77    },
78    /// Single static import: `import static java.util.Collections.sort;`
79    SingleStatic {
80        import_span: Span,
81        static_span: Span,
82        path: Path,
83        member: Ident,
84        semi_span: Span,
85    },
86    /// Static import on demand: `import static java.util.Collections.*;`
87    StaticOnDemand {
88        import_span: Span,
89        static_span: Span,
90        path: Path,
91        star_span: Span,
92        semi_span: Span,
93    },
94}
95
96impl ImportDecl {
97    pub fn span(&self) -> Span {
98        match self {
99            Self::SingleType {
100                import_span,
101                semi_span,
102                ..
103            }
104            | Self::TypeOnDemand {
105                import_span,
106                semi_span,
107                ..
108            }
109            | Self::SingleStatic {
110                import_span,
111                semi_span,
112                ..
113            }
114            | Self::StaticOnDemand {
115                import_span,
116                semi_span,
117                ..
118            } => import_span.join(semi_span),
119        }
120    }
121}