Skip to main content

rajac_ast/
ast.rs

1use super::ast_type::{AstTypeId, AstTypeParam};
2use rajac_base::shared_string::SharedString;
3use rajac_types::{FieldId as ResolvedFieldId, Ident, MethodId as ResolvedMethodId, TypeId};
4use std::ops::Range;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Span(pub Range<usize>);
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct AstNode<T> {
11    pub kind: T,
12    pub span: Span,
13}
14
15impl<T> AstNode<T> {
16    pub fn new(kind: T, span: Span) -> Self {
17        Self { kind, span }
18    }
19}
20
21#[derive(Debug, Clone, PartialEq)]
22pub enum UnaryOp {
23    Plus,
24    Minus,
25    Bang,
26    Tilde,
27    Increment,
28    Decrement,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum BinaryOp {
33    Add,
34    Sub,
35    Mul,
36    Div,
37    Mod,
38    BitAnd,
39    BitOr,
40    BitXor,
41    LShift,
42    RShift,
43    ARShift,
44    Lt,
45    LtEq,
46    Gt,
47    GtEq,
48    EqEq,
49    BangEq,
50    And,
51    Or,
52}
53
54#[derive(Debug, Clone, PartialEq)]
55pub enum AssignOp {
56    Eq,
57    AddEq,
58    SubEq,
59    MulEq,
60    DivEq,
61    ModEq,
62    AndEq,
63    OrEq,
64    XorEq,
65    LShiftEq,
66    RShiftEq,
67    ARShiftEq,
68}
69
70#[derive(Debug, Clone, PartialEq)]
71pub enum LiteralKind {
72    Int,
73    Long,
74    Float,
75    Double,
76    Char,
77    String,
78    Bool,
79    Null,
80}
81
82#[derive(Debug, Clone, PartialEq)]
83pub struct Literal {
84    pub kind: LiteralKind,
85    pub value: SharedString,
86}
87
88#[derive(Debug, Clone, PartialEq)]
89pub struct Ast {
90    pub statements: Vec<StmtId>,
91    pub source: SharedString,
92    pub package: Option<PackageDecl>,
93    pub imports: Vec<ImportDecl>,
94    pub classes: Vec<ClassDeclId>,
95}
96
97impl Ast {
98    pub fn new(source: SharedString) -> Self {
99        Self {
100            statements: Vec::new(),
101            source,
102            package: None,
103            imports: Vec::new(),
104            classes: Vec::new(),
105        }
106    }
107}
108
109#[derive(Debug, Clone, PartialEq)]
110pub struct PackageDecl {
111    pub name: QualifiedName,
112}
113
114#[derive(Debug, Clone, PartialEq)]
115pub struct ImportDecl {
116    pub name: QualifiedName,
117    pub is_static: bool,
118    pub is_on_demand: bool,
119}
120
121#[derive(Debug, Clone, PartialEq)]
122pub struct QualifiedName {
123    pub segments: Vec<SharedString>,
124}
125
126impl QualifiedName {
127    pub fn new(segments: Vec<SharedString>) -> Self {
128        Self { segments }
129    }
130}
131
132#[derive(Debug, Clone, PartialEq)]
133pub enum ClassKind {
134    Class,
135    Interface,
136    Enum,
137    Record,
138    Annotation,
139}
140
141#[derive(Debug, Clone, PartialEq)]
142pub struct ClassDecl {
143    pub kind: ClassKind,
144    pub name: Ident,
145    pub type_params: Vec<AstTypeParam>,
146    pub extends: Option<AstTypeId>,
147    pub implements: Vec<AstTypeId>,
148    pub permits: Vec<AstTypeId>,
149    pub enum_entries: Vec<EnumEntry>,
150    pub members: Vec<ClassMemberId>,
151    pub modifiers: Modifiers,
152}
153
154#[derive(Debug, Clone, PartialEq)]
155pub enum ClassMember {
156    Field(Field),
157    Method(Method),
158    Constructor(Constructor),
159    StaticBlock(StmtId),
160    NestedClass(ClassDeclId),
161    NestedInterface(ClassDeclId),
162    NestedEnum(ClassDeclId),
163    NestedRecord(ClassDeclId),
164    NestedAnnotation(ClassDeclId),
165}
166
167#[derive(Debug, Clone, PartialEq)]
168pub struct Constructor {
169    pub name: Ident,
170    pub params: Vec<ParamId>,
171    pub body: Option<StmtId>,
172    pub throws: Vec<AstTypeId>,
173    pub modifiers: Modifiers,
174}
175
176#[derive(Debug, Clone, PartialEq)]
177pub struct EnumEntry {
178    pub name: Ident,
179    pub args: Vec<ExprId>,
180    pub body: Option<Vec<ClassMemberId>>,
181}
182
183#[derive(Debug, Clone, PartialEq)]
184pub enum Stmt {
185    Empty,
186    Block(Vec<StmtId>),
187    Expr(ExprId),
188    If {
189        condition: ExprId,
190        then_branch: StmtId,
191        else_branch: Option<StmtId>,
192    },
193    While {
194        condition: ExprId,
195        body: StmtId,
196    },
197    DoWhile {
198        body: StmtId,
199        condition: ExprId,
200    },
201    For {
202        init: Option<ForInit>,
203        condition: Option<ExprId>,
204        update: Option<ExprId>,
205        body: StmtId,
206    },
207    Switch {
208        expr: ExprId,
209        cases: Vec<SwitchCase>,
210    },
211    Return(Option<ExprId>),
212    Break(Option<Ident>),
213    Continue(Option<Ident>),
214    Label(Ident, StmtId),
215    Try {
216        try_block: StmtId,
217        catches: Vec<CatchClause>,
218        finally_block: Option<StmtId>,
219    },
220    Throw(ExprId),
221    Synchronized {
222        expr: Option<ExprId>,
223        block: StmtId,
224    },
225    LocalVar {
226        ty: AstTypeId,
227        name: Ident,
228        initializer: Option<ExprId>,
229    },
230}
231
232#[derive(Debug, Clone, PartialEq)]
233pub enum ForInit {
234    Expr(ExprId),
235    LocalVar {
236        ty: AstTypeId,
237        name: Ident,
238        initializer: Option<ExprId>,
239    },
240}
241
242#[derive(Debug, Clone, PartialEq)]
243pub struct CatchClause {
244    pub param: ParamId,
245    pub body: StmtId,
246}
247
248#[derive(Debug, Clone, PartialEq)]
249pub struct SwitchCase {
250    pub labels: Vec<SwitchLabel>,
251    pub body: Vec<StmtId>,
252}
253
254#[derive(Debug, Clone, PartialEq)]
255pub enum SwitchLabel {
256    Case(ExprId),
257    Default,
258}
259
260#[derive(Debug, Clone, PartialEq)]
261pub enum Expr {
262    Error,
263    Ident(Ident),
264    Literal(Literal),
265    Unary {
266        op: UnaryOp,
267        expr: ExprId,
268    },
269    Binary {
270        op: BinaryOp,
271        lhs: ExprId,
272        rhs: ExprId,
273    },
274    Assign {
275        op: AssignOp,
276        lhs: ExprId,
277        rhs: ExprId,
278    },
279    Ternary {
280        condition: ExprId,
281        then_expr: ExprId,
282        else_expr: ExprId,
283    },
284    Cast {
285        ty: AstTypeId,
286        expr: ExprId,
287    },
288    InstanceOf {
289        expr: ExprId,
290        ty: AstTypeId,
291    },
292    FieldAccess {
293        expr: ExprId,
294        name: Ident,
295        field_id: Option<ResolvedFieldId>,
296    },
297    MethodCall {
298        expr: Option<ExprId>,
299        name: Ident,
300        type_args: Option<Vec<AstTypeId>>,
301        args: Vec<ExprId>,
302        method_id: Option<ResolvedMethodId>,
303    },
304    New {
305        ty: AstTypeId,
306        args: Vec<ExprId>,
307    },
308    NewArray {
309        ty: AstTypeId,
310        dimensions: Vec<ExprId>,
311        initializer: Option<ExprId>,
312    },
313    ArrayInitializer {
314        elements: Vec<ExprId>,
315    },
316    ArrayAccess {
317        array: ExprId,
318        index: ExprId,
319    },
320    ArrayLength {
321        array: ExprId,
322    },
323    This(Option<ExprId>),
324    Super,
325    SuperCall {
326        name: Ident,
327        type_args: Option<Vec<AstTypeId>>,
328        args: Vec<ExprId>,
329        method_id: Option<ResolvedMethodId>,
330    },
331}
332
333#[derive(Debug, Clone, PartialEq)]
334pub struct TypedExpr {
335    pub expr: Expr,
336    pub ty: TypeId,
337}
338
339impl TypedExpr {
340    pub fn new(expr: Expr) -> Self {
341        Self {
342            expr,
343            ty: TypeId::INVALID,
344        }
345    }
346}
347
348#[derive(Debug, Clone, PartialEq)]
349pub struct Param {
350    pub ty: AstTypeId,
351    pub name: Ident,
352    pub varargs: bool,
353}
354
355#[derive(Debug, Clone, PartialEq)]
356pub struct Method {
357    pub name: Ident,
358    pub params: Vec<ParamId>,
359    pub return_ty: AstTypeId,
360    pub body: Option<StmtId>,
361    pub throws: Vec<AstTypeId>,
362    pub modifiers: Modifiers,
363}
364
365#[derive(Debug, Clone, PartialEq)]
366pub struct Field {
367    pub name: Ident,
368    pub ty: AstTypeId,
369    pub initializer: Option<ExprId>,
370    pub modifiers: Modifiers,
371}
372
373#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
374pub struct StmtId(pub u32);
375
376#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
377pub struct ExprId(pub u32);
378
379#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
380pub struct ParamId(pub u32);
381
382#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
383pub struct MethodId(pub u32);
384
385#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
386pub struct FieldId(pub u32);
387
388#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
389pub struct ClassDeclId(pub u32);
390
391#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
392pub struct ClassMemberId(pub u32);
393
394#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
395pub struct Modifiers(pub u32);
396
397impl Modifiers {
398    pub const PUBLIC: u32 = 0x0001;
399    pub const PRIVATE: u32 = 0x0002;
400    pub const PROTECTED: u32 = 0x0004;
401    pub const STATIC: u32 = 0x0008;
402    pub const FINAL: u32 = 0x0010;
403    pub const SYNCHRONIZED: u32 = 0x0020;
404    pub const VOLATILE: u32 = 0x0040;
405    pub const TRANSIENT: u32 = 0x0080;
406    pub const NATIVE: u32 = 0x0100;
407    pub const INTERFACE: u32 = 0x0200;
408    pub const ABSTRACT: u32 = 0x0400;
409    pub const STRICTFP: u32 = 0x0800;
410    pub const SYNTHETIC: u32 = 0x1000;
411    pub const ANNOTATION: u32 = 0x2000;
412    pub const ENUM: u32 = 0x4000;
413    pub const MODULE: u32 = 0x8000;
414
415    pub fn is_public(&self) -> bool {
416        self.0 & Self::PUBLIC != 0
417    }
418
419    pub fn is_private(&self) -> bool {
420        self.0 & Self::PRIVATE != 0
421    }
422
423    pub fn is_protected(&self) -> bool {
424        self.0 & Self::PROTECTED != 0
425    }
426
427    pub fn is_static(&self) -> bool {
428        self.0 & Self::STATIC != 0
429    }
430
431    pub fn is_final(&self) -> bool {
432        self.0 & Self::FINAL != 0
433    }
434
435    pub fn is_abstract(&self) -> bool {
436        self.0 & Self::ABSTRACT != 0
437    }
438}