1use crate::ty::{MethodSig, Ty, TypeParam};
2use la_arena::{Arena, Idx};
3use std::collections::HashMap;
4use std::rc::Rc;
5use text_size::TextRange;
6use ustr::Ustr;
7
8pub type ExprId = Idx<Expr>;
9pub type StmtId = Idx<Stmt>;
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct HirId(pub u32);
13
14#[derive(Debug, Clone)]
15pub struct Package {
16 pub name: Ustr,
17}
18
19#[derive(Debug, Clone)]
20pub struct CompilationUnit {
21 pub package: Option<Package>,
22 pub imports: Vec<Import>,
23 pub type_decls: Vec<TypeDecl>,
24}
25
26#[derive(Debug, Clone)]
27pub struct Import {
28 pub path: Ustr,
29 pub is_static: bool,
30 pub is_wildcard: bool,
31 pub source_line: Option<u16>,
32 pub source_range: Option<TextRange>,
33}
34
35#[derive(Debug, Clone)]
36pub struct TypeDecl {
37 pub id: HirId,
38 pub name: Ustr,
39 pub kind: TypeDeclKind,
40 pub access_flags: u16,
41 pub super_class: Option<Ty>,
42 pub interfaces: Vec<Ty>,
43 pub type_params: Vec<TypeParam>,
44 pub generic_signature: Option<String>,
45 pub fields: Vec<FieldDecl>,
46 pub methods: Vec<MethodDecl>,
47 pub inner_types: Vec<Rc<TypeDecl>>,
48 pub anonymous: Option<AnonymousClassInfo>,
49 pub record_components: Vec<RecordComponentDecl>,
50 pub annotations: Vec<AnnotationUse>,
51}
52
53#[derive(Debug, Clone)]
54pub struct AnonymousClassInfo {
55 pub super_constructor: SuperConstructorCall,
56 pub outer_this: Option<OuterThisInfo>,
57 pub enclosing_static_owner: Option<Ustr>,
58 pub outer_fields: Vec<CapturedField>,
59}
60
61#[derive(Debug, Clone)]
62pub struct SuperConstructorCall {
63 pub owner: Ty,
64 pub params: Vec<Ty>,
65 pub arg_offset: usize,
66}
67
68#[derive(Debug, Clone)]
69pub struct OuterThisInfo {
70 pub field_name: Ustr,
71 pub ty: Ty,
72}
73
74#[derive(Debug, Clone)]
75pub struct CapturedField {
76 pub name: Ustr,
77 pub ty: Ty,
78 pub access_flags: u16,
79}
80
81#[derive(Debug, Clone)]
82pub struct AnonymousObject {
83 pub class_name: Ustr,
84 pub constructor_params: Vec<Ty>,
85 pub captures_enclosing_this: bool,
86}
87
88#[derive(Debug, Clone, PartialEq)]
89pub enum TypeDeclKind {
90 Class,
91 Interface,
92 Enum,
93 Record,
94 Annotation,
95}
96
97#[derive(Debug, Clone, Default)]
98pub struct Body {
99 pub exprs: Arena<Expr>,
100 pub stmts: Arena<Stmt>,
101 pub stmt_lines: HashMap<StmtId, u16>,
102}
103
104#[derive(Debug, Clone)]
105pub struct FieldDecl {
106 pub id: HirId,
107 pub name: Ustr,
108 pub ty: Ty,
109 pub access_flags: u16,
110 pub generic_signature: Option<String>,
111 pub body: Body,
112 pub initializer: Option<ExprId>,
113}
114
115#[derive(Debug, Clone)]
116pub struct RecordComponentDecl {
117 pub name: Ustr,
118 pub ty: Ty,
119 pub generic_signature: Option<String>,
120}
121
122#[derive(Debug, Clone)]
123pub struct AnnotationUse {
124 pub descriptor: String,
125 pub elements: Vec<AnnotationElement>,
126}
127
128#[derive(Debug, Clone)]
129pub struct AnnotationElement {
130 pub name: Ustr,
131 pub value: AnnotationValue,
132}
133
134#[derive(Debug, Clone)]
135pub enum AnnotationValue {
136 String(Ustr),
137 Int(i64),
138 Boolean(bool),
139}
140
141#[derive(Debug, Clone)]
142pub struct MethodDecl {
143 pub id: HirId,
144 pub name: Ustr,
145 pub params: Vec<ParamDecl>,
146 pub signature: MethodSig,
147 pub access_flags: u16,
148 pub source_line: Option<u16>,
149 pub generic_signature: Option<String>,
150 pub throws: Vec<Ty>,
151 pub body: Body,
152 pub root_block: Option<Block>,
153 pub constructor_call: Option<SuperConstructorCall>,
154}
155
156#[derive(Debug, Clone)]
157pub struct ParamDecl {
158 pub name: Ustr,
159 pub ty: Ty,
160}
161
162#[derive(Debug, Clone)]
163pub struct Block {
164 pub stmts: Vec<StmtId>,
165}
166
167#[derive(Debug, Clone)]
168pub enum Stmt {
169 Expr(ExprId),
170 Empty,
171 LocalVar(LocalVarDecl),
172 If {
173 condition: ExprId,
174 then_branch: StmtId,
175 else_branch: Option<StmtId>,
176 },
177 For {
178 init: Option<StmtId>,
179 condition: Option<ExprId>,
180 update: Option<ExprId>,
181 body: StmtId,
182 },
183 ForEach {
184 var_type: Ty,
185 var_name: Ustr,
186 iterable: ExprId,
187 body: StmtId,
188 },
189 While {
190 condition: ExprId,
191 body: StmtId,
192 },
193 Do {
194 body: StmtId,
195 condition: ExprId,
196 },
197 Return(Option<ExprId>),
198 Throw(ExprId),
199 Break(Option<Ustr>),
200 Continue(Option<Ustr>),
201 Labeled {
202 label: Ustr,
203 body: StmtId,
204 },
205 Switch {
206 selector: ExprId,
207 cases: Vec<SwitchCase>,
208 },
209 Try(TryStmt),
210 Synchronized(ExprId, Block),
211 Assert {
212 condition: ExprId,
213 message: Option<ExprId>,
214 },
215 Yield(ExprId),
216 Block(Block),
217}
218
219#[derive(Debug, Clone)]
220pub struct LocalVarDecl {
221 pub ty: Ty,
222 pub name: Ustr,
223 pub initializer: Option<ExprId>,
224}
225
226#[derive(Debug, Clone)]
227pub enum SwitchCase {
228 Case {
229 pattern: ExprId,
230 body: Vec<StmtId>,
231 is_arrow: bool,
232 },
233 Default {
234 body: Vec<StmtId>,
235 is_arrow: bool,
236 },
237}
238
239#[derive(Debug, Clone)]
240pub struct TryStmt {
241 pub resources: Vec<TryResource>,
242 pub body: Block,
243 pub catches: Vec<CatchClause>,
244 pub finally: Option<Block>,
245}
246
247#[derive(Debug, Clone)]
248pub struct TryResource {
249 pub ty: Ty,
250 pub name: Ustr,
251 pub initializer: Option<ExprId>,
252}
253
254#[derive(Debug, Clone)]
255pub struct CatchClause {
256 pub exception_type: Ty,
257 pub var_name: Ustr,
258 pub body: Block,
259}
260
261#[derive(Debug, Clone)]
262pub enum Expr {
263 IntLiteral(i64),
264 LongLiteral(i64),
265 FloatLiteral(f32),
266 DoubleLiteral(f64),
267 BoolLiteral(bool),
268 CharLiteral(char),
269 StringLiteral(Ustr),
270 NullLiteral,
271 This,
272 Super,
273
274 Ident(Ustr),
275 ClassName(Ustr),
276
277 FieldAccess {
278 target: ExprId,
279 field: Ustr,
280 },
281
282 MethodCall {
283 target: Option<ExprId>,
284 method: Ustr,
285 args: Vec<ExprId>,
286 },
287
288 NewObject {
289 class: Ty,
290 args: Vec<ExprId>,
291 anonymous: Option<AnonymousObject>,
292 },
293
294 NewArray {
295 element_type: Ty,
296 dimensions: Vec<Option<ExprId>>,
297 initializer: Option<ArrayInit>,
298 },
299
300 ArrayAccess {
301 array: ExprId,
302 index: ExprId,
303 },
304
305 Unary {
306 op: UnaryOp,
307 operand: ExprId,
308 },
309
310 Binary {
311 op: BinaryOp,
312 left: ExprId,
313 right: ExprId,
314 },
315
316 Ternary {
317 condition: ExprId,
318 then_expr: ExprId,
319 else_expr: ExprId,
320 },
321
322 Switch {
323 selector: ExprId,
324 cases: Vec<SwitchCase>,
325 ty: Ty,
326 },
327
328 Cast {
329 ty: Ty,
330 expr: ExprId,
331 },
332
333 Instanceof {
334 expr: ExprId,
335 ty: Ty,
336 binding: Option<Ustr>,
337 },
338
339 Assign {
340 target: ExprId,
341 op: AssignOp,
342 value: ExprId,
343 },
344
345 PostInc(ExprId),
346 PostDec(ExprId),
347
348 Lambda {
349 params: Vec<LambdaParam>,
350 body: LambdaBody,
351 target_ty: Option<Ty>,
352 },
353
354 MethodRef {
355 target: ExprId,
356 method: Ustr,
357 },
358
359 Parens(ExprId),
360}
361
362#[derive(Debug, Clone)]
363pub struct ArrayInit {
364 pub elements: Vec<ExprId>,
365}
366
367#[derive(Debug, Clone, PartialEq)]
368pub enum UnaryOp {
369 Neg,
370 Not,
371 BitNot,
372 PreInc,
373 PreDec,
374}
375
376#[derive(Debug, Clone, PartialEq)]
377pub enum BinaryOp {
378 Add,
379 Sub,
380 Mul,
381 Div,
382 Rem,
383 Shl,
384 Shr,
385 Ushr,
386 And,
387 Or,
388 Xor,
389 AndAnd,
390 OrOr,
391 Eq,
392 Ne,
393 Lt,
394 Gt,
395 Le,
396 Ge,
397}
398
399#[derive(Debug, Clone, PartialEq)]
400pub enum AssignOp {
401 Plain,
402 Add,
403 Sub,
404 Mul,
405 Div,
406 Rem,
407 Shl,
408 Shr,
409 Ushr,
410 And,
411 Or,
412 Xor,
413}
414
415#[derive(Debug, Clone)]
416pub struct LambdaParam {
417 pub ty: Option<Ty>,
418 pub name: Ustr,
419}
420
421#[derive(Debug, Clone)]
422pub enum LambdaBody {
423 Expr(ExprId),
424 Block(Block),
425}