1use std::fmt::{Display, Formatter};
2
3use ariadne::{CharSet, Color, Config, Label, Report, ReportKind, Source};
4use schemars::JsonSchema;
5use serde::Deserialize;
6use serde::Serialize;
7
8use crate::lexer::error::SyntaxError;
9use crate::lexer::token::{Span, Token, TokenKind};
10use crate::parser::ast::attributes::AttributeGroup;
11use crate::parser::ast::data_type::Type;
12use crate::parser::ast::modifiers::PromotedPropertyModifier;
13use crate::parser::ast::Program;
14
15use super::ast::identifiers::SimpleIdentifier;
16use super::ast::variables::SimpleVariable;
17use super::state::State;
18
19pub type ParseResult<T> = Result<T, ParseError>;
20
21#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
22#[serde(tag = "type")]
23pub enum ParseErrorAnnotationType {
24 Hint,
25 Error,
26}
27
28#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
29pub struct ParseErrorAnnotation {
30 pub r#type: ParseErrorAnnotationType,
31 pub message: String,
32 pub position: usize,
33 pub length: usize,
34}
35
36#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
37pub struct ParseError {
38 pub id: String,
39 pub message: String,
40 pub span: Span,
41 pub annotations: Vec<ParseErrorAnnotation>,
42 pub note: Option<String>,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
46pub struct ParseErrorStack {
47 pub partial: Program,
48 pub errors: Vec<ParseError>,
49}
50
51impl ParseErrorStack {
52 pub fn report<'a>(
53 &self,
54 source: &'a str,
55 origin: Option<&'a str>,
56 colored: bool,
57 ascii: bool,
58 ) -> std::io::Result<String> {
59 let mut reports = Vec::new();
60
61 for error in &self.errors {
62 reports.push(error.report(source, origin, colored, ascii)?);
63 }
64
65 Ok(reports.join("\n"))
66 }
67}
68
69impl ParseError {
70 pub fn new<TId: ToString, TMessage: ToString>(id: TId, message: TMessage, span: Span) -> Self {
71 Self {
72 id: id.to_string(),
73 message: message.to_string(),
74 span,
75 annotations: Vec::new(),
76 note: None,
77 }
78 }
79
80 pub fn highlight(mut self, position: usize, length: usize) -> Self {
81 self.annotations.push(ParseErrorAnnotation {
82 r#type: ParseErrorAnnotationType::Hint,
83 message: "".to_owned(),
84 position,
85 length,
86 });
87
88 self
89 }
90
91 pub fn error<T: ToString>(mut self, message: T, position: usize, length: usize) -> Self {
92 self.annotations.push(ParseErrorAnnotation {
93 r#type: ParseErrorAnnotationType::Error,
94 message: message.to_string(),
95 position,
96 length,
97 });
98
99 self
100 }
101
102 pub fn note<T: ToString>(mut self, note: T) -> Self {
103 self.note = Some(note.to_string());
104
105 self
106 }
107
108 pub fn report<'a>(
109 &self,
110 source: &'a str,
111 origin: Option<&'a str>,
112 colored: bool,
113 ascii: bool,
114 ) -> std::io::Result<String> {
115 let origin = origin.unwrap_or("input");
116
117 let mut report = Report::build(ReportKind::Error, origin, self.span.position)
118 .with_code(&self.id)
119 .with_message(&self.message)
120 .with_config(
121 Config::default()
122 .with_color(colored)
123 .with_char_set(if ascii {
124 CharSet::Ascii
125 } else {
126 CharSet::Unicode
127 }),
128 );
129
130 for (order, annotation) in self.annotations.iter().enumerate() {
131 let mut label = Label::new((
132 origin,
133 annotation.position..annotation.position + annotation.length,
134 ))
135 .with_order(order.try_into().unwrap());
136
137 if !annotation.message.is_empty() {
138 label = label.with_message(&annotation.message);
139 }
140
141 if colored {
142 label = match annotation.r#type {
143 ParseErrorAnnotationType::Hint => label.with_color(Color::Cyan),
144 ParseErrorAnnotationType::Error => label.with_color(Color::Red),
145 };
146 }
147
148 report = report.with_label(label);
149 }
150
151 if let Some(note) = &self.note {
152 report = report.with_note(note);
153 }
154
155 let code = (origin, Source::from(source));
156
157 let mut bytes = Vec::new();
158
159 report.finish().write(code, &mut bytes)?;
160
161 let string = unsafe {
162 String::from_utf8_unchecked(bytes)
164 };
165
166 Ok(string)
167 }
168}
169
170pub fn unexpected_token(expected: Vec<String>, found: &Token) -> ParseError {
171 let (found_name, eof) = match &found.kind {
172 TokenKind::Eof => ("end of file".to_string(), true),
173 kind => match kind {
174 TokenKind::Identifier
175 | TokenKind::QualifiedIdentifier
176 | TokenKind::FullyQualifiedIdentifier => ("identifier".to_string(), false),
177 TokenKind::Variable => ("variable".to_string(), false),
178 TokenKind::LiteralInteger
179 | TokenKind::LiteralFloat
180 | TokenKind::LiteralSingleQuotedString
181 | TokenKind::LiteralDoubleQuotedString => ("literal".to_string(), false),
182 _ => (format!("token `{}`", found.value), false),
183 },
184 };
185
186 if expected.is_empty() {
187 return if eof {
188 ParseError::new("E002", format!("unexpected {}", found_name), found.span)
189 } else {
190 ParseError::new("E003", format!("unexpected {}", found_name), found.span).error(
191 "try removing this".to_string(),
192 found.span.position,
193 found.value.len(),
194 )
195 };
196 }
197
198 let expected: Vec<String> = expected
199 .iter()
200 .map(|s| {
201 if s.starts_with("a ") || s.starts_with("an ") {
202 s.to_string()
203 } else {
204 format!("`{}`", s)
205 }
206 })
207 .collect();
208
209 let length = expected.len();
210 let expected = if length > 2 {
211 let (left, right) = expected.split_at(length - 1);
212
213 format!("{}, or {}", left.join(", "), right[0])
214 } else {
215 expected.join(", or ")
216 };
217
218 ParseError::new(
219 "E005",
220 format!("unexpected {}, expecting {}", found_name, expected),
221 found.span,
222 )
223 .error(
224 format!("expected {}", expected),
225 found.span.position,
226 found.value.len(),
227 )
228}
229
230pub fn unexpected_identifier(expected: Vec<String>, found: String, span: Span) -> ParseError {
231 let length = expected.len();
232 let expected = if length >= 2 {
233 let (left, right) = expected.split_at(length - 1);
234
235 format!("{}`, or `{}", left.join("`, `"), right[0])
236 } else {
237 expected.join("")
238 };
239
240 ParseError::new(
241 "E006",
242 format!(
243 "unexpected identifier `{}`, expecting `{}`",
244 found, expected
245 ),
246 span,
247 )
248 .error(
249 format!("try replacing this with `{}`", expected),
250 span.position,
251 found.len(),
252 )
253}
254
255pub fn multiple_modifiers(modifier: String, first: Span, second: Span) -> ParseError {
256 ParseError::new(
257 "E007",
258 format!("multiple `{}` modifiers are not allowed", modifier),
259 second,
260 )
261 .highlight(first.position, modifier.len())
262 .error("try removing this", second.position, modifier.len())
263}
264
265pub fn multiple_visibility_modifiers(first: (String, Span), second: (String, Span)) -> ParseError {
266 ParseError::new(
267 "E008",
268 "multiple visibility modifiers are not allowed",
269 second.1,
270 )
271 .highlight(first.1.position, first.0.len())
272 .error("try removing this", second.1.position, second.0.len())
273}
274
275pub fn standalone_type_used_as_nullable(ty: &Type, span: Span) -> ParseError {
276 let type_span = ty.first_span();
277 let type_string = ty.to_string();
278
279 ParseError::new(
280 "E009",
281 format!("standalone type `{}` cannot be nullable", type_string),
282 type_span,
283 )
284 .error("try removing this", span.position, 1)
285 .highlight(type_span.position, type_string.len())
286 .note("`never`, `void`, and `mixed` cannot be nullable")
287}
288
289pub fn standalone_type_used_in_union(ty: &Type, span: Span) -> ParseError {
290 let type_span = ty.first_span();
291 let type_string = ty.to_string();
292
293 ParseError::new(
294 "E010",
295 format!(
296 "standalone type `{}` cannot be used in a union",
297 type_string
298 ),
299 type_span,
300 )
301 .error(
302 format!("try using a type other than `{}`", type_string),
303 type_span.position,
304 type_string.len(),
305 )
306 .highlight(span.position, 1)
307 .note("`never`, `void`, `mixed`, and nullable types cannot be used in a union")
308}
309
310pub fn standalone_type_used_in_intersection(ty: &Type, span: Span) -> ParseError {
311 let type_span = ty.first_span();
312 let type_string = ty.to_string();
313
314 ParseError::new(
315 "E011",
316 format!(
317 "standalone type `{}` cannot be used in an intersection",
318 type_string
319 ),
320 type_span,
321 )
322 .error(
323 format!("try using a type other than `{}`", type_string),
324 type_span.position,
325 type_string.len(),
326 )
327 .highlight(span.position, 1)
328 .note("`never`, `void`, `mixed`, and nullable types cannot be used in an intersection")
329}
330
331pub fn try_without_catch_or_finally(try_span: Span, last_right_brace: Span) -> ParseError {
332 ParseError::new(
333 "E012",
334 "cannot use `try` without `catch` or `finally`",
335 try_span,
336 )
337 .highlight(
338 try_span.position,
339 last_right_brace.position - try_span.position + 1,
340 )
341}
342
343pub fn variadic_promoted_property(
344 state: &mut State,
345 class: Option<&SimpleIdentifier>,
346 property: &SimpleVariable,
347 span: Span,
348 modifier: &PromotedPropertyModifier,
349) -> ParseError {
350 let error = ParseError::new(
351 "E013",
352 format!(
353 "promoted property `{}::{}` cannot declare variadic",
354 class
355 .map(|c| state.named(c))
356 .unwrap_or_else(|| "anonymous@class".to_string()),
357 property.name
358 ),
359 span,
360 )
361 .highlight(modifier.span().position, modifier.to_string().len())
362 .highlight(property.span.position, property.name.len())
363 .error("try removing this variadic declaration", span.position, 3);
364
365 if let Some(class) = class {
366 error.highlight(class.span.position, class.value.len())
367 } else {
368 error
369 }
370}
371
372pub fn missing_type_for_readonly_property(
373 state: &mut State,
374 class: Option<&SimpleIdentifier>,
375 property: &SimpleVariable,
376 readonly_span: Span,
377) -> ParseError {
378 let error = ParseError::new(
379 "E014",
380 format!(
381 "missing type for readonly property `{}::{}`",
382 class
383 .map(|c| state.named(c))
384 .unwrap_or_else(|| "anonymous@class".to_string()),
385 property.name
386 ),
387 property.span,
388 )
389 .error(
390 format!("try adding a type before `{}`", property.name),
391 property.span.position,
392 property.name.len(),
393 )
394 .highlight(readonly_span.position, 8);
395
396 if let Some(class) = class {
397 error.highlight(class.span.position, class.value.len())
398 } else {
399 error
400 }
401}
402
403pub fn abstract_method_on_a_non_abstract_class(
404 state: &mut State,
405 class: &SimpleIdentifier,
406 method: &SimpleIdentifier,
407 abstract_span: Span,
408 semicolon_span: Span,
409) -> ParseError {
410 ParseError::new(
411 "E015",
412 format!(
413 "cannot declare method `{}::{}` abstract, as `{}` class is not abstract",
414 state.named(&class),
415 method.value,
416 class,
417 ),
418 semicolon_span,
419 )
420 .error(
421 "try removing this `abstract` modifier",
422 abstract_span.position,
423 "abstract".len(),
424 )
425 .highlight(class.span.position, class.value.len())
426 .highlight(method.span.position, method.value.len())
427}
428
429pub fn constructor_in_enum(
430 state: &mut State,
431 r#enum: &SimpleIdentifier,
432 constructor: &SimpleIdentifier,
433) -> ParseError {
434 ParseError::new(
435 "E016",
436 format!(
437 "cannot declare a constructor on enum `{}`",
438 state.named(&r#enum)
439 ),
440 constructor.span,
441 )
442 .error(
443 "try removing this constructor",
444 constructor.span.position,
445 constructor.value.len(),
446 )
447 .highlight(r#enum.span.position, r#enum.value.len())
448}
449
450pub fn magic_method_in_enum(
451 state: &mut State,
452 r#enum: &SimpleIdentifier,
453 method: &SimpleIdentifier,
454) -> ParseError {
455 ParseError::new(
456 "E017",
457 format!(
458 "cannot declare magic method `{}::{}` in an enum",
459 state.named(&r#enum),
460 method.value
461 ),
462 method.span,
463 )
464 .error(
465 "try removing this magic method",
466 method.span.position,
467 method.value.len(),
468 )
469 .highlight(r#enum.span.position, r#enum.value.len())
470}
471
472pub fn missing_case_value_for_backed_enum(
473 state: &mut State,
474 r#enum: &SimpleIdentifier,
475 case: &SimpleIdentifier,
476 semicolon_span: Span,
477) -> ParseError {
478 ParseError::new(
479 "E018",
480 format!(
481 "case `{}::{}` of backed enum `{}` must have a value",
482 state.named(&r#enum),
483 case,
484 r#enum
485 ),
486 semicolon_span,
487 )
488 .error("try adding a value", semicolon_span.position, 1)
489 .highlight(case.span.position, case.value.len())
490 .highlight(r#enum.span.position, r#enum.value.len())
491}
492
493pub fn case_value_for_unit_enum(
494 state: &mut State,
495 r#enum: &SimpleIdentifier,
496 case: &SimpleIdentifier,
497 equals_span: Span,
498) -> ParseError {
499 ParseError::new(
500 "E019",
501 format!(
502 "case `{}::{}` of unit enum `{}` cannot have a value",
503 state.named(&r#enum),
504 case,
505 r#enum
506 ),
507 equals_span,
508 )
509 .error("try replacing this with `;`", equals_span.position, 1)
510 .highlight(case.span.position, case.value.len())
511 .highlight(r#enum.span.position, r#enum.value.len())
512}
513
514pub fn modifier_cannot_be_used_for_constant(modifier: String, modifier_span: Span) -> ParseError {
515 ParseError::new(
516 "E020",
517 format!("cannot use '{}' as constant modifier", modifier),
518 modifier_span,
519 )
520 .error("try removing this", modifier_span.position, modifier.len())
521 .note("only `public`, `protected`, `private`, and `final` modifiers can be used on constants")
522}
523
524pub fn modifier_cannot_be_used_for_interface_constant(
525 modifier: String,
526 modifier_span: Span,
527) -> ParseError {
528 ParseError::new(
529 "E021",
530 format!(
531 "cannot use '{}' as an interface constant modifier",
532 modifier
533 ),
534 modifier_span,
535 )
536 .error("try removing this", modifier_span.position, modifier.len())
537 .note("only `public`, and `final` modifiers can be used on interface constants")
538}
539
540pub fn modifier_cannot_be_used_for_promoted_property(
541 modifier: String,
542 modifier_span: Span,
543) -> ParseError {
544 ParseError::new(
545 "E022",
546 format!("cannot use '{}' as a promoted property modifier", modifier),
547 modifier_span,
548 )
549 .error(
550 "try removing this",
551 modifier_span.position,
552 modifier.len(),
553 )
554 .note("only `public`, `protected`, `private`, and `readonly` modifiers can be used on promoted properties")
555}
556
557pub fn modifier_cannot_be_used_for_property(modifier: String, modifier_span: Span) -> ParseError {
558 ParseError::new(
559 "E023",
560 format!("cannot use '{}' as a property modifier", modifier),
561 modifier_span,
562 )
563 .error(
564 "try removing this",
565 modifier_span.position,
566 modifier.len(),
567 )
568 .note("only `public`, `protected`, `private`, `static`, and `readonly` modifiers can be used on properties")
569}
570
571pub fn modifier_cannot_be_used_for_class(modifier: String, modifier_span: Span) -> ParseError {
572 ParseError::new(
573 "E024",
574 format!("cannot use '{}' as a class modifier", modifier),
575 modifier_span,
576 )
577 .error("try removing this", modifier_span.position, modifier.len())
578 .note("only `final`, `abstract`, and `readonly` modifiers can be used on classes")
579}
580
581pub fn modifier_cannot_be_used_for_class_method(
582 modifier: String,
583 modifier_span: Span,
584) -> ParseError {
585 ParseError::new(
586 "E025",
587 format!("cannot use '{}' as a class method modifier", modifier),
588 modifier_span,
589 )
590 .error(
591 "try removing this",
592 modifier_span.position,
593 modifier.len(),
594 )
595 .note("only `public`, `protected`, `private`, `final`, `static`, and `abstract` modifiers can be used on class methods")
596}
597
598pub fn modifier_cannot_be_used_for_enum_method(
599 modifier: String,
600 modifier_span: Span,
601) -> ParseError {
602 ParseError::new(
603 "E026",
604 format!("cannot use '{}' as an enum method modifier", modifier),
605 modifier_span,
606 )
607 .error(
608 "try removing this",
609 modifier_span.position,
610 modifier.len(),
611 )
612 .note("only `public`, `protected`, `private`, `final`, and `static` modifiers can be used on enum methods")
613}
614
615pub fn modifier_cannot_be_used_for_interface_method(
616 modifier: String,
617 modifier_span: Span,
618) -> ParseError {
619 ParseError::new(
620 "E027",
621 format!("cannot use '{}' as an interface method modifier", modifier),
622 modifier_span,
623 )
624 .error("try removing this", modifier_span.position, modifier.len())
625 .note("only `public`, and `static` modifiers can be used on interface methods")
626}
627
628pub fn final_and_abstract_modifiers_combined_for_class(
629 final_span: Span,
630 abstract_span: Span,
631) -> ParseError {
632 ParseError::new(
633 "E028",
634 "cannot declare a `final` class as `abstract`",
635 abstract_span,
636 )
637 .highlight(final_span.position, "final".len())
638 .error(
639 "try removing this",
640 abstract_span.position,
641 "abstract".len(),
642 )
643}
644
645pub fn final_and_abstract_modifiers_combined_for_class_member(
646 final_span: Span,
647 abstract_span: Span,
648) -> ParseError {
649 ParseError::new(
650 "E029",
651 "cannot declare a `final` class member as `abstract`",
652 abstract_span,
653 )
654 .highlight(final_span.position, "final".len())
655 .error(
656 "try removing this",
657 abstract_span.position,
658 "abstract".len(),
659 )
660}
661
662pub fn final_and_private_modifiers_combined_for_constant(
663 final_span: Span,
664 private_span: Span,
665) -> ParseError {
666 ParseError::new(
667 "E030",
668 "cannot declare a `private` constant as `final`",
669 final_span,
670 )
671 .highlight(private_span.position, "private".len())
672 .error("try removing this", final_span.position, "final".len())
673 .note("private constants cannot be final as they are not visible to other classes")
674}
675
676pub fn reached_unpredictable_state(span: Span) -> ParseError {
677 ParseError::new("E031", "reached unpredictable state", span).error(
678 "please report this as a bug",
679 span.position,
680 1,
681 )
682}
683
684pub fn static_property_cannot_be_readonly(
685 state: &mut State,
686 class: Option<&SimpleIdentifier>,
687 property: &SimpleVariable,
688 static_span: Span,
689 readonly_span: Span,
690) -> ParseError {
691 let error = ParseError::new(
692 "E032",
693 format!(
694 "cannot declare `readonly` property `{}::{}` as 'static'",
695 class
696 .map(|c| state.named(c))
697 .unwrap_or_else(|| "anonymous@class".to_string()),
698 property.name,
699 ),
700 static_span,
701 )
702 .highlight(property.span.position, property.name.len())
703 .highlight(readonly_span.position, "readonly".len())
704 .error("try removing this", static_span.position, "static".len());
705
706 if let Some(class) = class {
708 error.highlight(class.span.position, class.value.len())
709 } else {
710 error
711 }
712}
713
714pub fn readonly_property_has_default_value(
715 state: &mut State,
716 class: Option<&SimpleIdentifier>,
717 property: &SimpleVariable,
718 readonly_span: Span,
719 equals_span: Span,
720) -> ParseError {
721 let error = ParseError::new(
722 "E033",
723 format!(
724 "readonly property `{}::{}` cannot have a default value",
725 class
726 .map(|c| state.named(c))
727 .unwrap_or_else(|| "anonymous@class".to_string()),
728 property.name,
729 ),
730 equals_span,
731 )
732 .highlight(property.span.position, property.name.len())
733 .highlight(readonly_span.position, "readonly".len())
734 .error("try removing this `=`", equals_span.position, 1);
735
736 if let Some(class) = class {
738 error.highlight(class.span.position, class.value.len())
739 } else {
740 error
741 }
742}
743
744pub fn unbraced_namespace_declarations_in_braced_context(span: Span) -> ParseError {
745 ParseError::new(
746 "E034",
747 "cannot mix braced and unbraced namespace declarations",
748 span,
749 )
750 .error("try replacing this `;` with `{`", span.position, 1)
751}
752
753pub fn braced_namespace_declarations_in_unbraced_context(span: Span) -> ParseError {
754 ParseError::new(
755 "E035",
756 "cannot mix braced and unbraced namespace declarations",
757 span,
758 )
759 .error("try replacing this `{` with `;`", span.position, 1)
760}
761
762pub fn nested_namespace_declarations(span: Span) -> ParseError {
763 ParseError::new("E035", "cannot nest namespace declarations", span).error(
764 "try closing previous namespace with `}` before declaring a new one",
765 span.position,
766 1,
767 )
768}
769
770pub fn forbidden_type_used_in_property(
771 state: &mut State,
772 class: Option<&SimpleIdentifier>,
773 property: &SimpleVariable,
774 ty: Type,
775) -> ParseError {
776 let type_string = ty.to_string();
777 let type_span = ty.first_span();
778
779 let error = ParseError::new(
780 "E037".to_string(),
781 format!(
782 "property `{}::{}` cannot have type `{}`",
783 class
784 .map(|c| state.named(c))
785 .unwrap_or_else(|| "anonymous@class".to_string()),
786 property.name,
787 type_string
788 ),
789 type_span,
790 )
791 .highlight(property.span.position, property.name.len())
792 .error(
793 "try using a different type",
794 type_span.position,
795 type_string.len(),
796 )
797 .note("`void`, `never`, and `callable` types are not allowed in properties");
798
799 if let Some(class) = class {
801 error.highlight(class.span.position, class.value.len())
802 } else {
803 error
804 }
805}
806
807pub fn match_expression_has_multiple_default_arms(first: Span, second: Span) -> ParseError {
808 ParseError::new(
809 "E038".to_string(),
810 "match expression cannot have more than one default arm",
811 second,
812 )
813 .highlight(first.position, "default".len())
814 .error("try removing this arm", second.position, "default".len())
815}
816
817pub fn missing_item_definition_after_attributes(
818 attributes: &Vec<AttributeGroup>,
819 current: &Token,
820) -> ParseError {
821 let mut annotations = vec![];
822
823 for attribute in attributes {
824 annotations.push(ParseErrorAnnotation {
825 r#type: ParseErrorAnnotationType::Hint,
826 message: "".to_string(),
827 position: attribute.start.position,
828 length: attribute.end.position - attribute.start.position,
829 });
830 }
831
832 annotations.push(match current.kind {
833 TokenKind::Eof => ParseErrorAnnotation {
834 r#type: ParseErrorAnnotationType::Error,
835 message: "reached end of file before an item definition".to_string(),
836 position: current.span.position,
837 length: current.value.len(),
838 },
839 _ => ParseErrorAnnotation {
840 r#type: ParseErrorAnnotationType::Error,
841 message: format!("expected an item definition, found `{}`", current.value),
842 position: current.span.position,
843 length: current.value.len(),
844 },
845 });
846
847 ParseError {
848 id: "E039".to_string(),
849 message: "missing item definition after attribute(s)".to_string(),
850 span: current.span,
851 annotations,
852 note: None,
853 }
854}
855
856pub fn nested_disjunctive_normal_form_types(span: Span) -> ParseError {
857 ParseError::new(
858 "E040".to_string(),
859 "cannot nest disjunctive normal form types",
860 span,
861 )
862 .error("try removing this", span.position, 1)
863}
864
865pub fn illegal_spread_operator_usage(span: Span) -> ParseError {
866 ParseError::new("E041".to_string(), "illegal spread operator usage", span).error(
867 "try removing this",
868 span.position,
869 3,
870 )
871}
872
873pub fn cannot_assign_reference_to_non_referencable_value(span: Span) -> ParseError {
874 ParseError::new(
875 "E042".to_string(),
876 "cannot assign reference to non-referencable value",
877 span,
878 )
879 .error("try removing this", span.position, 1)
880}
881
882pub fn mixing_keyed_and_unkeyed_list_entries(span: Span) -> ParseError {
883 ParseError::new(
884 "E043".to_string(),
885 "cannot mix keyed and un-keyed list entries",
886 span,
887 )
888 .error("", span.position, 1)
889}
890
891pub fn cannot_use_positional_argument_after_named_argument(
892 span: Span,
893 current_span: Span,
894) -> ParseError {
895 ParseError::new(
896 "E044".to_string(),
897 "cannot use positional argument after named argument",
898 span,
899 )
900 .error(
901 "try adding a name for this argument",
902 span.position,
903 current_span.position - span.position,
904 )
905}
906
907pub fn cannot_use_reserved_keyword_as_a_type_name(span: Span, keyword: String) -> ParseError {
908 ParseError::new(
909 "E045".to_string(),
910 format!("cannot use reserved keyword `{}` as a type name", keyword),
911 span,
912 )
913 .error("try using a different name", span.position, keyword.len())
914}
915
916pub fn cannot_use_reserved_keyword_as_a_goto_label(span: Span, keyword: String) -> ParseError {
917 ParseError::new(
918 "E046".to_string(),
919 format!("cannot use reserved keyword `{}` as a goto label", keyword),
920 span,
921 )
922 .error("try using a different name", span.position, keyword.len())
923}
924
925pub fn cannot_use_reserved_keyword_as_a_constant_name(span: Span, keyword: String) -> ParseError {
926 ParseError::new(
927 "E047".to_string(),
928 format!(
929 "cannot use reserved keyword `{}` as a constant name",
930 keyword
931 ),
932 span,
933 )
934 .error("try using a different name", span.position, keyword.len())
935}
936
937pub fn cannot_use_type_in_context(span: Span, ty: String) -> ParseError {
938 ParseError::new(
939 "E048".to_string(),
940 format!("cannot use type `{}` in current context", ty),
941 span,
942 )
943 .error("try using a different type", span.position, ty.len())
944}
945
946pub fn only_positional_arguments_are_accepted(span: Span, current_span: Span) -> ParseError {
947 ParseError::new(
948 "E049".to_string(),
949 "cannot use named argument, only positional arguments are accepted",
950 span,
951 )
952 .error(
953 "try changing this to a positional argument",
954 span.position,
955 current_span.position - span.position,
956 )
957}
958
959pub fn only_one_argument_is_accepted(span: Span, current_span: Span) -> ParseError {
960 ParseError::new("E050".to_string(), "only one argument are accepted", span).error(
961 "try removing this argument",
962 span.position,
963 current_span.position - span.position,
964 )
965}
966
967pub fn argument_is_required(span: Span, current_span: Span) -> ParseError {
968 ParseError::new("E051".to_string(), "argument is required", span).error(
969 "try passing an argument",
970 span.position,
971 current_span.position - span.position,
972 )
973}
974
975impl From<SyntaxError> for ParseError {
976 fn from(e: SyntaxError) -> Self {
977 Self {
978 id: "E001".to_string(),
979 message: format!("syntax error, {}", e),
980 annotations: vec![],
981 span: e.span(),
982 note: None,
983 }
984 }
985}
986
987impl Display for ParseError {
988 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
989 write!(
990 f,
991 "[{}] Error: {} on line {} column {}",
992 self.id, self.message, self.span.line, self.span.column
993 )?;
994
995 if let Some(note) = &self.note {
996 write!(f, ", Note: {}", note)?;
997 }
998
999 Ok(())
1000 }
1001}
1002
1003impl Display for ParseErrorStack {
1004 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1005 for error in &self.errors {
1006 writeln!(f, "{}", error)?;
1007 }
1008
1009 Ok(())
1010 }
1011}