open_vaf/parser/
error.rs

1//  * ******************************************************************************************
2//  * Copyright (c) 2019 Pascal Kuthe. This file is part of the OpenVAF project.
3//  * It is subject to the license terms in the LICENSE file found in the top-level directory
4//  *  of this distribution and at  https://gitlab.com/DSPOM/OpenVAF/blob/master/LICENSE.
5//  *  No part of OpenVAF, including this file, may be copied, modified, propagated, or
6//  *  distributed except according to the terms contained in the LICENSE file.
7//  * *******************************************************************************************
8
9use 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    //Parser
29    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    //Preprocessor
44    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    //General
61    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, // TODO remove this. Only part of VerilogAMS not VerilogA
90    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        // TODO move exampels to webpage
129        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