1use rustc_hash::FxHashMap as HashMap;
2
3use ecow::EcoString;
4use serde::{Deserialize, Serialize};
5use syntax::ast::{
6 Annotation, AttributeArg, Generic, Span, StructKind, Visibility as FieldVisibility,
7};
8use syntax::program::{Definition, Interface, MethodSignatures, Visibility};
9use syntax::types::{Bound, Type};
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15pub struct CachedSpan {
16 pub file_index: u32,
17 pub byte_offset: u32,
18 pub byte_length: u32,
19}
20
21impl CachedSpan {
22 pub fn from_span(span: &Span, file_id_to_index: &HashMap<u32, u32>) -> Self {
23 Self {
24 file_index: *file_id_to_index.get(&span.file_id).unwrap_or(&0),
25 byte_offset: span.byte_offset,
26 byte_length: span.byte_length,
27 }
28 }
29
30 pub fn to_span(&self, file_ids: &[u32]) -> Span {
31 Span {
32 file_id: file_ids.get(self.file_index as usize).copied().unwrap_or(0),
33 byte_offset: self.byte_offset,
34 byte_length: self.byte_length,
35 }
36 }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
42pub enum CachedType {
43 Constructor {
44 id: String,
45 params: Vec<CachedType>,
46 underlying_ty: Option<Box<CachedType>>,
47 },
48 Function {
49 params: Vec<CachedType>,
50 param_mutability: Vec<bool>,
51 bounds: Vec<CachedBound>,
52 return_type: Box<CachedType>,
53 },
54 Forall {
55 vars: Vec<String>,
56 body: Box<CachedType>,
57 },
58 Parameter(String),
59 Tuple(Vec<CachedType>),
60 Never,
61}
62
63impl CachedType {
64 pub fn from_type_with_vars(ty: &Type, var_names: &mut HashMap<i32, String>) -> Self {
68 match ty {
69 Type::Variable(var) => {
70 use syntax::types::TypeVariableState;
71 match &*var.borrow() {
72 TypeVariableState::Link(linked) => {
73 CachedType::from_type_with_vars(linked, var_names)
74 }
75 TypeVariableState::Unbound { id, hint } => {
76 if let Some(name) = var_names.get(id) {
77 return CachedType::Parameter(name.clone());
78 }
79 let name = match hint {
80 Some(h) => format!("{}_{}", h, id),
81 None => format!("T{}", var_names.len()),
82 };
83 var_names.insert(*id, name.clone());
84 CachedType::Parameter(name)
85 }
86 }
87 }
88 Type::Constructor {
89 id,
90 params,
91 underlying_ty,
92 } => CachedType::Constructor {
93 id: id.to_string(),
94 params: params
95 .iter()
96 .map(|p| CachedType::from_type_with_vars(p, var_names))
97 .collect(),
98 underlying_ty: underlying_ty
99 .as_ref()
100 .map(|u| Box::new(CachedType::from_type_with_vars(u, var_names))),
101 },
102 Type::Function {
103 params,
104 param_mutability,
105 bounds,
106 return_type,
107 } => CachedType::Function {
108 params: params
109 .iter()
110 .map(|p| CachedType::from_type_with_vars(p, var_names))
111 .collect(),
112 param_mutability: param_mutability.clone(),
113 bounds: bounds
114 .iter()
115 .map(|b| CachedBound::from_bound_with_vars(b, var_names))
116 .collect(),
117 return_type: Box::new(CachedType::from_type_with_vars(return_type, var_names)),
118 },
119 Type::Forall { vars, body } => CachedType::Forall {
120 vars: vars.iter().map(|v| v.to_string()).collect(),
121 body: Box::new(CachedType::from_type_with_vars(body, var_names)),
122 },
123 Type::Parameter(name) => CachedType::Parameter(name.to_string()),
124 Type::Tuple(elements) => CachedType::Tuple(
125 elements
126 .iter()
127 .map(|e| CachedType::from_type_with_vars(e, var_names))
128 .collect(),
129 ),
130 Type::Never | Type::Error => CachedType::Never,
131 }
132 }
133
134 pub fn from_type(ty: &Type) -> Self {
135 let mut var_names = HashMap::default();
136 Self::from_type_with_vars(ty, &mut var_names)
137 }
138
139 pub fn to_type(&self) -> Type {
140 match self {
141 CachedType::Constructor {
142 id,
143 params,
144 underlying_ty,
145 } => Type::Constructor {
146 id: EcoString::from(id.as_str()),
147 params: params.iter().map(|p| p.to_type()).collect(),
148 underlying_ty: underlying_ty.as_ref().map(|u| Box::new(u.to_type())),
149 },
150 CachedType::Function {
151 params,
152 param_mutability,
153 bounds,
154 return_type,
155 } => Type::Function {
156 params: params.iter().map(|p| p.to_type()).collect(),
157 param_mutability: param_mutability.clone(),
158 bounds: bounds.iter().map(|b| b.to_bound()).collect(),
159 return_type: Box::new(return_type.to_type()),
160 },
161 CachedType::Forall { vars, body } => Type::Forall {
162 vars: vars.iter().map(|v| EcoString::from(v.as_str())).collect(),
163 body: Box::new(body.to_type()),
164 },
165 CachedType::Parameter(name) => Type::Parameter(EcoString::from(name.as_str())),
166 CachedType::Tuple(elements) => {
167 Type::Tuple(elements.iter().map(|e| e.to_type()).collect())
168 }
169 CachedType::Never => Type::Never,
170 }
171 }
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
175pub struct CachedBound {
176 pub param_name: String,
177 pub generic: CachedType,
178 pub ty: CachedType,
179}
180
181impl CachedBound {
182 pub fn from_bound_with_vars(bound: &Bound, var_names: &mut HashMap<i32, String>) -> Self {
183 Self {
184 param_name: bound.param_name.to_string(),
185 generic: CachedType::from_type_with_vars(&bound.generic, var_names),
186 ty: CachedType::from_type_with_vars(&bound.ty, var_names),
187 }
188 }
189
190 pub fn to_bound(&self) -> Bound {
191 Bound {
192 param_name: EcoString::from(self.param_name.as_str()),
193 generic: self.generic.to_type(),
194 ty: self.ty.to_type(),
195 }
196 }
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
200pub struct CachedGeneric {
201 pub name: String,
202 pub bounds: Vec<Annotation>,
203 pub span: CachedSpan,
204}
205
206impl CachedGeneric {
207 pub fn from_generic(generic: &Generic, file_id_to_index: &HashMap<u32, u32>) -> Self {
208 Self {
209 name: generic.name.to_string(),
210 bounds: generic.bounds.clone(),
211 span: CachedSpan::from_span(&generic.span, file_id_to_index),
212 }
213 }
214
215 pub fn to_generic(&self, file_ids: &[u32]) -> Generic {
216 Generic {
217 name: EcoString::from(self.name.as_str()),
218 bounds: self.bounds.clone(),
219 span: self.span.to_span(file_ids),
220 }
221 }
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
225pub enum CachedLiteral {
226 Integer { value: u64, text: Option<String> },
227 Float { value: f64, text: Option<String> },
228 Boolean(bool),
229 String(String),
230 Char(String),
231}
232
233impl CachedLiteral {
234 pub fn from_literal(lit: &syntax::ast::Literal) -> Self {
235 use syntax::ast::Literal;
236 match lit {
237 Literal::Integer { value, text } => CachedLiteral::Integer {
238 value: *value,
239 text: text.clone(),
240 },
241 Literal::Float { value, text } => CachedLiteral::Float {
242 value: *value,
243 text: text.clone(),
244 },
245 Literal::Boolean(v) => CachedLiteral::Boolean(*v),
246 Literal::String(v) => CachedLiteral::String(v.clone()),
247 Literal::Char(v) => CachedLiteral::Char(v.clone()),
248 Literal::Imaginary(_) | Literal::FormatString(_) | Literal::Slice(_) => {
250 CachedLiteral::Integer {
251 value: 0,
252 text: None,
253 }
254 }
255 }
256 }
257
258 pub fn to_literal(&self) -> syntax::ast::Literal {
259 use syntax::ast::Literal;
260 match self {
261 CachedLiteral::Integer { value, text } => Literal::Integer {
262 value: *value,
263 text: text.clone(),
264 },
265 CachedLiteral::Float { value, text } => Literal::Float {
266 value: *value,
267 text: text.clone(),
268 },
269 CachedLiteral::Boolean(v) => Literal::Boolean(*v),
270 CachedLiteral::String(v) => Literal::String(v.clone()),
271 CachedLiteral::Char(v) => Literal::Char(v.clone()),
272 }
273 }
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
277pub struct CachedAttribute {
278 pub name: String,
279 pub args: Vec<AttributeArg>,
280}
281
282impl CachedAttribute {
283 pub fn from_attribute(attribute: &syntax::ast::Attribute) -> Self {
284 Self {
285 name: attribute.name.clone(),
286 args: attribute.args.clone(),
287 }
288 }
289
290 pub fn to_attribute(&self) -> syntax::ast::Attribute {
291 syntax::ast::Attribute {
292 name: self.name.clone(),
293 args: self.args.clone(),
294 span: Span::dummy(),
295 }
296 }
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
300pub struct CachedStructField {
301 pub name: String,
302 pub name_span: CachedSpan,
303 pub ty: CachedType,
304 pub visibility: FieldVisibility,
305 pub attributes: Vec<CachedAttribute>,
306 pub doc: Option<String>,
307}
308
309impl CachedStructField {
310 pub fn from_field(
311 field: &syntax::ast::StructFieldDefinition,
312 file_id_to_index: &HashMap<u32, u32>,
313 ) -> Self {
314 Self {
315 name: field.name.to_string(),
316 name_span: CachedSpan::from_span(&field.name_span, file_id_to_index),
317 ty: CachedType::from_type(&field.ty),
318 visibility: field.visibility,
319 attributes: field
320 .attributes
321 .iter()
322 .map(CachedAttribute::from_attribute)
323 .collect(),
324 doc: field.doc.clone(),
325 }
326 }
327
328 pub fn to_field(&self, file_ids: &[u32]) -> syntax::ast::StructFieldDefinition {
329 syntax::ast::StructFieldDefinition {
330 doc: self.doc.clone(),
331 name: self.name.clone().into(),
332 name_span: self.name_span.to_span(file_ids),
333 ty: self.ty.to_type(),
334 visibility: self.visibility,
335 attributes: self.attributes.iter().map(|a| a.to_attribute()).collect(),
336 annotation: Annotation::Unknown,
337 }
338 }
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
342pub struct CachedEnumVariant {
343 pub name: String,
344 pub name_span: CachedSpan,
345 pub fields: CachedVariantFields,
346 pub doc: Option<String>,
347}
348
349#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
350pub enum CachedVariantFields {
351 Unit,
352 Tuple(Vec<CachedEnumField>),
353 Struct(Vec<CachedEnumField>),
354}
355
356impl CachedVariantFields {
357 pub fn from_variant_fields(fields: &syntax::ast::VariantFields) -> Self {
358 match fields {
359 syntax::ast::VariantFields::Unit => CachedVariantFields::Unit,
360 syntax::ast::VariantFields::Tuple(fs) => {
361 CachedVariantFields::Tuple(fs.iter().map(CachedEnumField::from_field).collect())
362 }
363 syntax::ast::VariantFields::Struct(fs) => {
364 CachedVariantFields::Struct(fs.iter().map(CachedEnumField::from_field).collect())
365 }
366 }
367 }
368
369 pub fn to_variant_fields(&self) -> syntax::ast::VariantFields {
370 match self {
371 CachedVariantFields::Unit => syntax::ast::VariantFields::Unit,
372 CachedVariantFields::Tuple(fs) => {
373 syntax::ast::VariantFields::Tuple(fs.iter().map(|f| f.to_field()).collect())
374 }
375 CachedVariantFields::Struct(fs) => {
376 syntax::ast::VariantFields::Struct(fs.iter().map(|f| f.to_field()).collect())
377 }
378 }
379 }
380}
381
382impl CachedEnumVariant {
383 pub fn from_variant(
384 variant: &syntax::ast::EnumVariant,
385 file_id_to_index: &HashMap<u32, u32>,
386 ) -> Self {
387 Self {
388 name: variant.name.to_string(),
389 name_span: CachedSpan::from_span(&variant.name_span, file_id_to_index),
390 fields: CachedVariantFields::from_variant_fields(&variant.fields),
391 doc: variant.doc.clone(),
392 }
393 }
394
395 pub fn to_variant(&self, file_ids: &[u32]) -> syntax::ast::EnumVariant {
396 syntax::ast::EnumVariant {
397 doc: self.doc.clone(),
398 name: self.name.clone().into(),
399 name_span: self.name_span.to_span(file_ids),
400 fields: self.fields.to_variant_fields(),
401 }
402 }
403}
404
405#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
406pub struct CachedEnumField {
407 pub name: String,
408 pub ty: CachedType,
409}
410
411impl CachedEnumField {
412 pub fn from_field(field: &syntax::ast::EnumFieldDefinition) -> Self {
413 Self {
414 name: field.name.to_string(),
415 ty: CachedType::from_type(&field.ty),
416 }
417 }
418
419 pub fn to_field(&self) -> syntax::ast::EnumFieldDefinition {
420 syntax::ast::EnumFieldDefinition {
421 name: self.name.clone().into(),
422 name_span: Span::dummy(),
423 ty: self.ty.to_type(),
424 annotation: Annotation::Unknown,
425 }
426 }
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
430pub struct CachedValueEnumVariant {
431 pub name: String,
432 pub name_span: CachedSpan,
433 pub value: CachedLiteral,
434 pub doc: Option<String>,
435}
436
437impl CachedValueEnumVariant {
438 pub fn from_variant(
439 variant: &syntax::ast::ValueEnumVariant,
440 file_id_to_index: &HashMap<u32, u32>,
441 ) -> Self {
442 Self {
443 name: variant.name.to_string(),
444 name_span: CachedSpan::from_span(&variant.name_span, file_id_to_index),
445 value: CachedLiteral::from_literal(&variant.value),
446 doc: variant.doc.clone(),
447 }
448 }
449
450 pub fn to_variant(&self, file_ids: &[u32]) -> syntax::ast::ValueEnumVariant {
451 syntax::ast::ValueEnumVariant {
452 doc: self.doc.clone(),
453 name: self.name.clone().into(),
454 name_span: self.name_span.to_span(file_ids),
455 value: self.value.to_literal(),
456 value_span: Span::dummy(),
457 }
458 }
459}
460
461#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
462pub struct CachedInterface {
463 pub name: String,
464 pub generics: Vec<CachedGeneric>,
465 pub parents: Vec<CachedType>,
466 pub methods: HashMap<String, CachedType>,
467}
468
469impl CachedInterface {
470 pub fn from_interface(iface: &Interface, file_id_to_index: &HashMap<u32, u32>) -> Self {
471 Self {
472 name: iface.name.to_string(),
473 generics: iface
474 .generics
475 .iter()
476 .map(|g| CachedGeneric::from_generic(g, file_id_to_index))
477 .collect(),
478 parents: iface.parents.iter().map(CachedType::from_type).collect(),
479 methods: iface
480 .methods
481 .iter()
482 .map(|(k, v)| (k.to_string(), CachedType::from_type(v)))
483 .collect(),
484 }
485 }
486
487 pub fn to_interface(&self, file_ids: &[u32]) -> Interface {
488 Interface {
489 name: EcoString::from(self.name.as_str()),
490 generics: self
491 .generics
492 .iter()
493 .map(|g| g.to_generic(file_ids))
494 .collect(),
495 parents: self.parents.iter().map(|p| p.to_type()).collect(),
496 methods: self
497 .methods
498 .iter()
499 .map(|(k, v)| (EcoString::from(k.as_str()), v.to_type()))
500 .collect(),
501 }
502 }
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
507pub enum CachedDefinition {
508 TypeAlias {
509 name: String,
510 name_span: CachedSpan,
511 generics: Vec<CachedGeneric>,
512 ty: CachedType,
513 methods: HashMap<String, CachedType>,
514 is_opaque: bool,
515 doc: Option<String>,
516 },
517 Enum {
518 name: String,
519 name_span: CachedSpan,
520 ty: CachedType,
521 generics: Vec<CachedGeneric>,
522 variants: Vec<CachedEnumVariant>,
523 methods: HashMap<String, CachedType>,
524 doc: Option<String>,
525 },
526 ValueEnum {
527 name: String,
528 name_span: CachedSpan,
529 ty: CachedType,
530 variants: Vec<CachedValueEnumVariant>,
531 underlying_ty: Option<CachedType>,
532 methods: HashMap<String, CachedType>,
533 doc: Option<String>,
534 },
535 Struct {
536 name: String,
537 name_span: CachedSpan,
538 ty: CachedType,
539 generics: Vec<CachedGeneric>,
540 fields: Vec<CachedStructField>,
541 kind: StructKind,
542 methods: HashMap<String, CachedType>,
543 constructor: Option<CachedType>,
544 doc: Option<String>,
545 },
546 Interface {
547 name_span: CachedSpan,
548 ty: CachedType,
549 definition: CachedInterface,
550 doc: Option<String>,
551 },
552 Value {
553 name_span: Option<CachedSpan>,
554 ty: CachedType,
555 allowed_lints: Vec<String>,
556 go_hints: Vec<String>,
557 go_name: Option<String>,
558 doc: Option<String>,
559 },
560}
561
562impl CachedDefinition {
563 pub fn from_definition(definition: &Definition, file_id_to_index: &HashMap<u32, u32>) -> Self {
566 match definition {
567 Definition::TypeAlias {
568 name,
569 name_span,
570 generics,
571 ty,
572 methods,
573 annotation,
574 doc,
575 ..
576 } => CachedDefinition::TypeAlias {
577 name: name.to_string(),
578 name_span: CachedSpan::from_span(name_span, file_id_to_index),
579 generics: generics
580 .iter()
581 .map(|g| CachedGeneric::from_generic(g, file_id_to_index))
582 .collect(),
583 ty: CachedType::from_type(ty),
584 methods: Self::convert_methods(methods),
585 is_opaque: annotation.is_opaque(),
586 doc: doc.clone(),
587 },
588 Definition::Enum {
589 name,
590 name_span,
591 ty,
592 generics,
593 variants,
594 methods,
595 doc,
596 ..
597 } => CachedDefinition::Enum {
598 name: name.to_string(),
599 name_span: CachedSpan::from_span(name_span, file_id_to_index),
600 ty: CachedType::from_type(ty),
601 generics: generics
602 .iter()
603 .map(|g| CachedGeneric::from_generic(g, file_id_to_index))
604 .collect(),
605 variants: variants
606 .iter()
607 .map(|v| CachedEnumVariant::from_variant(v, file_id_to_index))
608 .collect(),
609 methods: Self::convert_methods(methods),
610 doc: doc.clone(),
611 },
612 Definition::ValueEnum {
613 name,
614 name_span,
615 ty,
616 variants,
617 underlying_ty,
618 methods,
619 doc,
620 ..
621 } => CachedDefinition::ValueEnum {
622 name: name.to_string(),
623 name_span: CachedSpan::from_span(name_span, file_id_to_index),
624 ty: CachedType::from_type(ty),
625 variants: variants
626 .iter()
627 .map(|v| CachedValueEnumVariant::from_variant(v, file_id_to_index))
628 .collect(),
629 underlying_ty: underlying_ty.as_ref().map(CachedType::from_type),
630 methods: Self::convert_methods(methods),
631 doc: doc.clone(),
632 },
633 Definition::Struct {
634 name,
635 name_span,
636 ty,
637 generics,
638 fields,
639 kind,
640 methods,
641 constructor,
642 doc,
643 ..
644 } => CachedDefinition::Struct {
645 name: name.to_string(),
646 name_span: CachedSpan::from_span(name_span, file_id_to_index),
647 ty: CachedType::from_type(ty),
648 generics: generics
649 .iter()
650 .map(|g| CachedGeneric::from_generic(g, file_id_to_index))
651 .collect(),
652 fields: fields
653 .iter()
654 .map(|f| CachedStructField::from_field(f, file_id_to_index))
655 .collect(),
656 kind: *kind,
657 methods: Self::convert_methods(methods),
658 constructor: constructor.as_ref().map(CachedType::from_type),
659 doc: doc.clone(),
660 },
661 Definition::Interface {
662 ty,
663 name_span,
664 definition,
665 doc,
666 ..
667 } => CachedDefinition::Interface {
668 name_span: CachedSpan::from_span(name_span, file_id_to_index),
669 ty: CachedType::from_type(ty),
670 definition: CachedInterface::from_interface(definition, file_id_to_index),
671 doc: doc.clone(),
672 },
673 Definition::Value {
674 ty,
675 name_span,
676 allowed_lints,
677 go_hints,
678 go_name,
679 doc,
680 ..
681 } => CachedDefinition::Value {
682 name_span: name_span.map(|s| CachedSpan::from_span(&s, file_id_to_index)),
683 ty: CachedType::from_type(ty),
684 allowed_lints: allowed_lints.clone(),
685 go_hints: go_hints.clone(),
686 go_name: go_name.clone(),
687 doc: doc.clone(),
688 },
689 }
690 }
691
692 fn convert_methods(methods: &MethodSignatures) -> HashMap<String, CachedType> {
693 methods
694 .iter()
695 .map(|(k, v)| (k.to_string(), CachedType::from_type(v)))
696 .collect()
697 }
698
699 fn restore_methods(methods: &HashMap<String, CachedType>) -> MethodSignatures {
700 methods
701 .iter()
702 .map(|(k, v)| (EcoString::from(k.as_str()), v.to_type()))
703 .collect()
704 }
705
706 pub fn to_definition(&self, file_ids: &[u32]) -> Definition {
707 match self {
708 CachedDefinition::TypeAlias {
709 name,
710 name_span,
711 generics,
712 ty,
713 methods,
714 is_opaque,
715 doc,
716 } => Definition::TypeAlias {
717 visibility: Visibility::Public,
718 name: EcoString::from(name.as_str()),
719 name_span: name_span.to_span(file_ids),
720 generics: generics.iter().map(|g| g.to_generic(file_ids)).collect(),
721 annotation: if *is_opaque {
722 Annotation::Opaque {
723 span: Span::dummy(),
724 }
725 } else {
726 Annotation::Unknown
727 },
728 ty: ty.to_type(),
729 methods: Self::restore_methods(methods),
730 doc: doc.clone(),
731 },
732 CachedDefinition::Enum {
733 name,
734 name_span,
735 ty,
736 generics,
737 variants,
738 methods,
739 doc,
740 } => Definition::Enum {
741 visibility: Visibility::Public,
742 name: EcoString::from(name.as_str()),
743 name_span: name_span.to_span(file_ids),
744 ty: ty.to_type(),
745 generics: generics.iter().map(|g| g.to_generic(file_ids)).collect(),
746 variants: variants.iter().map(|v| v.to_variant(file_ids)).collect(),
747 methods: Self::restore_methods(methods),
748 doc: doc.clone(),
749 },
750 CachedDefinition::ValueEnum {
751 name,
752 name_span,
753 ty,
754 variants,
755 underlying_ty,
756 methods,
757 doc,
758 } => Definition::ValueEnum {
759 visibility: Visibility::Public,
760 name: EcoString::from(name.as_str()),
761 name_span: name_span.to_span(file_ids),
762 ty: ty.to_type(),
763 variants: variants.iter().map(|v| v.to_variant(file_ids)).collect(),
764 underlying_ty: underlying_ty.as_ref().map(|u| u.to_type()),
765 methods: Self::restore_methods(methods),
766 doc: doc.clone(),
767 },
768 CachedDefinition::Struct {
769 name,
770 name_span,
771 ty,
772 generics,
773 fields,
774 kind,
775 methods,
776 constructor,
777 doc,
778 } => Definition::Struct {
779 visibility: Visibility::Public,
780 name: EcoString::from(name.as_str()),
781 name_span: name_span.to_span(file_ids),
782 ty: ty.to_type(),
783 generics: generics.iter().map(|g| g.to_generic(file_ids)).collect(),
784 fields: fields.iter().map(|f| f.to_field(file_ids)).collect(),
785 kind: *kind,
786 methods: Self::restore_methods(methods),
787 constructor: constructor.as_ref().map(|c| c.to_type()),
788 doc: doc.clone(),
789 },
790 CachedDefinition::Interface {
791 name_span,
792 ty,
793 definition,
794 doc,
795 } => Definition::Interface {
796 visibility: Visibility::Public,
797 ty: ty.to_type(),
798 name_span: name_span.to_span(file_ids),
799 definition: definition.to_interface(file_ids),
800 doc: doc.clone(),
801 },
802 CachedDefinition::Value {
803 name_span,
804 ty,
805 allowed_lints,
806 go_hints,
807 go_name,
808 doc,
809 } => Definition::Value {
810 visibility: Visibility::Public,
811 ty: ty.to_type(),
812 name_span: name_span.as_ref().map(|s| s.to_span(file_ids)),
813 allowed_lints: allowed_lints.clone(),
814 go_hints: go_hints.clone(),
815 go_name: go_name.clone(),
816 doc: doc.clone(),
817 },
818 }
819 }
820}