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)]
355pub struct InterfaceDef {
356 pub name: String,
357 #[serde(default)]
358 pub doc_comment: Option<DocComment>,
359 pub type_params: Option<Vec<TypeParam>>,
360 pub members: Vec<InterfaceMember>,
361}
362
363#[derive(Debug, Clone, Serialize, Deserialize)]
364pub enum InterfaceMember {
365 Property {
367 name: String,
368 optional: bool,
369 type_annotation: TypeAnnotation,
370 #[serde(default)]
371 span: Span,
372 #[serde(default)]
373 doc_comment: Option<DocComment>,
374 },
375 Method {
377 name: String,
378 optional: bool,
379 params: Vec<FunctionParam>,
380 return_type: TypeAnnotation,
381 is_async: bool,
383 #[serde(default)]
384 span: Span,
385 #[serde(default)]
386 doc_comment: Option<DocComment>,
387 },
388 IndexSignature {
390 param_name: String,
391 param_type: String, return_type: TypeAnnotation,
393 #[serde(default)]
394 span: Span,
395 #[serde(default)]
396 doc_comment: Option<DocComment>,
397 },
398}
399
400impl InterfaceMember {
401 pub fn span(&self) -> Span {
402 match self {
403 InterfaceMember::Property { span, .. }
404 | InterfaceMember::Method { span, .. }
405 | InterfaceMember::IndexSignature { span, .. } => *span,
406 }
407 }
408
409 pub fn doc_comment(&self) -> Option<&DocComment> {
410 match self {
411 InterfaceMember::Property { doc_comment, .. }
412 | InterfaceMember::Method { doc_comment, .. }
413 | InterfaceMember::IndexSignature { doc_comment, .. } => doc_comment.as_ref(),
414 }
415 }
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize)]
419pub struct EnumDef {
420 pub name: String,
421 #[serde(default)]
422 pub doc_comment: Option<DocComment>,
423 pub type_params: Option<Vec<TypeParam>>,
424 pub members: Vec<EnumMember>,
425 #[serde(default)]
427 pub annotations: Vec<super::Annotation>,
428}
429
430#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct EnumMember {
432 pub name: String,
433 pub kind: EnumMemberKind,
434 #[serde(default)]
435 pub span: Span,
436 #[serde(default)]
437 pub doc_comment: Option<DocComment>,
438}
439
440#[derive(Debug, Clone, Serialize, Deserialize)]
441pub enum EnumMemberKind {
442 Unit { value: Option<EnumValue> },
444 Tuple(Vec<TypeAnnotation>),
446 Struct(Vec<ObjectTypeField>),
448}
449
450#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
451pub enum EnumValue {
452 String(String),
453 Number(f64),
454}
455
456#[derive(Debug, Clone, Serialize, Deserialize)]
458pub enum TraitMember {
459 Required(InterfaceMember),
461 Default(MethodDef),
463 AssociatedType {
465 name: String,
466 bounds: Vec<TypeAnnotation>,
467 #[serde(default)]
468 span: Span,
469 #[serde(default)]
470 doc_comment: Option<DocComment>,
471 },
472}
473
474impl TraitMember {
475 pub fn span(&self) -> Span {
476 match self {
477 TraitMember::Required(member) => member.span(),
478 TraitMember::Default(method) => method.span,
479 TraitMember::AssociatedType { span, .. } => *span,
480 }
481 }
482
483 pub fn doc_comment(&self) -> Option<&DocComment> {
484 match self {
485 TraitMember::Required(member) => member.doc_comment(),
486 TraitMember::Default(method) => method.doc_comment.as_ref(),
487 TraitMember::AssociatedType { doc_comment, .. } => doc_comment.as_ref(),
488 }
489 }
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct AssociatedTypeBinding {
496 pub name: String,
497 pub concrete_type: TypeAnnotation,
498}
499
500#[derive(Debug, Clone, Serialize, Deserialize)]
511pub struct TraitDef {
512 pub name: String,
513 #[serde(default)]
514 pub doc_comment: Option<DocComment>,
515 pub type_params: Option<Vec<TypeParam>>,
516 #[serde(default)]
518 pub super_traits: Vec<TypeAnnotation>,
519 pub members: Vec<TraitMember>,
520 #[serde(default)]
522 pub annotations: Vec<super::Annotation>,
523}
524
525#[derive(Debug, Clone, Serialize, Deserialize)]
537pub struct ImplBlock {
538 pub trait_name: TypeName,
540 pub target_type: TypeName,
542 pub impl_name: Option<String>,
545 pub methods: Vec<MethodDef>,
547 pub associated_type_bindings: Vec<AssociatedTypeBinding>,
549 pub where_clause: Option<Vec<WherePredicate>>,
551}
552
553#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
555pub struct ExtendStatement {
556 pub type_name: TypeName,
558 pub methods: Vec<MethodDef>,
560}
561
562#[derive(Debug, Clone, Serialize, Deserialize)]
563pub struct MethodDef {
564 pub name: String,
566 #[serde(default)]
567 pub span: Span,
568 #[serde(default, skip_serializing_if = "Option::is_none")]
573 pub declaring_module_path: Option<String>,
574 #[serde(default)]
575 pub doc_comment: Option<DocComment>,
576 #[serde(default)]
578 pub annotations: Vec<super::functions::Annotation>,
579 #[serde(default)]
581 pub type_params: Option<Vec<TypeParam>>,
582 pub params: Vec<super::functions::FunctionParameter>,
584 pub when_clause: Option<Box<super::expressions::Expr>>,
586 pub return_type: Option<TypeAnnotation>,
588 pub body: Vec<super::statements::Statement>,
590 pub is_async: bool,
592}
593
594impl PartialEq for MethodDef {
595 fn eq(&self, other: &Self) -> bool {
596 self.name == other.name
597 && self.doc_comment == other.doc_comment
598 && self.annotations == other.annotations
599 && self.type_params == other.type_params
600 && self.params == other.params
601 && self.when_clause == other.when_clause
602 && self.return_type == other.return_type
603 && self.body == other.body
604 && self.is_async == other.is_async
605 }
606}
607
608#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
609pub enum TypeName {
610 Simple(TypePath),
612 Generic {
614 name: TypePath,
615 type_args: Vec<TypeAnnotation>,
616 },
617}
618
619#[derive(Debug, Clone, Serialize, Deserialize)]
630pub struct StructTypeDef {
631 pub name: String,
632 #[serde(default)]
633 pub doc_comment: Option<DocComment>,
634 pub type_params: Option<Vec<TypeParam>>,
635 pub fields: Vec<StructField>,
636 #[serde(default)]
638 pub methods: Vec<MethodDef>,
639 pub annotations: Vec<Annotation>,
641 #[serde(default)]
643 pub native_layout: Option<NativeLayoutBinding>,
644}
645
646#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
648pub struct NativeLayoutBinding {
649 pub abi: String,
651}
652
653#[derive(Debug, Clone, Serialize, Deserialize)]
667pub struct StructField {
668 pub annotations: Vec<Annotation>,
669 pub is_comptime: bool,
670 pub name: String,
671 #[serde(default)]
672 pub span: Span,
673 #[serde(default)]
674 pub doc_comment: Option<DocComment>,
675 pub type_annotation: TypeAnnotation,
676 pub default_value: Option<super::expressions::Expr>,
677}
678
679impl PartialEq for StructField {
680 fn eq(&self, other: &Self) -> bool {
681 self.annotations == other.annotations
682 && self.is_comptime == other.is_comptime
683 && self.name == other.name
684 && self.doc_comment == other.doc_comment
685 && self.type_annotation == other.type_annotation
686 && self.default_value == other.default_value
687 }
688}