1use super::DocComment;
4use super::functions::Annotation;
5use super::span::Span;
6use super::type_path::TypePath;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub enum TypeAnnotation {
11 Basic(String),
13 Array(Box<TypeAnnotation>),
15 Tuple(Vec<TypeAnnotation>),
17 Object(Vec<ObjectTypeField>),
19 Function {
21 params: Vec<FunctionParam>,
22 returns: Box<TypeAnnotation>,
23 },
24 Union(Vec<TypeAnnotation>),
26 Intersection(Vec<TypeAnnotation>),
29 Generic {
31 name: TypePath,
32 args: Vec<TypeAnnotation>,
33 },
34 Reference(TypePath),
36 Void,
38 Never,
40 Null,
42 Undefined,
44 Dyn(Vec<TypePath>),
47}
48
49impl TypeAnnotation {
50 pub fn option(inner: TypeAnnotation) -> Self {
51 TypeAnnotation::Generic {
52 name: TypePath::simple("Option"),
53 args: vec![inner],
54 }
55 }
56
57 pub fn option_inner(&self) -> Option<&TypeAnnotation> {
58 match self {
59 TypeAnnotation::Generic { name, args }
60 if name.as_str() == "Option" && args.len() == 1 =>
61 {
62 args.first()
63 }
64 _ => None,
65 }
66 }
67
68 pub fn into_option_inner(self) -> Option<TypeAnnotation> {
69 match self {
70 TypeAnnotation::Generic { name, mut args }
71 if name.as_str() == "Option" && args.len() == 1 =>
72 {
73 Some(args.remove(0))
74 }
75 _ => None,
76 }
77 }
78
79 pub fn is_option(&self) -> bool {
80 self.option_inner().is_some()
81 }
82
83 pub fn as_simple_name(&self) -> Option<&str> {
91 match self {
92 TypeAnnotation::Reference(path) => Some(path.as_str()),
93 TypeAnnotation::Basic(name) => Some(name.as_str()),
94 _ => None,
95 }
96 }
97
98 pub fn as_type_name_str(&self) -> Option<&str> {
101 match self {
102 TypeAnnotation::Basic(name) => Some(name.as_str()),
103 TypeAnnotation::Reference(path) => Some(path.as_str()),
104 _ => None,
105 }
106 }
107
108 pub fn to_type_string(&self) -> String {
110 match self {
111 TypeAnnotation::Basic(name) => name.clone(),
112 TypeAnnotation::Reference(path) => path.to_string(),
113 TypeAnnotation::Array(inner) => format!("Array<{}>", inner.to_type_string()),
114 TypeAnnotation::Generic { name, args }
115 if name.as_str() == "Option" && args.len() == 1 =>
116 {
117 format!("{}?", args[0].to_type_string())
118 }
119 TypeAnnotation::Generic { name, args } => {
120 let args_str: Vec<String> = args.iter().map(|a| a.to_type_string()).collect();
121 format!("{}<{}>", name, args_str.join(", "))
122 }
123 TypeAnnotation::Tuple(items) => {
124 let items_str: Vec<String> = items.iter().map(|t| t.to_type_string()).collect();
125 format!("[{}]", items_str.join(", "))
126 }
127 TypeAnnotation::Union(items) => {
128 let items_str: Vec<String> = items.iter().map(|t| t.to_type_string()).collect();
129 items_str.join(" | ")
130 }
131 TypeAnnotation::Void => "void".to_string(),
132 TypeAnnotation::Never => "never".to_string(),
133 TypeAnnotation::Null => "null".to_string(),
134 TypeAnnotation::Undefined => "undefined".to_string(),
135 TypeAnnotation::Object(fields) => {
136 let fields_str: Vec<String> = fields
137 .iter()
138 .map(|f| {
139 let opt = if f.optional { "?" } else { "" };
140 let alias = f
143 .annotations
144 .iter()
145 .find(|a| a.name == "alias")
146 .and_then(|a| a.args.first())
147 .and_then(|arg| match arg {
148 super::expressions::Expr::Literal(
149 super::literals::Literal::String(s),
150 _,
151 ) => Some(s.as_str()),
152 _ => None,
153 });
154 let alias_str = alias.map(|a| format!("@\"{}\" ", a)).unwrap_or_default();
155 format!(
156 "{}{}{}: {}",
157 alias_str,
158 f.name,
159 opt,
160 f.type_annotation.to_type_string()
161 )
162 })
163 .collect();
164 format!("{{{}}}", fields_str.join(", "))
165 }
166 _ => "any".to_string(),
167 }
168 }
169}
170
171#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
172pub struct ObjectTypeField {
173 pub name: String,
174 pub optional: bool,
175 pub type_annotation: TypeAnnotation,
176 #[serde(default)]
178 pub annotations: Vec<Annotation>,
179}
180
181#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct FunctionParam {
183 pub name: Option<String>,
184 pub optional: bool,
185 pub type_annotation: TypeAnnotation,
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct TypeParam {
190 pub name: String,
191 #[serde(default)]
192 pub span: Span,
193 #[serde(default)]
194 pub doc_comment: Option<DocComment>,
195 pub default_type: Option<TypeAnnotation>,
197 #[serde(default)]
199 pub trait_bounds: Vec<TypePath>,
200}
201
202#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
204pub struct WherePredicate {
205 pub type_name: String,
206 pub bounds: Vec<TypePath>,
207}
208
209impl PartialEq for TypeParam {
210 fn eq(&self, other: &Self) -> bool {
211 self.name == other.name
212 && self.doc_comment == other.doc_comment
213 && self.default_type == other.default_type
214 && self.trait_bounds == other.trait_bounds
215 }
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct TypeAliasDef {
220 pub name: String,
221 #[serde(default)]
222 pub doc_comment: Option<DocComment>,
223 pub type_params: Option<Vec<TypeParam>>,
224 pub type_annotation: TypeAnnotation,
225 pub meta_param_overrides: Option<std::collections::HashMap<String, super::expressions::Expr>>,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct InterfaceDef {
231 pub name: String,
232 #[serde(default)]
233 pub doc_comment: Option<DocComment>,
234 pub type_params: Option<Vec<TypeParam>>,
235 pub members: Vec<InterfaceMember>,
236}
237
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub enum InterfaceMember {
240 Property {
242 name: String,
243 optional: bool,
244 type_annotation: TypeAnnotation,
245 #[serde(default)]
246 span: Span,
247 #[serde(default)]
248 doc_comment: Option<DocComment>,
249 },
250 Method {
252 name: String,
253 optional: bool,
254 params: Vec<FunctionParam>,
255 return_type: TypeAnnotation,
256 is_async: bool,
258 #[serde(default)]
259 span: Span,
260 #[serde(default)]
261 doc_comment: Option<DocComment>,
262 },
263 IndexSignature {
265 param_name: String,
266 param_type: String, return_type: TypeAnnotation,
268 #[serde(default)]
269 span: Span,
270 #[serde(default)]
271 doc_comment: Option<DocComment>,
272 },
273}
274
275impl InterfaceMember {
276 pub fn span(&self) -> Span {
277 match self {
278 InterfaceMember::Property { span, .. }
279 | InterfaceMember::Method { span, .. }
280 | InterfaceMember::IndexSignature { span, .. } => *span,
281 }
282 }
283
284 pub fn doc_comment(&self) -> Option<&DocComment> {
285 match self {
286 InterfaceMember::Property { doc_comment, .. }
287 | InterfaceMember::Method { doc_comment, .. }
288 | InterfaceMember::IndexSignature { doc_comment, .. } => doc_comment.as_ref(),
289 }
290 }
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
294pub struct EnumDef {
295 pub name: String,
296 #[serde(default)]
297 pub doc_comment: Option<DocComment>,
298 pub type_params: Option<Vec<TypeParam>>,
299 pub members: Vec<EnumMember>,
300 #[serde(default)]
302 pub annotations: Vec<super::Annotation>,
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize)]
306pub struct EnumMember {
307 pub name: String,
308 pub kind: EnumMemberKind,
309 #[serde(default)]
310 pub span: Span,
311 #[serde(default)]
312 pub doc_comment: Option<DocComment>,
313}
314
315#[derive(Debug, Clone, Serialize, Deserialize)]
316pub enum EnumMemberKind {
317 Unit { value: Option<EnumValue> },
319 Tuple(Vec<TypeAnnotation>),
321 Struct(Vec<ObjectTypeField>),
323}
324
325#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
326pub enum EnumValue {
327 String(String),
328 Number(f64),
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize)]
333pub enum TraitMember {
334 Required(InterfaceMember),
336 Default(MethodDef),
338 AssociatedType {
340 name: String,
341 bounds: Vec<TypeAnnotation>,
342 #[serde(default)]
343 span: Span,
344 #[serde(default)]
345 doc_comment: Option<DocComment>,
346 },
347}
348
349impl TraitMember {
350 pub fn span(&self) -> Span {
351 match self {
352 TraitMember::Required(member) => member.span(),
353 TraitMember::Default(method) => method.span,
354 TraitMember::AssociatedType { span, .. } => *span,
355 }
356 }
357
358 pub fn doc_comment(&self) -> Option<&DocComment> {
359 match self {
360 TraitMember::Required(member) => member.doc_comment(),
361 TraitMember::Default(method) => method.doc_comment.as_ref(),
362 TraitMember::AssociatedType { doc_comment, .. } => doc_comment.as_ref(),
363 }
364 }
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize)]
370pub struct AssociatedTypeBinding {
371 pub name: String,
372 pub concrete_type: TypeAnnotation,
373}
374
375#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct TraitDef {
387 pub name: String,
388 #[serde(default)]
389 pub doc_comment: Option<DocComment>,
390 pub type_params: Option<Vec<TypeParam>>,
391 #[serde(default)]
393 pub super_traits: Vec<TypeAnnotation>,
394 pub members: Vec<TraitMember>,
395 #[serde(default)]
397 pub annotations: Vec<super::Annotation>,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize)]
412pub struct ImplBlock {
413 pub trait_name: TypeName,
415 pub target_type: TypeName,
417 pub impl_name: Option<String>,
420 pub methods: Vec<MethodDef>,
422 pub associated_type_bindings: Vec<AssociatedTypeBinding>,
424 pub where_clause: Option<Vec<WherePredicate>>,
426}
427
428#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
430pub struct ExtendStatement {
431 pub type_name: TypeName,
433 pub methods: Vec<MethodDef>,
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct MethodDef {
439 pub name: String,
441 #[serde(default)]
442 pub span: Span,
443 #[serde(default, skip_serializing_if = "Option::is_none")]
448 pub declaring_module_path: Option<String>,
449 #[serde(default)]
450 pub doc_comment: Option<DocComment>,
451 #[serde(default)]
453 pub annotations: Vec<super::functions::Annotation>,
454 #[serde(default)]
456 pub type_params: Option<Vec<TypeParam>>,
457 pub params: Vec<super::functions::FunctionParameter>,
459 pub when_clause: Option<Box<super::expressions::Expr>>,
461 pub return_type: Option<TypeAnnotation>,
463 pub body: Vec<super::statements::Statement>,
465 pub is_async: bool,
467}
468
469impl PartialEq for MethodDef {
470 fn eq(&self, other: &Self) -> bool {
471 self.name == other.name
472 && self.doc_comment == other.doc_comment
473 && self.annotations == other.annotations
474 && self.type_params == other.type_params
475 && self.params == other.params
476 && self.when_clause == other.when_clause
477 && self.return_type == other.return_type
478 && self.body == other.body
479 && self.is_async == other.is_async
480 }
481}
482
483#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
484pub enum TypeName {
485 Simple(TypePath),
487 Generic {
489 name: TypePath,
490 type_args: Vec<TypeAnnotation>,
491 },
492}
493
494#[derive(Debug, Clone, Serialize, Deserialize)]
505pub struct StructTypeDef {
506 pub name: String,
507 #[serde(default)]
508 pub doc_comment: Option<DocComment>,
509 pub type_params: Option<Vec<TypeParam>>,
510 pub fields: Vec<StructField>,
511 #[serde(default)]
513 pub methods: Vec<MethodDef>,
514 pub annotations: Vec<Annotation>,
516 #[serde(default)]
518 pub native_layout: Option<NativeLayoutBinding>,
519}
520
521#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
523pub struct NativeLayoutBinding {
524 pub abi: String,
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize)]
542pub struct StructField {
543 pub annotations: Vec<Annotation>,
544 pub is_comptime: bool,
545 pub name: String,
546 #[serde(default)]
547 pub span: Span,
548 #[serde(default)]
549 pub doc_comment: Option<DocComment>,
550 pub type_annotation: TypeAnnotation,
551 pub default_value: Option<super::expressions::Expr>,
552}
553
554impl PartialEq for StructField {
555 fn eq(&self, other: &Self) -> bool {
556 self.annotations == other.annotations
557 && self.is_comptime == other.is_comptime
558 && self.name == other.name
559 && self.doc_comment == other.doc_comment
560 && self.type_annotation == other.type_annotation
561 && self.default_value == other.default_value
562 }
563}