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)]
201pub enum TypeParam {
202 Type {
204 name: String,
205 #[serde(default)]
206 span: Span,
207 #[serde(default)]
208 doc_comment: Option<DocComment>,
209 default_type: Option<TypeAnnotation>,
211 #[serde(default)]
213 trait_bounds: Vec<TypePath>,
214 },
215 Const {
221 name: String,
222 #[serde(default)]
223 span: Span,
224 #[serde(default)]
225 doc_comment: Option<DocComment>,
226 ty: TypeAnnotation,
228 default: Option<super::expressions::Expr>,
230 },
231}
232
233impl TypeParam {
234 pub fn name(&self) -> &str {
236 match self {
237 TypeParam::Type { name, .. } | TypeParam::Const { name, .. } => name,
238 }
239 }
240
241 pub fn span(&self) -> &Span {
243 match self {
244 TypeParam::Type { span, .. } | TypeParam::Const { span, .. } => span,
245 }
246 }
247
248 pub fn doc_comment(&self) -> Option<&DocComment> {
250 match self {
251 TypeParam::Type { doc_comment, .. } | TypeParam::Const { doc_comment, .. } => {
252 doc_comment.as_ref()
253 }
254 }
255 }
256
257 pub fn trait_bounds(&self) -> &[TypePath] {
261 match self {
262 TypeParam::Type { trait_bounds, .. } => trait_bounds.as_slice(),
263 TypeParam::Const { .. } => &[],
266 }
267 }
268
269 pub fn default_type(&self) -> Option<&TypeAnnotation> {
271 match self {
272 TypeParam::Type { default_type, .. } => default_type.as_ref(),
273 TypeParam::Const { .. } => None,
274 }
275 }
276
277 pub fn is_const(&self) -> bool {
279 matches!(self, TypeParam::Const { .. })
280 }
281
282 pub fn simple(name: impl Into<String>) -> Self {
286 TypeParam::Type {
287 name: name.into(),
288 span: Span::DUMMY,
289 doc_comment: None,
290 default_type: None,
291 trait_bounds: Vec::new(),
292 }
293 }
294}
295
296#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
298pub struct WherePredicate {
299 pub type_name: String,
300 pub bounds: Vec<TypePath>,
301}
302
303impl PartialEq for TypeParam {
304 fn eq(&self, other: &Self) -> bool {
305 match (self, other) {
306 (
307 TypeParam::Type {
308 name: ln,
309 doc_comment: ld,
310 default_type: ldt,
311 trait_bounds: ltb,
312 ..
313 },
314 TypeParam::Type {
315 name: rn,
316 doc_comment: rd,
317 default_type: rdt,
318 trait_bounds: rtb,
319 ..
320 },
321 ) => ln == rn && ld == rd && ldt == rdt && ltb == rtb,
322 (
323 TypeParam::Const {
324 name: ln,
325 doc_comment: ld,
326 ty: lty,
327 default: ldef,
328 ..
329 },
330 TypeParam::Const {
331 name: rn,
332 doc_comment: rd,
333 ty: rty,
334 default: rdef,
335 ..
336 },
337 ) => ln == rn && ld == rd && lty == rty && ldef == rdef,
338 _ => false,
339 }
340 }
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
344pub struct TypeAliasDef {
345 pub name: String,
346 #[serde(default)]
347 pub doc_comment: Option<DocComment>,
348 pub type_params: Option<Vec<TypeParam>>,
349 pub type_annotation: TypeAnnotation,
350 pub meta_param_overrides: Option<std::collections::HashMap<String, super::expressions::Expr>>,
352}
353
354#[derive(Debug, Clone, Serialize, Deserialize)]
360pub enum TraitMemberSignature {
361 Property {
363 name: String,
364 optional: bool,
365 type_annotation: TypeAnnotation,
366 #[serde(default)]
367 span: Span,
368 #[serde(default)]
369 doc_comment: Option<DocComment>,
370 },
371 Method {
373 name: String,
374 optional: bool,
375 params: Vec<FunctionParam>,
376 return_type: TypeAnnotation,
377 is_async: bool,
379 #[serde(default)]
380 span: Span,
381 #[serde(default)]
382 doc_comment: Option<DocComment>,
383 },
384 IndexSignature {
386 param_name: String,
387 param_type: String, return_type: TypeAnnotation,
389 #[serde(default)]
390 span: Span,
391 #[serde(default)]
392 doc_comment: Option<DocComment>,
393 },
394}
395
396impl TraitMemberSignature {
397 pub fn span(&self) -> Span {
398 match self {
399 TraitMemberSignature::Property { span, .. }
400 | TraitMemberSignature::Method { span, .. }
401 | TraitMemberSignature::IndexSignature { span, .. } => *span,
402 }
403 }
404
405 pub fn doc_comment(&self) -> Option<&DocComment> {
406 match self {
407 TraitMemberSignature::Property { doc_comment, .. }
408 | TraitMemberSignature::Method { doc_comment, .. }
409 | TraitMemberSignature::IndexSignature { doc_comment, .. } => doc_comment.as_ref(),
410 }
411 }
412}
413
414#[derive(Debug, Clone, Serialize, Deserialize)]
415pub struct EnumDef {
416 pub name: String,
417 #[serde(default)]
418 pub doc_comment: Option<DocComment>,
419 pub type_params: Option<Vec<TypeParam>>,
420 pub members: Vec<EnumMember>,
421 #[serde(default)]
423 pub annotations: Vec<super::Annotation>,
424}
425
426#[derive(Debug, Clone, Serialize, Deserialize)]
427pub struct EnumMember {
428 pub name: String,
429 pub kind: EnumMemberKind,
430 #[serde(default)]
431 pub span: Span,
432 #[serde(default)]
433 pub doc_comment: Option<DocComment>,
434}
435
436#[derive(Debug, Clone, Serialize, Deserialize)]
437pub enum EnumMemberKind {
438 Unit { value: Option<EnumValue> },
440 Tuple(Vec<TypeAnnotation>),
442 Struct(Vec<ObjectTypeField>),
444}
445
446#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
447pub enum EnumValue {
448 String(String),
449 Number(f64),
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
454pub enum TraitMember {
455 Required(TraitMemberSignature),
457 Default(MethodDef),
459 AssociatedType {
461 name: String,
462 bounds: Vec<TypeAnnotation>,
463 #[serde(default)]
464 span: Span,
465 #[serde(default)]
466 doc_comment: Option<DocComment>,
467 },
468}
469
470impl TraitMember {
471 pub fn span(&self) -> Span {
472 match self {
473 TraitMember::Required(member) => member.span(),
474 TraitMember::Default(method) => method.span,
475 TraitMember::AssociatedType { span, .. } => *span,
476 }
477 }
478
479 pub fn doc_comment(&self) -> Option<&DocComment> {
480 match self {
481 TraitMember::Required(member) => member.doc_comment(),
482 TraitMember::Default(method) => method.doc_comment.as_ref(),
483 TraitMember::AssociatedType { doc_comment, .. } => doc_comment.as_ref(),
484 }
485 }
486}
487
488#[derive(Debug, Clone, Serialize, Deserialize)]
491pub struct AssociatedTypeBinding {
492 pub name: String,
493 pub concrete_type: TypeAnnotation,
494}
495
496#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct TraitDef {
508 pub name: String,
509 #[serde(default)]
510 pub doc_comment: Option<DocComment>,
511 pub type_params: Option<Vec<TypeParam>>,
512 #[serde(default)]
514 pub super_traits: Vec<TypeAnnotation>,
515 pub members: Vec<TraitMember>,
516 #[serde(default)]
518 pub annotations: Vec<super::Annotation>,
519 #[serde(default)]
524 pub is_comptime: bool,
525}
526
527#[derive(Debug, Clone, Serialize, Deserialize)]
539pub struct ImplBlock {
540 pub trait_name: TypeName,
542 pub target_type: TypeName,
544 pub impl_name: Option<String>,
547 pub methods: Vec<MethodDef>,
549 pub associated_type_bindings: Vec<AssociatedTypeBinding>,
551 pub where_clause: Option<Vec<WherePredicate>>,
553 #[serde(default)]
558 pub is_comptime: bool,
559}
560
561#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
563pub struct ExtendStatement {
564 pub type_name: TypeName,
566 pub methods: Vec<MethodDef>,
568}
569
570#[derive(Debug, Clone, Serialize, Deserialize)]
571pub struct MethodDef {
572 pub name: String,
574 #[serde(default)]
575 pub span: Span,
576 #[serde(default, skip_serializing_if = "Option::is_none")]
581 pub declaring_module_path: Option<String>,
582 #[serde(default)]
583 pub doc_comment: Option<DocComment>,
584 #[serde(default)]
586 pub annotations: Vec<super::functions::Annotation>,
587 #[serde(default)]
589 pub type_params: Option<Vec<TypeParam>>,
590 pub params: Vec<super::functions::FunctionParameter>,
592 pub when_clause: Option<Box<super::expressions::Expr>>,
594 pub return_type: Option<TypeAnnotation>,
596 pub body: Vec<super::statements::Statement>,
598 pub is_async: bool,
600}
601
602impl PartialEq for MethodDef {
603 fn eq(&self, other: &Self) -> bool {
604 self.name == other.name
605 && self.doc_comment == other.doc_comment
606 && self.annotations == other.annotations
607 && self.type_params == other.type_params
608 && self.params == other.params
609 && self.when_clause == other.when_clause
610 && self.return_type == other.return_type
611 && self.body == other.body
612 && self.is_async == other.is_async
613 }
614}
615
616#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
617pub enum TypeName {
618 Simple(TypePath),
620 Generic {
622 name: TypePath,
623 type_args: Vec<TypeAnnotation>,
624 },
625}
626
627#[derive(Debug, Clone, Serialize, Deserialize)]
638pub struct StructTypeDef {
639 pub name: String,
640 #[serde(default)]
641 pub doc_comment: Option<DocComment>,
642 pub type_params: Option<Vec<TypeParam>>,
643 pub fields: Vec<StructField>,
644 #[serde(default)]
646 pub methods: Vec<MethodDef>,
647 pub annotations: Vec<Annotation>,
649 #[serde(default)]
651 pub native_layout: Option<NativeLayoutBinding>,
652}
653
654#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
656pub struct NativeLayoutBinding {
657 pub abi: String,
659}
660
661#[derive(Debug, Clone, Serialize, Deserialize)]
675pub struct StructField {
676 pub annotations: Vec<Annotation>,
677 pub is_comptime: bool,
678 pub name: String,
679 #[serde(default)]
680 pub span: Span,
681 #[serde(default)]
682 pub doc_comment: Option<DocComment>,
683 pub type_annotation: TypeAnnotation,
684 pub default_value: Option<super::expressions::Expr>,
685}
686
687impl PartialEq for StructField {
688 fn eq(&self, other: &Self) -> bool {
689 self.annotations == other.annotations
690 && self.is_comptime == other.is_comptime
691 && self.name == other.name
692 && self.doc_comment == other.doc_comment
693 && self.type_annotation == other.type_annotation
694 && self.default_value == other.default_value
695 }
696}