Skip to main content

java_lang/ast/
ty.rs

1//! Type types.
2
3use crate::{ident::Ident, span::Span};
4
5use super::{
6    attribute::Annotation,
7    path::{Path, TypeArguments},
8};
9
10/// A Java type.
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum Type {
13    /// A primitive type: `int`, `boolean`, etc.
14    Primitive(PrimitiveType),
15    /// A reference type: class, interface, type variable, or array.
16    Reference(ReferenceType),
17    /// The `void` type (only used in method return types).
18    Void(Span),
19}
20
21impl Type {
22    pub fn span(&self) -> Span {
23        match self {
24            Self::Primitive(p) => p.span(),
25            Self::Reference(r) => r.span(),
26            Self::Void(s) => *s,
27        }
28    }
29
30    /// Check if this is the void type.
31    pub fn is_void(&self) -> bool {
32        matches!(self, Self::Void(_))
33    }
34
35    /// Check if this is a primitive type.
36    pub fn is_primitive(&self) -> bool {
37        matches!(self, Self::Primitive(_))
38    }
39}
40
41/// A primitive Java type.
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub enum PrimitiveType {
44    Byte,
45    Short,
46    Int,
47    Long,
48    Char,
49    Float,
50    Double,
51    Boolean,
52}
53
54impl PrimitiveType {
55    pub fn as_str(&self) -> &'static str {
56        match self {
57            Self::Byte => "byte",
58            Self::Short => "short",
59            Self::Int => "int",
60            Self::Long => "long",
61            Self::Char => "char",
62            Self::Float => "float",
63            Self::Double => "double",
64            Self::Boolean => "boolean",
65        }
66    }
67
68    pub fn span(&self) -> Span {
69        Span::call_site() // Primitive types are keywords, spans are set at the Type level
70    }
71}
72
73/// A reference type wrapper (class/interface type, type variable, or array type).
74#[derive(Debug, Clone, PartialEq, Eq, Hash)]
75pub enum ReferenceType {
76    /// A class or interface type: `String`, `List<Integer>`, `java.util.Map.Entry`.
77    ClassOrInterfaceType(ClassOrInterfaceType),
78    /// A type variable: `T`.
79    TypeVar(Ident),
80    /// An array type: `int[]`, `String[][]`.
81    Array(ArrayType),
82}
83
84impl ReferenceType {
85    pub fn span(&self) -> Span {
86        match self {
87            Self::ClassOrInterfaceType(t) => t.span(),
88            Self::TypeVar(i) => i.span(),
89            Self::Array(a) => a.span,
90        }
91    }
92}
93
94/// A class or interface type with optional type arguments.
95#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96pub struct ClassOrInterfaceType {
97    /// For a simple type like `List`, this is the name with optional type args.
98    /// For a qualified type like `Map.Entry`, this contains both segments.
99    pub path: Path,
100    pub annotations_prefix: Vec<Annotation>, // annotations before the type (rare)
101}
102
103impl ClassOrInterfaceType {
104    pub fn span(&self) -> Span {
105        self.path.span
106    }
107
108    pub fn name(&self) -> &Ident {
109        self.path.last_ident()
110    }
111
112    pub fn type_args(&self) -> Option<&TypeArguments> {
113        self.path.last_segment().args.as_ref()
114    }
115}
116
117/// An array type with its dimensions.
118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
119pub struct ArrayType {
120    pub elem_type: Box<Type>,
121    pub dims: Vec<ArrayDim>,
122    pub span: Span,
123}
124
125/// A single array dimension `[]` with optional annotations.
126#[derive(Debug, Clone, PartialEq, Eq, Hash)]
127pub struct ArrayDim {
128    pub bracket_span: (Span, Span),
129    pub annotations: Vec<Annotation>,
130}