diff options
Diffstat (limited to 'crates/ra_syntax/src/yellow/syntax_error.rs')
-rw-r--r-- | crates/ra_syntax/src/yellow/syntax_error.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/yellow/syntax_error.rs b/crates/ra_syntax/src/yellow/syntax_error.rs new file mode 100644 index 000000000..f3df6bc15 --- /dev/null +++ b/crates/ra_syntax/src/yellow/syntax_error.rs | |||
@@ -0,0 +1,89 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | use crate::{TextRange, TextUnit}; | ||
4 | |||
5 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
6 | pub struct SyntaxError { | ||
7 | kind: SyntaxErrorKind, | ||
8 | location: Location, | ||
9 | } | ||
10 | |||
11 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
12 | pub enum Location { | ||
13 | Offset(TextUnit), | ||
14 | Range(TextRange), | ||
15 | } | ||
16 | |||
17 | impl Into<Location> for TextUnit { | ||
18 | fn into(self) -> Location { | ||
19 | Location::Offset(self) | ||
20 | } | ||
21 | } | ||
22 | |||
23 | impl Into<Location> for TextRange { | ||
24 | fn into(self) -> Location { | ||
25 | Location::Range(self) | ||
26 | } | ||
27 | } | ||
28 | |||
29 | impl SyntaxError { | ||
30 | pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { | ||
31 | SyntaxError { | ||
32 | kind, | ||
33 | location: loc.into(), | ||
34 | } | ||
35 | } | ||
36 | |||
37 | pub fn location(&self) -> Location { | ||
38 | self.location.clone() | ||
39 | } | ||
40 | |||
41 | pub fn offset(&self) -> TextUnit { | ||
42 | match self.location { | ||
43 | Location::Offset(offset) => offset, | ||
44 | Location::Range(range) => range.start(), | ||
45 | } | ||
46 | } | ||
47 | |||
48 | pub fn add_offset(mut self, plus_offset: TextUnit) -> SyntaxError { | ||
49 | self.location = match self.location { | ||
50 | Location::Range(range) => Location::Range(range + plus_offset), | ||
51 | Location::Offset(offset) => Location::Offset(offset + plus_offset), | ||
52 | }; | ||
53 | |||
54 | self | ||
55 | } | ||
56 | } | ||
57 | |||
58 | impl fmt::Display for SyntaxError { | ||
59 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
60 | self.kind.fmt(f) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
65 | pub enum SyntaxErrorKind { | ||
66 | ParseError(ParseError), | ||
67 | EmptyChar, | ||
68 | UnclosedChar, | ||
69 | LongChar, | ||
70 | EmptyAsciiEscape, | ||
71 | InvalidAsciiEscape, | ||
72 | } | ||
73 | |||
74 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
75 | pub struct ParseError(pub String); | ||
76 | |||
77 | impl fmt::Display for SyntaxErrorKind { | ||
78 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
79 | use self::SyntaxErrorKind::*; | ||
80 | match self { | ||
81 | EmptyAsciiEscape => write!(f, "Empty escape sequence"), | ||
82 | InvalidAsciiEscape => write!(f, "Invalid escape sequence"), | ||
83 | EmptyChar => write!(f, "Empty char literal"), | ||
84 | UnclosedChar => write!(f, "Unclosed char literal"), | ||
85 | LongChar => write!(f, "Char literal should be one character long"), | ||
86 | ParseError(msg) => write!(f, "{}", msg.0), | ||
87 | } | ||
88 | } | ||
89 | } | ||