1#![allow(clippy::unused_unit)] use dada_util::FromImpls;
4use dada_util::SalsaSerialize;
5use salsa::Update;
6use serde::Serialize;
7
8use crate::{
9 inputs::SourceFile,
10 span::{Span, Spanned},
11};
12
13mod use_item;
14pub use use_item::*;
15mod class_item;
16pub use class_item::*;
17mod member;
18pub use member::*;
19mod function;
20pub use function::*;
21mod types;
22pub use types::*;
23mod util;
24pub use util::*;
25mod expr;
26pub use expr::*;
27
28#[derive(SalsaSerialize)]
29#[salsa::interned(debug)]
30pub struct Identifier<'db> {
31 #[return_ref]
32 pub text: String,
33}
34
35impl<'db> Identifier<'db> {
36 pub fn prelude(db: &'db dyn crate::Db) -> Identifier<'db> {
37 Identifier::new(db, "prelude")
38 }
39
40 pub fn dada(db: &'db dyn crate::Db) -> Identifier<'db> {
41 Identifier::new(db, "dada")
42 }
43
44 pub fn main(db: &'db dyn crate::Db) -> Identifier<'db> {
45 Identifier::new(db, "main")
46 }
47
48 pub fn new_ident(db: &'db dyn crate::Db) -> Identifier<'db> {
49 Identifier::new(db, "new")
50 }
51
52 pub fn self_ident(db: &'db dyn crate::Db) -> Identifier<'db> {
54 Identifier::new(db, "self")
55 }
56
57 pub fn self_ty_ident(db: &'db dyn crate::Db) -> Identifier<'db> {
59 Identifier::new(db, "Self")
60 }
61}
62
63impl std::fmt::Display for Identifier<'_> {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 salsa::with_attached_database(|db| write!(f, "{}", self.text(db)))
66 .unwrap_or_else(|| std::fmt::Debug::fmt(self, f))
67 }
68}
69
70#[derive(SalsaSerialize)]
71#[salsa::tracked(debug)]
72pub struct AstModule<'db> {
73 pub name: Identifier<'db>,
74
75 #[return_ref]
76 pub items: SpanVec<'db, AstItem<'db>>,
77}
78
79impl<'db> Spanned<'db> for AstModule<'db> {
80 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
81 self.items(db).span
82 }
83}
84
85#[derive(
86 Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Update, FromImpls, Serialize,
87)]
88pub enum AstItem<'db> {
89 SourceFile(SourceFile),
90 Use(AstUse<'db>),
91 Aggregate(AstAggregate<'db>),
92 Function(AstFunction<'db>),
93 MainFunction(AstMainFunction<'db>),
94}
95
96#[derive(SalsaSerialize)]
98#[salsa::tracked(debug)]
99pub struct AstPath<'db> {
100 #[return_ref]
101 pub kind: AstPathKind<'db>,
102}
103
104#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Update, Serialize)]
105pub enum AstPathKind<'db> {
106 Identifier(SpannedIdentifier<'db>),
108
109 GenericArgs {
111 path: AstPath<'db>,
112 args: SpanVec<'db, AstGenericTerm<'db>>,
113 },
114
115 Member {
117 path: AstPath<'db>,
118 id: SpannedIdentifier<'db>,
119 },
120}
121
122impl<'db> AstPath<'db> {
123 pub fn len(self, db: &'db dyn crate::Db) -> usize {
124 match self.kind(db) {
125 AstPathKind::Identifier(_) => 1,
126 AstPathKind::GenericArgs { path, .. } => path.len(db) + 1,
127 AstPathKind::Member { path, .. } => path.len(db) + 1,
128 }
129 }
130
131 pub fn first_id(self, db: &'db dyn crate::Db) -> SpannedIdentifier<'db> {
132 match *self.kind(db) {
133 AstPathKind::Identifier(id) => id,
134 AstPathKind::GenericArgs { path, .. } => path.first_id(db),
135 AstPathKind::Member { path, .. } => path.first_id(db),
136 }
137 }
138
139 pub fn last_id(self, db: &'db dyn crate::Db) -> SpannedIdentifier<'db> {
140 match *self.kind(db) {
141 AstPathKind::Identifier(id) => id,
142 AstPathKind::GenericArgs { path, .. } => path.first_id(db),
143 AstPathKind::Member { id: ident, .. } => ident,
144 }
145 }
146}
147
148impl<'db> Spanned<'db> for AstPath<'db> {
149 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
150 match self.kind(db) {
151 AstPathKind::Identifier(id) => id.span,
152 AstPathKind::GenericArgs { path, args } => path.first_id(db).span.to(db, args.span),
153 AstPathKind::Member { path, id: ident } => path.first_id(db).span.to(db, ident.span),
154 }
155 }
156}
157
158#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
159pub struct SpannedIdentifier<'db> {
160 pub span: Span<'db>,
161 pub id: Identifier<'db>,
162}
163
164impl<'db> Spanned<'db> for SpannedIdentifier<'db> {
165 fn span(&self, _db: &'db dyn crate::Db) -> Span<'db> {
166 self.span
167 }
168}
169
170#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
177pub struct DeferredParse<'db> {
178 pub span: Span<'db>,
179 pub contents: String,
180}
181
182#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
183pub struct AstVisibility<'db> {
184 pub span: Span<'db>,
185 pub kind: VisibilityKind,
186}
187
188impl<'db> Spanned<'db> for AstVisibility<'db> {
189 fn span(&self, _db: &'db dyn crate::Db) -> Span<'db> {
190 self.span
191 }
192}
193
194#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
195pub enum VisibilityKind {
196 Export,
197 Pub,
198}