1use rustc_hash::FxHashMap as HashMap;
2
3use ecow::EcoString;
4
5use crate::ast::{
6 Annotation, EnumVariant, Generic, Span, StructFieldDefinition, StructKind, ValueEnumVariant,
7};
8use crate::types::Type;
9
10#[derive(Debug, Clone)]
11pub enum Definition {
12 TypeAlias {
13 visibility: Visibility,
14 name: EcoString,
15 name_span: Span,
16 generics: Vec<Generic>,
17 annotation: Annotation,
18 ty: Type,
19 methods: MethodSignatures,
20 doc: Option<String>,
21 },
22 Enum {
23 visibility: Visibility,
24 ty: Type,
25 name: EcoString,
26 name_span: Span,
27 generics: Vec<Generic>,
28 variants: Vec<EnumVariant>,
29 methods: MethodSignatures,
30 doc: Option<String>,
31 },
32 ValueEnum {
33 visibility: Visibility,
34 ty: Type,
35 name: EcoString,
36 name_span: Span,
37 variants: Vec<ValueEnumVariant>,
38 underlying_ty: Option<Type>,
39 methods: MethodSignatures,
40 doc: Option<String>,
41 },
42 Struct {
43 visibility: Visibility,
44 ty: Type,
45 name: EcoString,
46 name_span: Span,
47 generics: Vec<Generic>,
48 fields: Vec<StructFieldDefinition>,
49 kind: StructKind,
50 methods: MethodSignatures,
51 constructor: Option<Type>,
52 doc: Option<String>,
53 },
54 Interface {
55 visibility: Visibility,
56 ty: Type,
57 name_span: Span,
58 definition: Interface,
59 doc: Option<String>,
60 },
61 Value {
62 visibility: Visibility,
63 ty: Type,
64 name_span: Option<Span>,
65 allowed_lints: Vec<String>,
66 go_hints: Vec<String>,
67 go_name: Option<String>,
68 doc: Option<String>,
69 },
70}
71
72impl Definition {
73 pub fn ty(&self) -> &Type {
74 match self {
75 Definition::TypeAlias { ty, .. } => ty,
76 Definition::Enum { ty, .. } => ty,
77 Definition::ValueEnum { ty, .. } => ty,
78 Definition::Struct { ty, .. } => ty,
79 Definition::Interface { ty, .. } => ty,
80 Definition::Value { ty, .. } => ty,
81 }
82 }
83
84 pub fn visibility(&self) -> &Visibility {
85 match self {
86 Definition::TypeAlias { visibility, .. } => visibility,
87 Definition::Enum { visibility, .. } => visibility,
88 Definition::ValueEnum { visibility, .. } => visibility,
89 Definition::Struct { visibility, .. } => visibility,
90 Definition::Interface { visibility, .. } => visibility,
91 Definition::Value { visibility, .. } => visibility,
92 }
93 }
94
95 pub fn is_newtype(&self) -> bool {
100 matches!(
101 self,
102 Definition::Struct {
103 kind: StructKind::Tuple,
104 fields,
105 generics,
106 ..
107 } if fields.len() == 1 && generics.is_empty()
108 )
109 }
110
111 pub fn allowed_lints(&self) -> &[String] {
112 match self {
113 Definition::Value { allowed_lints, .. } => allowed_lints,
114 _ => &[],
115 }
116 }
117
118 pub fn go_hints(&self) -> &[String] {
119 match self {
120 Definition::Value { go_hints, .. } => go_hints,
121 _ => &[],
122 }
123 }
124
125 pub fn go_name(&self) -> Option<&str> {
126 match self {
127 Definition::Value { go_name, .. } => go_name.as_deref(),
128 _ => None,
129 }
130 }
131
132 pub fn methods_mut(&mut self) -> Option<&mut MethodSignatures> {
133 match self {
134 Definition::Struct { methods, .. } => Some(methods),
135 Definition::TypeAlias { methods, .. } => Some(methods),
136 Definition::Enum { methods, .. } => Some(methods),
137 Definition::ValueEnum { methods, .. } => Some(methods),
138 _ => None,
139 }
140 }
141
142 pub fn is_type_definition(&self) -> bool {
143 matches!(
144 self,
145 Definition::Struct { .. }
146 | Definition::Enum { .. }
147 | Definition::ValueEnum { .. }
148 | Definition::TypeAlias { .. }
149 )
150 }
151
152 pub fn name_span(&self) -> Option<Span> {
153 match self {
154 Definition::TypeAlias { name_span, .. } => Some(*name_span),
155 Definition::Enum { name_span, .. } => Some(*name_span),
156 Definition::ValueEnum { name_span, .. } => Some(*name_span),
157 Definition::Struct { name_span, .. } => Some(*name_span),
158 Definition::Interface { name_span, .. } => Some(*name_span),
159 Definition::Value { name_span, .. } => *name_span,
160 }
161 }
162
163 pub fn doc(&self) -> Option<&String> {
164 match self {
165 Definition::TypeAlias { doc, .. }
166 | Definition::Enum { doc, .. }
167 | Definition::ValueEnum { doc, .. }
168 | Definition::Struct { doc, .. }
169 | Definition::Interface { doc, .. }
170 | Definition::Value { doc, .. } => doc.as_ref(),
171 }
172 }
173}
174
175pub type MethodSignatures = HashMap<EcoString, Type>;
176
177#[derive(Debug, Clone, PartialEq)]
178pub enum Visibility {
179 Public,
180 Private,
181 Local,
182}
183
184impl Visibility {
185 pub fn is_public(&self) -> bool {
186 matches!(self, Visibility::Public)
187 }
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub struct Interface {
192 pub name: EcoString,
193 pub generics: Vec<Generic>,
194 pub parents: Vec<Type>,
195 pub methods: HashMap<EcoString, Type>,
196}