goscript_parser/
errors.rs1use super::position;
2use std::cell::{Ref, RefCell};
3use std::fmt;
4use std::rc::Rc;
5
6#[derive(Clone, Debug)]
7pub struct Error {
8 pub pos: position::Position,
9 pub msg: String,
10 pub soft: bool,
11 pub by_parser: bool, order: usize, }
14
15impl fmt::Display for Error {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 let p = if self.by_parser { "[Parser]" } else { "[TC]" };
18 write!(f, "{} {} {}\n", p, self.pos, self.msg)?;
19 Ok(())
20 }
21}
22
23#[derive(Clone, Debug)]
24pub struct ErrorList {
25 errors: Rc<RefCell<Vec<Error>>>,
26}
27
28impl fmt::Display for ErrorList {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(f, "Result: {} errors\n", self.errors.borrow().len())?;
31 for e in self.errors.borrow().iter() {
32 e.fmt(f)?;
33 }
34 Ok(())
35 }
36}
37
38impl ErrorList {
39 pub fn new() -> ErrorList {
40 ErrorList {
41 errors: Rc::new(RefCell::new(vec![])),
42 }
43 }
44
45 pub fn add(&self, p: position::Position, msg: String, soft: bool, by_parser: bool) {
46 let order = if msg.starts_with('\t') {
47 self.errors
48 .borrow()
49 .iter()
50 .rev()
51 .find(|x| !x.msg.starts_with('\t'))
52 .unwrap()
53 .pos
54 .offset
55 } else {
56 p.offset
57 };
58 self.errors.borrow_mut().push(Error {
59 pos: p,
60 msg: msg,
61 soft: soft,
62 by_parser: by_parser,
63 order: order,
64 });
65 }
66
67 pub fn len(&self) -> usize {
68 self.errors.borrow().len()
69 }
70
71 pub fn sort(&mut self) {
72 self.errors.borrow_mut().sort_by_key(|e| e.order);
73 }
74
75 pub fn borrow(&self) -> Ref<Vec<Error>> {
76 self.errors.borrow()
77 }
78}
79
80#[derive(Clone, Debug)]
81pub struct FilePosErrors<'a> {
82 file: &'a position::File,
83 elist: &'a ErrorList,
84}
85
86impl<'a> FilePosErrors<'a> {
87 pub fn new(file: &'a position::File, elist: &'a ErrorList) -> FilePosErrors<'a> {
88 FilePosErrors {
89 file: file,
90 elist: elist,
91 }
92 }
93
94 pub fn add(&self, pos: position::Pos, msg: String, soft: bool) {
95 let p = self.file.position(pos);
96 self.elist.add(p, msg, soft, false);
97 }
98
99 pub fn add_str(&self, pos: position::Pos, s: &str, soft: bool) {
100 self.add(pos, s.to_string(), soft);
101 }
102
103 pub fn parser_add(&self, pos: position::Pos, msg: String) {
104 let p = self.file.position(pos);
105 self.elist.add(p, msg, false, true);
106 }
107
108 pub fn parser_add_str(&self, pos: position::Pos, s: &str) {
109 self.parser_add(pos, s.to_string());
110 }
111}