1use std::fmt::{Display, Formatter};
10
11use annotate_snippets::display_list::{DisplayList, FormatOptions};
12use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation};
13
14use crate::parser::lexer::Token;
15use crate::parser::preprocessor::ArgumentIndex;
16use crate::span::Index;
17use crate::symbol::{Ident, Symbol};
18use crate::util::format_list;
19use crate::{SourceMap, Span};
20use beef::lean::Cow;
21
22pub type Error = crate::error::Error<Type>;
23pub type Warning = crate::error::Error<WarningType>;
24pub type Result<T = ()> = std::result::Result<T, Error>;
25
26#[derive(Debug, Clone)]
27pub enum Type {
28 PortRedeclaration(Span, Span),
30 HierarchicalIdNotAllowedAsNature {
31 hierarchical_id: Vec<Ident>,
32 },
33 PortNotPreDeclaredInModuleHead {
34 port_list: Span,
35 },
36 PortPreDeclaredNotDefined,
37 EmptyListEntry(List),
38 AttributeAlreadyDefined,
39 RequiredAttributeNotDefined(Vec<Symbol>),
40 DiscreteDisciplineHasNatures,
41 StringTooLong(usize),
42
43 MacroArgumentCount {
45 expected: ArgumentIndex,
46 found: usize,
47 },
48 ConditionEndWithoutStart,
49 MacroEndTooEarly,
50 UnclosedConditions(Vec<Span>),
51 MacroNotFound,
52 MacroRecursion,
53 CompilerDirectiveSplit,
54 IoErr(String),
55 AlreadyDeclaredInThisScope {
56 other_declaration: Span,
57 name: Symbol,
58 },
59
60 UnexpectedEof {
62 expected: Vec<Token>,
63 },
64 UnexpectedToken {
65 expected: Vec<Token>,
66 },
67 MissingOrUnexpectedToken {
68 expected: Vec<Token>,
69 expected_at: Index,
70 },
71 UnexpectedTokens {
72 expected: Vec<Expected>,
73 },
74 TooManyBranchArgs(usize),
75 Unsupported(Unsupported),
76 FunctionWithoutBody(Ident),
77 Unrecoverable,
78}
79
80impl From<std::io::Error> for Type {
81 fn from(io_err: std::io::Error) -> Self {
82 Self::IoErr(io_err.to_string())
83 }
84}
85
86#[derive(Clone, Copy, Debug)]
87pub enum Unsupported {
88 StringParameters,
89 DefaultDiscipline, MacroDefinedInMacro,
91 NatureInheritance,
92 ConstantFunctionCalls,
93 SelfDerivingAssignments,
94}
95
96impl Display for Unsupported {
97 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
98 match self {
99 Self::StringParameters => f.write_str("String parameters"),
100 Self::DefaultDiscipline => f.write_str("Implicit Disciplines"),
101 Self::MacroDefinedInMacro => f.write_str("Macros defined inside another Macros"),
102 Self::NatureInheritance => f.write_str("Derived Natures"),
103 Self::ConstantFunctionCalls => {
104 f.write_str("Function calls inside constant expressions")
105 }
106 Self::SelfDerivingAssignments => {
107 f.write_str("Assignments of the form 'x = f(ddx(x,..),...)'")
108 }
109 }
110 }
111}
112#[derive(Debug, Copy, Clone)]
113pub enum Expected {
114 Identifier,
115 PortDeclaration,
116 Port,
117 UnaryOperator,
118 BinaryOperator,
119 Primary,
120 Statement,
121 Expression,
122 BranchAcess,
123 ParameterRange,
124}
125
126impl Display for Expected {
127 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
128 match self {
130 Self::Identifier => f.write_str("identifier"),
131 Self::PortDeclaration => f.write_str("port declaration"),
132 Self::Port => f.write_str("port listing"),
133 Self::UnaryOperator => f.write_str("unary operator (+,-,!)"),
134 Self::BinaryOperator => f.write_str("binary operator (such as * or +)"),
135 Self::Primary => f.write_str("expression primary"),
136 Self::Statement => f.write_str("statement"),
137 Self::BranchAcess => f.write_str("branch access"),
138 Self::ParameterRange => f.write_str("parameter range (such as from [0:inf]"),
139 Self::Expression => f.write_str("expression"),
140 }
141 }
142}
143
144#[derive(Clone, Debug)]
145pub enum WarningType {
146 MacroOverwritten(Span),
147 AttributeOverwrite(Ident, Span),
148}
149
150#[derive(Debug, Clone, Copy)]
151pub enum List {
152 MacroArgument,
153 FunctionArgument,
154}
155impl Error {
156 #[allow(clippy::too_many_lines)]
157 pub fn print(self, source_map: &SourceMap, translate_lines: bool) {
158 let (mut line, mut line_number, substitution_name, mut range) =
159 source_map.resolve_span_within_line(self.source, translate_lines);
160 let (origin, mut footer) = if let Some(substitution_name) = substitution_name {
161 (Cow::owned(substitution_name),vec![Annotation{
162 id: None,
163 label: Some("If macros/files are included inside this macro/file the error output might be hard to understand/display incorrect line numbers (See fully expanded source)"),
164 annotation_type: AnnotationType::Note
165 }])
166 } else {
167 (Cow::const_str(source_map.main_file_name), Vec::new())
168 };
169
170 let opt = FormatOptions {
171 color: true,
172 anonymized_line_numbers: false,
173 };
174
175 match self.error_type {
176 Type::UnexpectedToken { ref expected } => {
177 let range = (range.start as usize,range.end as usize);
178 let label = format!("expected {}", format_list(expected, "'"));
179
180 let snippet = Snippet {
181 title: Some(Annotation {
182 id: None,
183 label: Some("Unexpected Token"),
184 annotation_type: AnnotationType::Error,
185 }),
186 footer,
187 slices: vec![Slice {
188 source: line,
189 line_start: line_number as usize,
190 origin: Some(&*origin),
191 annotations: vec![SourceAnnotation {
192 range,
193 label: &label,
194 annotation_type: AnnotationType::Error,
195 }],
196 fold: false,
197 }],
198 opt,
199 };
200 let display_list = DisplayList::from(snippet);
201 eprintln!("{}", display_list);
202 }
203
204 Type::UnexpectedTokens { ref expected } => {
205 let range = (range.start as usize,range.end as usize);
206 let label = format!("expected {}", format_list(expected, ""));
207
208 let snippet = Snippet {
209 title: Some(Annotation {
210 id: None,
211 label: Some("Unexpected Token"),
212 annotation_type: AnnotationType::Error,
213 }),
214 footer,
215 slices: vec![Slice {
216 source: line,
217 line_start: line_number as usize,
218 origin: Some(&*origin),
219 annotations: vec![SourceAnnotation {
220 range,
221 label: &label,
222 annotation_type: AnnotationType::Error,
223 }],
224 fold: false,
225 }],
226 opt,
227 };
228 let display_list = DisplayList::from(snippet);
229 eprintln!("{}", display_list);
230 }
231 Type::PortRedeclaration(error_span, declaration_list_span) => {
232 let error_range = (
233 (range.start + error_span.get_start()) as usize,
234 (range.start + error_span.get_end()) as usize,
235 );
236 let declaration_list_range = (
237 (declaration_list_span.get_start() + range.start) as usize,
238 (range.start as Index + declaration_list_span.get_end()) as usize,
239 );
240 let snippet = Snippet {
241 title: Some(Annotation {
242 id: None,
243 label: Some(
244 "Module ports declared in Module body when already declared in Module Head"
245 ,
246 ),
247 annotation_type: AnnotationType::Error,
248 }),
249 footer,
250 slices: vec![Slice {
251 source: line,
252 line_start: line_number as usize,
253 origin:Some(&*origin),
254 annotations: vec![
255 SourceAnnotation {
256 range:declaration_list_range,
257 label: "Ports are declared here",
258 annotation_type: AnnotationType::Info,
259 },
260 SourceAnnotation {
261 range: error_range,
262 label: "Port declaration is illegal here",
263 annotation_type: AnnotationType::Error,
264 },
265 ],
266 fold: true,
267 }],opt
268 };
269 let display_list = DisplayList::from(snippet);
270 eprintln!("{}", display_list);
271 }
272
273 Type::AlreadyDeclaredInThisScope {
274 name,
275 other_declaration,
276 } => {
277 let (
278 other_declaration_line,
279 other_declaration_line_number,
280 other_declaration_origin,
281 other_declaration_range,
282 ) = source_map.resolve_span_within_line(other_declaration, translate_lines);
283
284 let range = (range.start as usize,range.end as usize);
285 let other_declaration_range = (
286 other_declaration_range.start as usize,
287 other_declaration_range.end as usize,
288 );
289 let other_declaration_origin = if let Some(other_declaration_origin) =
290 other_declaration_origin
291 {
292 footer.push(Annotation{
293 id: None,
294 label: Some("If macros/files are included inside this macro/file the error output might be hard to understand/display incorrect line numbers (See fully expanded source)"),
295 annotation_type: AnnotationType::Note
296 });
297 Cow::owned(other_declaration_origin)
298 } else {
299 Cow::const_str(source_map.main_file_name)
300 };
301 let label = format!("'{}' has already been declared", name.as_str());
302 let inline_label = format!("First declaration of '{}' here", name.as_str());
303
304 let snippet = Snippet {
305 title: Some(Annotation {
306 id: None,
307 label: Some(&label),
308 annotation_type: AnnotationType::Error,
309 }),
310 footer,
311 slices: vec![
312 Slice {
313 source: other_declaration_line,
314 line_start: other_declaration_line_number as usize,
315 origin: Some(&*other_declaration_origin),
316 annotations: vec![SourceAnnotation {
317 range: other_declaration_range,
318 label: &inline_label,
319 annotation_type: AnnotationType::Info,
320 }],
321 fold: false,
322 },
323 Slice {
324 source: line,
325 line_start: line_number as usize,
326 origin: Some(&*origin),
327 annotations: vec![SourceAnnotation {
328 range,
329 label: "Item already declared",
330 annotation_type: AnnotationType::Error,
331 }],
332
333 fold: false,
334 },
335 ],
336 opt,
337 };
338 let display_list = DisplayList::from(snippet);
339 eprintln!("{}", display_list);
340 }
341
342 Type::PortPreDeclaredNotDefined => {
343 let range = (range.start as usize,range.end as usize);
344 let snippet = Snippet {
345 title: Some(Annotation {
346 id: None,
347 label: Some(
348 "Port was pre declared in module head but not defined in module body",
349 ),
350 annotation_type: AnnotationType::Error,
351 }),
352 footer,
353 slices: vec![Slice {
354 source: line,
355 line_start: line_number as usize,
356 origin: Some(&*origin),
357 annotations: vec![SourceAnnotation {
358 range,
359 label: "Declared here",
360 annotation_type: AnnotationType::Error,
361 }],
362 fold: false,
363 }],
364 opt,
365 };
366 let display_list = DisplayList::from(snippet);
367 eprintln!("{}", display_list);
368 }
369
370 Type::UnclosedConditions(ref conditions) => {
371 let slice_text: Vec<_> = conditions
372 .iter()
373 .copied()
374 .enumerate()
375 .map(|(index, condition)| {
376 let (src, line_number, origin, range) =
377 source_map.resolve_span_within_line(condition, translate_lines);
378 let range = (range.start as usize, range.end as usize);
379 (
380 src,
381 line_number,
382 origin.map_or(Cow::const_str(source_map.main_file_name), |val| {
383 Cow::owned(val)
384 }),
385 range,
386 format!("{}. condition started here", index),
387 )
388 })
389 .collect();
390 let slices = slice_text
391 .iter()
392 .map(|(src, line_number, origin, range, label)| Slice {
393 source: *src,
394 line_start: *line_number as usize,
395 origin: Some(&**origin),
396 annotations: vec![SourceAnnotation {
397 range: *range,
398 label,
399 annotation_type: AnnotationType::Error,
400 }],
401 fold: false,
402 })
403 .collect();
404
405 let label = format!("{} macro conditions where not closed. Conditions should be closed using `endif",{conditions.len()});
406 let snippet = Snippet {
407 title: Some(Annotation {
408 id: None,
409 label: Some(&label),
410 annotation_type: AnnotationType::Error,
411 }),
412 footer,
413 slices,
414 opt,
415 };
416
417 let display_list = DisplayList::from(snippet);
418 eprintln!("{}", display_list);
419 }
420
421 Type::MacroNotFound => {
422 let range = (range.start as usize,range.end as usize);
423 let snippet = Snippet {
424 title: Some(Annotation {
425 id: None,
426 label: Some("Macro referenced that was not defined before"),
427 annotation_type: AnnotationType::Error,
428 }),
429 footer,
430 slices: vec![Slice {
431 source: line,
432 line_start: line_number as usize,
433 origin: Some(&*origin),
434 annotations: vec![SourceAnnotation {
435 range,
436 label: "Reference occurs here",
437 annotation_type: AnnotationType::Error,
438 }],
439 fold: false,
440 }],
441 opt,
442 };
443
444 let display_list = DisplayList::from(snippet);
445 eprintln!("{}", display_list);
446 }
447 Type::HierarchicalIdNotAllowedAsNature { .. } => {
448 let range = (range.start as usize,range.end as usize);
449
450 let snippet = Snippet {
451 title: Some(Annotation {
452 id: None,
453 label: Some("Natures can not be hierarchical "),
454 annotation_type: AnnotationType::Error,
455 }),
456 footer,
457 slices: vec![Slice {
458 source: line,
459 line_start: line_number as usize,
460 origin: Some(&*origin),
461 annotations: vec![SourceAnnotation {
462 range,
463 label: ". in Nature identifier is illegal",
464 annotation_type: AnnotationType::Error,
465 }],
466 fold: false,
467 }],
468 opt,
469 };
470
471 let display_list = DisplayList::from(snippet);
472 eprintln!("{}", display_list);
473 }
474 Type::PortNotPreDeclaredInModuleHead { port_list } => {
475 let (
476 other_declaration_line,
477 other_declaration_line_number,
478 other_declaration_origin,
479 other_declaration_range,
480 ) = source_map.resolve_span_within_line(port_list, translate_lines);
481
482 let other_declaration_origin = if let Some(other_declaration_origin) =
483 other_declaration_origin
484 {
485 footer.push(Annotation{
486 id: None,
487 label: Some("If macros/files are included inside this macro/file the error output might be hard to understand/display incorrect line numbers (See fully expanded source)"),
488 annotation_type: AnnotationType::Note
489 });
490 Cow::owned(other_declaration_origin)
491 } else {
492 Cow::const_str(source_map.main_file_name)
493 };
494
495 let range = (range.start as usize,range.end as usize);
496 let other_declaration_range = (
497 other_declaration_range.start as usize,
498 other_declaration_range.end as usize,
499 );
500
501 let snippet = Snippet {
502 title: Some(Annotation {
503 id: None,
504 label: Some("Ports have to be listed in the Module head fi they are declared in the body"),
505 annotation_type: AnnotationType::Error,
506 }),
507 footer,
508 slices: vec![
509 Slice {
510 source: other_declaration_line,
511 line_start: other_declaration_line_number as usize,
512 origin: Some(&*other_declaration_origin),
513 annotations: vec![SourceAnnotation {
514 range: other_declaration_range,
515 label: "Port should have been listed here",
516 annotation_type: AnnotationType::Info,
517 }],
518 fold: false,
519 },
520 Slice {
521 source: line,
522 line_start: line_number as usize,
523 origin:Some(&*origin),
524 annotations: vec![SourceAnnotation {
525 range,
526 label: "Port declaration illegal without listing in module head",
527 annotation_type: AnnotationType::Error,
528 }],
529 fold: false,
530 },
531 ],
532 opt
533 };
534 let display_list = DisplayList::from(snippet);
535 eprintln!("{}", display_list);
536 }
537 Type::EmptyListEntry(_list_type) => {
538 let range = (range.start as usize,range.end as usize);
539 let snippet = Snippet {
540 title: Some(Annotation {
541 id: None,
542 label: Some("Empty macro arguments are not allowed"),
543 annotation_type: AnnotationType::Error,
544 }),
545 footer,
546 slices: vec![Slice {
547 source: line,
548 line_start: line_number as usize,
549 origin: Some(&*origin),
550 annotations: vec![SourceAnnotation {
551 range,
552 label: "Expected argument here",
553 annotation_type: AnnotationType::Error,
554 }],
555 fold: false,
556 }],
557 opt,
558 };
559 let display_list = DisplayList::from(snippet);
560 eprintln!("{}", display_list);
561 }
562 Type::MacroArgumentCount { expected, found } => {
563 let range = (range.start as usize,range.end as usize);
564 let label = format!(
565 "Found wrong number of Macro arguments. Expected {} found {} ",
566 expected, found
567 );
568
569 let snippet = Snippet {
570 title: Some(Annotation {
571 id: None,
572 label: Some(&*label),
573 annotation_type: AnnotationType::Error,
574 }),
575 footer,
576 slices: vec![Slice {
577 source: line,
578 line_start: line_number as usize,
579 origin: Some(&*origin),
580 annotations: vec![SourceAnnotation {
581 range,
582 label: "Unexpected `endif",
583 annotation_type: AnnotationType::Error,
584 }],
585 fold: false,
586 }],
587 opt,
588 };
589 let display_list = DisplayList::from(snippet);
590 eprintln!("{}", display_list);
591 }
592 Type::ConditionEndWithoutStart => {
593 let range = (range.start as usize,range.end as usize);
594 let snippet = Snippet {
595 title: Some(Annotation {
596 id: None,
597 label: Some("Unexpected `endif: No condition is currently in Scope "),
598 annotation_type: AnnotationType::Error,
599 }),
600 footer,
601 slices: vec![Slice {
602 source: line,
603 line_start: line_number as usize,
604 origin: Some(&*origin),
605 annotations: vec![SourceAnnotation {
606 range,
607 label: "Unexpected `endif",
608 annotation_type: AnnotationType::Error,
609 }],
610 fold: false,
611 }],
612 opt,
613 };
614 let display_list = DisplayList::from(snippet);
615 eprintln!("{}", display_list);
616 }
617 Type::MacroEndTooEarly => {
618 let range = (range.start as usize,range.end as usize);
619 let snippet = Snippet {
620 title: Some(Annotation {
621 id: None,
622 label: Some("Macro ended too early! One or more compiler directives are still unfinished (macro ends on new line not preceded by \\)"),
623 annotation_type: AnnotationType::Error,
624 }),
625 footer,
626 slices: vec![Slice {
627 source: line,
628 line_start: line_number as usize,
629 origin:Some(&*origin),
630 annotations: vec![SourceAnnotation {
631 range,
632 label: "Unexpected newline",
633 annotation_type: AnnotationType::Error,
634 }],
635 fold: false,
636 }],
637 opt
638 };
639 let display_list = DisplayList::from(snippet);
640 eprintln!("{}", display_list);
641 }
642 Type::MacroRecursion => {
643 let range = (range.start as usize,range.end as usize);
644 let snippet = Snippet {
645 title: Some(Annotation {
646 id: None,
647 label: Some("Macro recursion detected! Macros may not call themselves (directly or indirectly)"),
648 annotation_type: AnnotationType::Error,
649 }),
650 footer,
651 slices: vec![Slice {
652 source: line,
653 line_start: line_number as usize,
654 origin:Some(&*origin),
655 annotations: vec![SourceAnnotation {
656 range,
657 label: "Recursion detected here",
658 annotation_type: AnnotationType::Error,
659 }],
660 fold: false,
661 }],
662 opt
663 };
664 let display_list = DisplayList::from(snippet);
665 eprintln!("{}", display_list);
666 }
667 Type::CompilerDirectiveSplit => {
668 let range = (range.start as usize,range.end as usize);
669 let snippet = Snippet {
670 title: Some(Annotation {
671 id: None,
672 label: Some("Compiler directives (such as `define x) can't be split across borders of macros or files"),
673 annotation_type: AnnotationType::Error,
674 }),
675 footer,
676 slices: vec![Slice {
677 source: line,
678 line_start: line_number as usize,
679 origin:Some(&*origin),
680 annotations: vec![SourceAnnotation {
681 range,
682 label: "Split detected here",
683 annotation_type: AnnotationType::Error,
684 }],
685 fold: false,
686 }],
687 opt
688 };
689 let display_list = DisplayList::from(snippet);
690 eprintln!("{}", display_list);
691 }
692 Type::UnexpectedEof { ref expected } => {
693 let range = (range.start as usize,range.end as usize);
694 let label = format!("Unexpected EOF expected {}", format_list(expected, "'"));
695
696 let snippet = Snippet {
697 title: Some(Annotation {
698 id: None,
699 label: Some(&label),
700 annotation_type: AnnotationType::Error,
701 }),
702 footer,
703 slices: vec![Slice {
704 source: line,
705 line_start: line_number as usize,
706 origin: Some(&*origin),
707 annotations: vec![SourceAnnotation {
708 range,
709 label: "Unexpected EOF",
710 annotation_type: AnnotationType::Error,
711 }],
712 fold: true,
713 }],
714 opt,
715 };
716 let display_list = DisplayList::from(snippet);
717 eprintln!("{}", display_list);
718 }
719 Type::Unsupported(unsupported) => {
720 let range = (range.start as usize,range.end as usize);
721 let label = format!("{} are currently not supported", unsupported);
722
723 let snippet = Snippet {
724 title: Some(Annotation {
725 id: None,
726 label: Some(&label),
727 annotation_type: AnnotationType::Error,
728 }),
729 footer,
730 slices: vec![Slice {
731 source: line,
732 line_start: line_number as usize,
733 origin: Some(&*origin),
734 annotations: vec![SourceAnnotation {
735 range,
736 label: "Unsupported feature was used here",
737 annotation_type: AnnotationType::Error,
738 }],
739 fold: false,
740 }],
741 opt,
742 };
743 let display_list = DisplayList::from(snippet);
744 eprintln!("{}", display_list);
745 }
746 Type::IoErr(error) => {
747 let range = (range.start as usize,range.end as usize);
748 let snippet = Snippet {
749 title: Some(Annotation {
750 id: None,
751 label: Some(&error),
752 annotation_type: AnnotationType::Error,
753 }),
754 footer,
755 slices: vec![Slice {
756 source: line,
757 line_start: line_number as usize,
758 origin: Some(&*origin),
759 annotations: vec![SourceAnnotation {
760 range,
761 label: "Io Error occured here",
762 annotation_type: AnnotationType::Error,
763 }],
764 fold: false,
765 }],
766 opt,
767 };
768 let display_list = DisplayList::from(snippet);
769 eprintln!("{}", display_list);
770 }
771 Type::AttributeAlreadyDefined => {
772 let range = (range.start as usize,range.end as usize);
773 let snippet = Snippet {
774 title: Some(Annotation {
775 id: None,
776 label: Some("An attribute was redefined"),
777 annotation_type: AnnotationType::Error,
778 }),
779 footer,
780 slices: vec![Slice {
781 source: line,
782 line_start: line_number as usize,
783 origin: Some(&*origin),
784 annotations: vec![SourceAnnotation {
785 range,
786 label: "Redefined here",
787 annotation_type: AnnotationType::Error,
788 }],
789 fold: false,
790 }],
791 opt,
792 };
793 let display_list = DisplayList::from(snippet);
794 eprintln!("{}", display_list);
795 }
796
797 Type::RequiredAttributeNotDefined(ref missing) => {
798 let range = (range.start as usize,range.end as usize);
799 let label = format!(
800 "Nature is missing the required attributes {}",
801 format_list(missing, "'")
802 );
803
804 let snippet = Snippet {
805 title: Some(Annotation {
806 id: None,
807 label: Some(&label),
808 annotation_type: AnnotationType::Error,
809 }),
810 footer,
811 slices: vec![Slice {
812 source: line,
813 line_start: line_number as usize,
814 origin: Some(&*origin),
815 annotations: vec![SourceAnnotation {
816 range,
817 label: "Required attributes are missing",
818 annotation_type: AnnotationType::Error,
819 }],
820 fold: false,
821 }],
822 opt,
823 };
824 let display_list = DisplayList::from(snippet);
825 eprintln!("{}", display_list);
826 }
827
828 Type::DiscreteDisciplineHasNatures => {
829 let range = (range.start as usize, range.end as usize);
830 let snippet = Snippet {
831 title: Some(Annotation {
832 id: None,
833 label: Some("Disciplines in the discrete Domain may not define flow/potential natures"),
834 annotation_type: AnnotationType::Error,
835 }),
836 footer,
837 slices: vec![Slice {
838 source: line,
839 line_start: line_number as usize,
840 origin:Some(&*origin),
841 annotations: vec![SourceAnnotation {
842 range,
843 label: "Natures may not be defined",
844 annotation_type: AnnotationType::Error,
845 }],
846 fold: false,
847 }],
848 opt
849 };
850 let display_list = DisplayList::from(snippet);
851 eprintln!("{}", display_list);
852 }
853 Type::StringTooLong(len) => {
854 let range = (range.start as usize, range.end as usize);
855 let label = format!(
856 "String literals longer than {} characters are not supported",
857 std::u16::MAX
858 );
859 let inline_label = format!("String literal with {} characters", len);
860
861 let snippet = Snippet {
862 title: Some(Annotation {
863 id: None,
864 label: Some(&label),
865 annotation_type: AnnotationType::Error,
866 }),
867 footer,
868 slices: vec![Slice {
869 source: line,
870 line_start: line_number as usize,
871 origin: Some(&*origin),
872 annotations: vec![SourceAnnotation {
873 range,
874 label: &inline_label,
875 annotation_type: AnnotationType::Error,
876 }],
877 fold: false,
878 }],
879 opt,
880 };
881 let display_list = DisplayList::from(snippet);
882 eprintln!("{}", display_list);
883 }
884 Type::Unrecoverable => (),
885 Type::FunctionWithoutBody(name) => {
886 let range = (range.start as usize, range.end as usize);
887 let label = format!("Function {} was delcared without body", name);
888 let snippet = Snippet {
889 title: Some(Annotation {
890 id: None,
891 label: Some(&label),
892 annotation_type: AnnotationType::Error,
893 }),
894 footer,
895 slices: vec![Slice {
896 source: line,
897 line_start: line_number as usize,
898 origin: Some(&*origin),
899 annotations: vec![SourceAnnotation {
900 range,
901 label: "Function body is missing",
902 annotation_type: AnnotationType::Error,
903 }],
904 fold: true,
905 }],
906 opt,
907 };
908 let display_list = DisplayList::from(snippet);
909 eprintln!("{}", display_list);
910 }
911 Type::MissingOrUnexpectedToken {
912 ref expected,
913 expected_at,
914 } => {
915 let (range, expected_at) = if expected_at < self.source.get_start() {
916 let res = source_map.resolve_span_within_line(
917 Span::new(expected_at, self.source.get_end()),
918 translate_lines,
919 );
920 line = res.0;
921 range = res.3;
922 line_number = res.1;
923 (
924 (
925 (self.source.get_start() - expected_at + range.start) as usize,
926 range.end as usize,
927 ),
928 range.start as usize,
929 )
930 } else {
931 (
932 (range.start as usize, range.end as usize),
933 (expected_at - self.source.get_start() + range.start) as usize,
934 )
935 };
936 let label = format!("expected {}", format_list(expected, "'"));
937
938 let snippet = Snippet {
939 title: Some(Annotation {
940 id: None,
941 label: Some("Unexpected Token"),
942 annotation_type: AnnotationType::Error,
943 }),
944 footer,
945 slices: vec![Slice {
946 source: line,
947 line_start: line_number as usize,
948 origin: Some(&*origin),
949 annotations: vec![
950 SourceAnnotation {
951 range,
952 label: "Unexpected Token",
953 annotation_type: AnnotationType::Error,
954 },
955 SourceAnnotation {
956 range: (expected_at, expected_at + 1),
957 label: &label,
958 annotation_type: AnnotationType::Info,
959 },
960 ],
961 fold: false,
962 }],
963 opt,
964 };
965 let display_list = DisplayList::from(snippet);
966 eprintln!("{}", display_list);
967 }
968 Type::TooManyBranchArgs(count) => {
969 let range = (range.start as usize, range.end as usize);
970 let label = format!(
971 "Branch access expected at most 2 arguments but {} were specified",
972 count
973 );
974 let snippet = Snippet {
975 title: Some(Annotation {
976 id: None,
977 label: Some(&label),
978 annotation_type: AnnotationType::Error,
979 }),
980 footer,
981 slices: vec![Slice {
982 source: line,
983 line_start: line_number as usize,
984 origin: Some(&*origin),
985 annotations: vec![SourceAnnotation {
986 range,
987 label: "Unexpected arguemts",
988 annotation_type: AnnotationType::Error,
989 }],
990 fold: false,
991 }],
992 opt,
993 };
994 let display_list = DisplayList::from(snippet);
995 eprintln!("{}", display_list);
996 }
997 };
998 }
999}
1000impl Warning {
1001 #[allow(clippy::too_many_lines)]
1002 pub fn print(&self, source_map: &SourceMap, translate_lines: bool) {
1003 let (line, line_number, substitution_name, range) =
1004 source_map.resolve_span_within_line(self.source, translate_lines);
1005 let (origin, footer) = if let Some(substitution_name) = substitution_name {
1006 (Cow::owned(substitution_name),vec![Annotation{
1007 id: None,
1008 label: Some("This error occurred inside an expansion of a macro or a file. If additional macros or files are included inside this expansion the line information will be inaccurate and the error output might be hard to track if macros are used extensivly. The fully expanded source could give better insight in that case"),
1009 annotation_type: AnnotationType::Note
1010 }])
1011 } else {
1012 (Cow::const_str(source_map.main_file_name), Vec::new())
1013 };
1014 let opt = FormatOptions {
1015 color: true,
1016 anonymized_line_numbers: false,
1017 };
1018
1019 match self.error_type {
1020 WarningType::MacroOverwritten(first_declaration) => {
1021 let range = (range.start as usize, range.end as usize);
1022 let (original_line, original_line_number, _, original_range) =
1023 source_map.resolve_span_within_line(first_declaration, translate_lines);
1024 let original_range = (
1025 original_range.start as usize,
1026 original_range.end as usize,
1027 );
1028 let snippet = Snippet {
1029 title: Some(Annotation {
1030 id: None,
1031 label: Some("Macro overwritten"),
1032 annotation_type: AnnotationType::Warning,
1033 }),
1034 footer,
1035 slices: vec![
1036 Slice {
1037 source: original_line,
1038 line_start: original_line_number as usize,
1039 origin: Some(&*origin),
1040 annotations: vec![SourceAnnotation {
1041 range: original_range,
1042 label: "First_declared here",
1043 annotation_type: AnnotationType::Info,
1044 }],
1045 fold: false,
1046 },
1047 Slice {
1048 source: line,
1049 line_start: line_number as usize,
1050 origin: Some(&*origin),
1051 annotations: vec![SourceAnnotation {
1052 range,
1053 label: "Later overwritten here",
1054 annotation_type: AnnotationType::Warning,
1055 }],
1056 fold: false,
1057 },
1058 ],
1059 opt,
1060 };
1061 let display_list = DisplayList::from(snippet);
1062 eprintln!("{}", display_list);
1063 }
1064 WarningType::AttributeOverwrite(overwritten_ident, overwrite_span) => {
1065 let overwritten_range = (
1066 range.start as usize,
1067 (range.start + overwritten_ident.span.get_end() - self.source.get_start()) as usize,
1068 );
1069 let overwrite_span = overwrite_span.negative_offset(self.source.get_start());
1070 let overwrite_range = (
1071 (range.start + overwrite_span.get_start() ) as usize,
1072 (range.start + overwrite_span.get_end()) as usize,
1073 );
1074 let label = format!(
1075 "Attribute {} was declared multiple times. First value is ignored",
1076 overwritten_ident.name.as_str()
1077 );
1078 let snippet = Snippet {
1079 title: Some(Annotation {
1080 id: None,
1081 label: Some(&label),
1082 annotation_type: AnnotationType::Warning,
1083 }),
1084 footer,
1085 slices: vec![Slice {
1086 source: line,
1087 line_start: line_number as usize,
1088 origin: Some(&*origin),
1089 annotations: vec![
1090 SourceAnnotation {
1091 range: overwrite_range,
1092 label: "overwritten here",
1093 annotation_type: AnnotationType::Warning,
1094 },
1095 SourceAnnotation {
1096 range: overwritten_range,
1097 label: "First declared here",
1098 annotation_type: AnnotationType::Info,
1099 },
1100 ],
1101 fold: false,
1102 }],
1103 opt,
1104 };
1105 let display_list = DisplayList::from(snippet);
1106 eprintln!("{}", display_list);
1107 }
1108 };
1109 }
1110}
1111