1use super::DocComment;
4use super::functions::Annotation;
5use super::span::Span;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub enum TypeAnnotation {
10 Basic(String),
12 Array(Box<TypeAnnotation>),
14 Tuple(Vec<TypeAnnotation>),
16 Object(Vec<ObjectTypeField>),
18 Function {
20 params: Vec<FunctionParam>,
21 returns: Box<TypeAnnotation>,
22 },
23 Union(Vec<TypeAnnotation>),
25 Intersection(Vec<TypeAnnotation>),
28 Generic {
30 name: String,
31 args: Vec<TypeAnnotation>,
32 },
33 Reference(String),
35 Void,
37 Never,
39 Null,
41 Undefined,
43 Dyn(Vec<String>),
46}
47
48impl TypeAnnotation {
49 pub fn option(inner: TypeAnnotation) -> Self {
50 TypeAnnotation::Generic {
51 name: "Option".to_string(),
52 args: vec![inner],
53 }
54 }
55
56 pub fn option_inner(&self) -> Option<&TypeAnnotation> {
57 match self {
58 TypeAnnotation::Generic { name, args } if name == "Option" && args.len() == 1 => {
59 args.first()
60 }
61 _ => None,
62 }
63 }
64
65 pub fn into_option_inner(self) -> Option<TypeAnnotation> {
66 match self {
67 TypeAnnotation::Generic { name, mut args } if name == "Option" && args.len() == 1 => {
68 Some(args.remove(0))
69 }
70 _ => None,
71 }
72 }
73
74 pub fn is_option(&self) -> bool {
75 self.option_inner().is_some()
76 }
77
78 pub fn as_simple_name(&self) -> Option<&str> {
86 match self {
87 TypeAnnotation::Reference(name) => Some(name.as_str()),
88 TypeAnnotation::Basic(name) => Some(name.as_str()),
89 _ => None,
90 }
91 }
92
93 pub fn to_type_string(&self) -> String {
95 match self {
96 TypeAnnotation::Basic(name) | TypeAnnotation::Reference(name) => name.clone(),
97 TypeAnnotation::Array(inner) => format!("Array<{}>", inner.to_type_string()),
98 TypeAnnotation::Generic { name, args } if name == "Option" && args.len() == 1 => {
99 format!("{}?", args[0].to_type_string())
100 }
101 TypeAnnotation::Generic { name, args } => {
102 let args_str: Vec<String> = args.iter().map(|a| a.to_type_string()).collect();
103 format!("{}<{}>", name, args_str.join(", "))
104 }
105 TypeAnnotation::Tuple(items) => {
106 let items_str: Vec<String> = items.iter().map(|t| t.to_type_string()).collect();
107 format!("[{}]", items_str.join(", "))
108 }
109 TypeAnnotation::Union(items) => {
110 let items_str: Vec<String> = items.iter().map(|t| t.to_type_string()).collect();
111 items_str.join(" | ")
112 }
113 TypeAnnotation::Void => "void".to_string(),
114 TypeAnnotation::Never => "never".to_string(),
115 TypeAnnotation::Null => "null".to_string(),
116 TypeAnnotation::Undefined => "undefined".to_string(),
117 TypeAnnotation::Object(fields) => {
118 let fields_str: Vec<String> = fields
119 .iter()
120 .map(|f| {
121 let opt = if f.optional { "?" } else { "" };
122 let alias = f
125 .annotations
126 .iter()
127 .find(|a| a.name == "alias")
128 .and_then(|a| a.args.first())
129 .and_then(|arg| match arg {
130 super::expressions::Expr::Literal(
131 super::literals::Literal::String(s),
132 _,
133 ) => Some(s.as_str()),
134 _ => None,
135 });
136 let alias_str = alias.map(|a| format!("@\"{}\" ", a)).unwrap_or_default();
137 format!(
138 "{}{}{}: {}",
139 alias_str,
140 f.name,
141 opt,
142 f.type_annotation.to_type_string()
143 )
144 })
145 .collect();
146 format!("{{{}}}", fields_str.join(", "))
147 }
148 _ => "any".to_string(),
149 }
150 }
151}
152
153#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
154pub struct ObjectTypeField {
155 pub name: String,
156 pub optional: bool,
157 pub type_annotation: TypeAnnotation,
158 #[serde(default)]
160 pub annotations: Vec<Annotation>,
161}
162
163#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
164pub struct FunctionParam {
165 pub name: Option<String>,
166 pub optional: bool,
167 pub type_annotation: TypeAnnotation,
168}
169
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct TypeParam {
172 pub name: String,
173 #[serde(default)]
174 pub span: Span,
175 #[serde(default)]
176 pub doc_comment: Option<DocComment>,
177 pub default_type: Option<TypeAnnotation>,
179 #[serde(default)]
181 pub trait_bounds: Vec<String>,
182}
183
184#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
186pub struct WherePredicate {
187 pub type_name: String,
188 pub bounds: Vec<String>,
189}
190
191impl PartialEq for TypeParam {
192 fn eq(&self, other: &Self) -> bool {
193 self.name == other.name
194 && self.doc_comment == other.doc_comment
195 && self.default_type == other.default_type
196 && self.trait_bounds == other.trait_bounds
197 }
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct TypeAliasDef {
202 pub name: String,
203 #[serde(default)]
204 pub doc_comment: Option<DocComment>,
205 pub type_params: Option<Vec<TypeParam>>,
206 pub type_annotation: TypeAnnotation,
207 pub meta_param_overrides: Option<std::collections::HashMap<String, super::expressions::Expr>>,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
212pub struct InterfaceDef {
213 pub name: String,
214 #[serde(default)]
215 pub doc_comment: Option<DocComment>,
216 pub type_params: Option<Vec<TypeParam>>,
217 pub members: Vec<InterfaceMember>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub enum InterfaceMember {
222 Property {
224 name: String,
225 optional: bool,
226 type_annotation: TypeAnnotation,
227 #[serde(default)]
228 span: Span,
229 #[serde(default)]
230 doc_comment: Option<DocComment>,
231 },
232 Method {
234 name: String,
235 optional: bool,
236 params: Vec<FunctionParam>,
237 return_type: TypeAnnotation,
238 is_async: bool,
240 #[serde(default)]
241 span: Span,
242 #[serde(default)]
243 doc_comment: Option<DocComment>,
244 },
245 IndexSignature {
247 param_name: String,
248 param_type: String, return_type: TypeAnnotation,
250 #[serde(default)]
251 span: Span,
252 #[serde(default)]
253 doc_comment: Option<DocComment>,
254 },
255}
256
257impl InterfaceMember {
258 pub fn span(&self) -> Span {
259 match self {
260 InterfaceMember::Property { span, .. }
261 | InterfaceMember::Method { span, .. }
262 | InterfaceMember::IndexSignature { span, .. } => *span,
263 }
264 }
265
266 pub fn doc_comment(&self) -> Option<&DocComment> {
267 match self {
268 InterfaceMember::Property { doc_comment, .. }
269 | InterfaceMember::Method { doc_comment, .. }
270 | InterfaceMember::IndexSignature { doc_comment, .. } => doc_comment.as_ref(),
271 }
272 }
273}
274
275#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct EnumDef {
277 pub name: String,
278 #[serde(default)]
279 pub doc_comment: Option<DocComment>,
280 pub type_params: Option<Vec<TypeParam>>,
281 pub members: Vec<EnumMember>,
282 #[serde(default)]
284 pub annotations: Vec<super::Annotation>,
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct EnumMember {
289 pub name: String,
290 pub kind: EnumMemberKind,
291 #[serde(default)]
292 pub span: Span,
293 #[serde(default)]
294 pub doc_comment: Option<DocComment>,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub enum EnumMemberKind {
299 Unit { value: Option<EnumValue> },
301 Tuple(Vec<TypeAnnotation>),
303 Struct(Vec<ObjectTypeField>),
305}
306
307#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
308pub enum EnumValue {
309 String(String),
310 Number(f64),
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub enum TraitMember {
316 Required(InterfaceMember),
318 Default(MethodDef),
320 AssociatedType {
322 name: String,
323 bounds: Vec<TypeAnnotation>,
324 #[serde(default)]
325 span: Span,
326 #[serde(default)]
327 doc_comment: Option<DocComment>,
328 },
329}
330
331impl TraitMember {
332 pub fn span(&self) -> Span {
333 match self {
334 TraitMember::Required(member) => member.span(),
335 TraitMember::Default(method) => method.span,
336 TraitMember::AssociatedType { span, .. } => *span,
337 }
338 }
339
340 pub fn doc_comment(&self) -> Option<&DocComment> {
341 match self {
342 TraitMember::Required(member) => member.doc_comment(),
343 TraitMember::Default(method) => method.doc_comment.as_ref(),
344 TraitMember::AssociatedType { doc_comment, .. } => doc_comment.as_ref(),
345 }
346 }
347}
348
349#[derive(Debug, Clone, Serialize, Deserialize)]
352pub struct AssociatedTypeBinding {
353 pub name: String,
354 pub concrete_type: TypeAnnotation,
355}
356
357#[derive(Debug, Clone, Serialize, Deserialize)]
368pub struct TraitDef {
369 pub name: String,
370 #[serde(default)]
371 pub doc_comment: Option<DocComment>,
372 pub type_params: Option<Vec<TypeParam>>,
373 pub members: Vec<TraitMember>,
374 #[serde(default)]
376 pub annotations: Vec<super::Annotation>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
391pub struct ImplBlock {
392 pub trait_name: TypeName,
394 pub target_type: TypeName,
396 pub impl_name: Option<String>,
399 pub methods: Vec<MethodDef>,
401 pub associated_type_bindings: Vec<AssociatedTypeBinding>,
403 pub where_clause: Option<Vec<WherePredicate>>,
405}
406
407#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
409pub struct ExtendStatement {
410 pub type_name: TypeName,
412 pub methods: Vec<MethodDef>,
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
417pub struct MethodDef {
418 pub name: String,
420 #[serde(default)]
421 pub span: Span,
422 #[serde(default, skip_serializing_if = "Option::is_none")]
427 pub declaring_module_path: Option<String>,
428 #[serde(default)]
429 pub doc_comment: Option<DocComment>,
430 #[serde(default)]
432 pub annotations: Vec<super::functions::Annotation>,
433 pub params: Vec<super::functions::FunctionParameter>,
435 pub when_clause: Option<Box<super::expressions::Expr>>,
437 pub return_type: Option<TypeAnnotation>,
439 pub body: Vec<super::statements::Statement>,
441 pub is_async: bool,
443}
444
445impl PartialEq for MethodDef {
446 fn eq(&self, other: &Self) -> bool {
447 self.name == other.name
448 && self.doc_comment == other.doc_comment
449 && self.annotations == other.annotations
450 && self.params == other.params
451 && self.when_clause == other.when_clause
452 && self.return_type == other.return_type
453 && self.body == other.body
454 && self.is_async == other.is_async
455 }
456}
457
458#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
459pub enum TypeName {
460 Simple(String),
462 Generic {
464 name: String,
465 type_args: Vec<TypeAnnotation>,
466 },
467}
468
469#[derive(Debug, Clone, Serialize, Deserialize)]
480pub struct StructTypeDef {
481 pub name: String,
482 #[serde(default)]
483 pub doc_comment: Option<DocComment>,
484 pub type_params: Option<Vec<TypeParam>>,
485 pub fields: Vec<StructField>,
486 #[serde(default)]
488 pub methods: Vec<MethodDef>,
489 pub annotations: Vec<Annotation>,
491 #[serde(default)]
493 pub native_layout: Option<NativeLayoutBinding>,
494}
495
496#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
498pub struct NativeLayoutBinding {
499 pub abi: String,
501}
502
503#[derive(Debug, Clone, Serialize, Deserialize)]
517pub struct StructField {
518 pub annotations: Vec<Annotation>,
519 pub is_comptime: bool,
520 pub name: String,
521 #[serde(default)]
522 pub span: Span,
523 #[serde(default)]
524 pub doc_comment: Option<DocComment>,
525 pub type_annotation: TypeAnnotation,
526 pub default_value: Option<super::expressions::Expr>,
527}
528
529impl PartialEq for StructField {
530 fn eq(&self, other: &Self) -> bool {
531 self.annotations == other.annotations
532 && self.is_comptime == other.is_comptime
533 && self.name == other.name
534 && self.doc_comment == other.doc_comment
535 && self.type_annotation == other.type_annotation
536 && self.default_value == other.default_value
537 }
538}