1use crate::rib_source_span::SourceSpan;
16use crate::type_inference::type_hint::{GetTypeHint, TypeHint};
17use crate::{InferredType, Path, PathElem};
18use golem_wasm_ast::analysis::AnalysedType;
19
20#[derive(Debug, Clone)]
21pub struct AmbiguousTypeError {
22 pub ambiguous_expr_source_span: SourceSpan,
23 pub ambiguous_types: Vec<String>,
24 pub additional_error_details: Vec<String>,
25}
26
27impl AmbiguousTypeError {
28 pub fn new(
29 inferred_expr: &InferredType,
30 source_span: &SourceSpan,
31 expected: &TypeHint,
32 ) -> AmbiguousTypeError {
33 let actual_kind = inferred_expr.get_type_hint();
34 match actual_kind {
35 TypeHint::Ambiguous { possibilities } => {
36 let possibilities = possibilities
37 .into_iter()
38 .map(|x| x.to_string())
39 .collect::<Vec<_>>();
40
41 AmbiguousTypeError {
42 ambiguous_expr_source_span: source_span.clone(),
43 ambiguous_types: possibilities,
44 additional_error_details: vec![],
45 }
46 }
47 _ => AmbiguousTypeError {
48 ambiguous_expr_source_span: source_span.clone(),
49 ambiguous_types: vec![expected.to_string(), inferred_expr.printable()],
50 additional_error_details: vec![],
51 },
52 }
53 }
54
55 pub fn with_additional_error_detail(&self, detail: &str) -> AmbiguousTypeError {
56 let mut error = self.clone();
57 error.additional_error_details.push(detail.to_string());
58 error
59 }
60}
61
62pub enum InvalidPatternMatchError {
63 ConstructorMismatch {
64 match_expr_source_span: SourceSpan,
65 constructor_name: String,
66 },
67 ArgSizeMismatch {
68 match_expr_source_span: SourceSpan,
69 constructor_name: String,
70 expected_arg_size: usize,
71 actual_arg_size: usize,
72 },
73}
74
75impl InvalidPatternMatchError {
76 pub fn constructor_type_mismatch(
77 match_expr_source_span: SourceSpan,
78 constructor_name: &str,
79 ) -> InvalidPatternMatchError {
80 InvalidPatternMatchError::ConstructorMismatch {
81 match_expr_source_span,
82 constructor_name: constructor_name.to_string(),
83 }
84 }
85
86 pub fn arg_size_mismatch(
87 match_expr_source_span: SourceSpan,
88 constructor_name: &str,
89 expected_arg_size: usize,
90 actual_arg_size: usize,
91 ) -> InvalidPatternMatchError {
92 InvalidPatternMatchError::ArgSizeMismatch {
93 match_expr_source_span,
94 expected_arg_size,
95 actual_arg_size,
96 constructor_name: constructor_name.to_string(),
97 }
98 }
99}
100
101#[derive(Debug, Clone)]
102pub struct UnificationError {}
103
104#[derive(Clone, Debug)]
105pub struct TypeMismatchError {
106 pub source_span: SourceSpan,
107 pub expected_type: ExpectedType,
108 pub actual_type: ActualType,
109 pub field_path: Path,
110 pub additional_error_detail: Vec<String>,
111}
112
113#[derive(Clone, Debug)]
114pub enum ExpectedType {
115 AnalysedType(AnalysedType),
116 Hint(TypeHint),
119 InferredType(InferredType),
120}
121
122#[derive(Clone, Debug)]
123pub enum ActualType {
124 Inferred(InferredType),
125 Hint(TypeHint),
127}
128
129impl TypeMismatchError {
130 pub fn updated_expected_type(&self, expected_type: &AnalysedType) -> TypeMismatchError {
131 let mut mismatch_error: TypeMismatchError = self.clone();
132 mismatch_error.expected_type = ExpectedType::AnalysedType(expected_type.clone());
133 mismatch_error
134 }
135
136 pub fn at_field(&self, field_name: String) -> TypeMismatchError {
137 let mut mismatch_error: TypeMismatchError = self.clone();
138 mismatch_error
139 .field_path
140 .push_front(PathElem::Field(field_name));
141 mismatch_error
142 }
143}
144
145pub enum TypeUnificationError {
147 TypeMismatchError { error: TypeMismatchError },
148 UnresolvedTypesError { error: UnResolvedTypesError },
149}
150
151impl TypeUnificationError {
152 pub fn unresolved_types_error(
153 source_span: SourceSpan,
154 additional_messages: Vec<String>,
155 ) -> TypeUnificationError {
156 TypeUnificationError::UnresolvedTypesError {
157 error: UnResolvedTypesError {
158 source_span,
159 additional_messages,
160 help_messages: vec![],
161 path: Path::default(),
162 },
163 }
164 }
165 pub fn type_mismatch_error(
166 source_span: SourceSpan,
167 expected_type: InferredType,
168 actual_type: InferredType,
169 additional_error_detail: Vec<String>,
170 ) -> TypeUnificationError {
171 TypeUnificationError::TypeMismatchError {
172 error: TypeMismatchError {
173 source_span,
174 expected_type: ExpectedType::InferredType(expected_type),
175 actual_type: ActualType::Inferred(actual_type),
176 field_path: Path::default(),
177 additional_error_detail,
178 },
179 }
180 }
181}
182
183#[derive(Debug, Clone)]
184pub struct UnResolvedTypesError {
185 pub source_span: SourceSpan,
186 pub help_messages: Vec<String>,
187 pub path: Path,
188 pub additional_messages: Vec<String>,
189}
190
191impl UnResolvedTypesError {
192 pub fn from(source_span: SourceSpan) -> Self {
193 let unresolved_types = UnResolvedTypesError {
194 source_span,
195 help_messages: Vec::new(),
196 path: Path::default(),
197 additional_messages: Vec::new(),
198 };
199
200 unresolved_types.with_default_help_messages()
201 }
202
203 pub fn with_default_help_messages(&self) -> Self {
204 self.with_help_message(
205 "try specifying the expected type explicitly",
206 ).with_help_message(
207 "if the issue persists, please review the script for potential type inconsistencies"
208 )
209 }
210
211 pub fn with_additional_error_detail(&self, message: impl AsRef<str>) -> UnResolvedTypesError {
212 let mut unresolved_error: UnResolvedTypesError = self.clone();
213 unresolved_error
214 .additional_messages
215 .push(message.as_ref().to_string());
216 unresolved_error
217 }
218
219 pub fn with_help_message(&self, message: impl AsRef<str>) -> UnResolvedTypesError {
220 let mut unresolved_error: UnResolvedTypesError = self.clone();
221 unresolved_error
222 .help_messages
223 .push(message.as_ref().to_string());
224
225 unresolved_error
226 }
227
228 pub fn at_field(&self, field_name: String) -> UnResolvedTypesError {
229 let mut unresolved_error: UnResolvedTypesError = self.clone();
230 unresolved_error
231 .path
232 .push_front(PathElem::Field(field_name));
233 unresolved_error
234 }
235
236 pub fn at_index(&self, index: usize) -> UnResolvedTypesError {
237 let mut unresolved_error: UnResolvedTypesError = self.clone();
238 unresolved_error.path.push_front(PathElem::Index(index));
239 unresolved_error
240 }
241}
242
243#[derive(Debug, Clone)]
244pub enum FunctionCallError {
245 InvalidFunctionCall {
246 function_name: String,
247 source_span: SourceSpan,
248 message: String,
249 },
250 TypeMisMatch {
251 function_name: String,
252 argument_source_span: SourceSpan,
253 error: TypeMismatchError,
254 },
255 MissingRecordFields {
256 function_name: String,
257 argument_source_span: SourceSpan,
258 missing_fields: Vec<Path>,
259 },
260 UnResolvedTypes {
261 function_name: String,
262 source_span: SourceSpan,
263 unresolved_error: UnResolvedTypesError,
264 expected_type: AnalysedType,
265 },
266
267 InvalidResourceMethodCall {
268 resource_method_name: String,
269 invalid_lhs_source_span: SourceSpan,
270 },
271
272 InvalidGenericTypeParameter {
273 generic_type_parameter: String,
274 source_span: SourceSpan,
275 message: String,
276 },
277
278 ArgumentSizeMisMatch {
279 function_name: String,
280 source_span: SourceSpan,
281 expected: usize,
282 provided: usize,
283 },
284}
285
286impl FunctionCallError {
287 pub fn invalid_function_call(
288 function_name: &str,
289 function_source_span: SourceSpan,
290 message: impl AsRef<str>,
291 ) -> FunctionCallError {
292 FunctionCallError::InvalidFunctionCall {
293 function_name: function_name.to_string(),
294 source_span: function_source_span,
295 message: message.as_ref().to_string(),
296 }
297 }
298 pub fn invalid_generic_type_parameter(
299 generic_type_parameter: &str,
300 message: impl AsRef<str>,
301 source_span: SourceSpan,
302 ) -> FunctionCallError {
303 FunctionCallError::InvalidGenericTypeParameter {
304 generic_type_parameter: generic_type_parameter.to_string(),
305 message: message.as_ref().to_string(),
306 source_span,
307 }
308 }
309}
310
311pub struct InvalidWorkerName {
312 pub worker_name_source_span: SourceSpan,
313 pub message: String,
314}
315
316#[derive(Clone)]
317pub struct CustomError {
318 pub source_span: SourceSpan,
319 pub message: String,
320 pub help_message: Vec<String>,
321}
322
323impl CustomError {
324 pub fn new(source_span: SourceSpan, message: impl AsRef<str>) -> CustomError {
325 CustomError {
326 source_span,
327 message: message.as_ref().to_string(),
328 help_message: Vec::new(),
329 }
330 }
331
332 pub fn with_help_message(&self, message: impl AsRef<str>) -> CustomError {
333 let mut custom_error: CustomError = self.clone();
334 custom_error.help_message.push(message.as_ref().to_string());
335 custom_error
336 }
337}