aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/syntax_error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/syntax_error.rs')
-rw-r--r--crates/ra_syntax/src/syntax_error.rs146
1 files changed, 146 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs
new file mode 100644
index 000000000..4ff998090
--- /dev/null
+++ b/crates/ra_syntax/src/syntax_error.rs
@@ -0,0 +1,146 @@
1use std::fmt;
2
3use crate::{TextRange, TextUnit};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct SyntaxError {
7 kind: SyntaxErrorKind,
8 location: Location,
9}
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum Location {
13 Offset(TextUnit),
14 Range(TextRange),
15}
16
17impl Into<Location> for TextUnit {
18 fn into(self) -> Location {
19 Location::Offset(self)
20 }
21}
22
23impl Into<Location> for TextRange {
24 fn into(self) -> Location {
25 Location::Range(self)
26 }
27}
28
29impl SyntaxError {
30 pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError {
31 SyntaxError { kind, location: loc.into() }
32 }
33
34 pub fn kind(&self) -> SyntaxErrorKind {
35 self.kind.clone()
36 }
37
38 pub fn location(&self) -> Location {
39 self.location.clone()
40 }
41
42 pub fn offset(&self) -> TextUnit {
43 match self.location {
44 Location::Offset(offset) => offset,
45 Location::Range(range) => range.start(),
46 }
47 }
48
49 pub fn add_offset(mut self, plus_offset: TextUnit) -> SyntaxError {
50 self.location = match self.location {
51 Location::Range(range) => Location::Range(range + plus_offset),
52 Location::Offset(offset) => Location::Offset(offset + plus_offset),
53 };
54
55 self
56 }
57}
58
59impl fmt::Display for SyntaxError {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 self.kind.fmt(f)
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Hash)]
66pub enum SyntaxErrorKind {
67 ParseError(ParseError),
68 UnescapedCodepoint,
69 EmptyChar,
70 UnclosedChar,
71 OverlongChar,
72 EmptyByte,
73 UnclosedByte,
74 OverlongByte,
75 ByteOutOfRange,
76 UnescapedByte,
77 EmptyByteEscape,
78 InvalidByteEscape,
79 TooShortByteCodeEscape,
80 MalformedByteCodeEscape,
81 UnicodeEscapeForbidden,
82 EmptyAsciiEscape,
83 InvalidAsciiEscape,
84 TooShortAsciiCodeEscape,
85 AsciiCodeEscapeOutOfRange,
86 MalformedAsciiCodeEscape,
87 UnclosedUnicodeEscape,
88 MalformedUnicodeEscape,
89 EmptyUnicodeEcape,
90 OverlongUnicodeEscape,
91 UnicodeEscapeOutOfRange,
92 UnclosedString,
93 InvalidSuffix,
94 InvalidBlockAttr,
95 InvalidMatchInnerAttr,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Hash)]
99pub struct ParseError(pub String);
100
101impl fmt::Display for SyntaxErrorKind {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 use self::SyntaxErrorKind::*;
104 match self {
105 UnescapedCodepoint => write!(f, "This codepoint should always be escaped"),
106 EmptyAsciiEscape => write!(f, "Empty escape sequence"),
107 InvalidAsciiEscape => write!(f, "Invalid escape sequence"),
108 EmptyChar => write!(f, "Empty char literal"),
109 UnclosedChar => write!(f, "Unclosed char literal"),
110 OverlongChar => write!(f, "Char literal should be one character long"),
111 EmptyByte => write!(f, "Empty byte literal"),
112 UnclosedByte => write!(f, "Unclosed byte literal"),
113 OverlongByte => write!(f, "Byte literal should be one character long"),
114 ByteOutOfRange => write!(f, "Byte should be a valid ASCII character"),
115 UnescapedByte => write!(f, "This byte should always be escaped"),
116 EmptyByteEscape => write!(f, "Empty escape sequence"),
117 InvalidByteEscape => write!(f, "Invalid escape sequence"),
118 TooShortByteCodeEscape => write!(f, "Escape sequence should have two digits"),
119 MalformedByteCodeEscape => write!(f, "Escape sequence should be a hexadecimal number"),
120 UnicodeEscapeForbidden => {
121 write!(f, "Unicode escapes are not allowed in byte literals or byte strings")
122 }
123 TooShortAsciiCodeEscape => write!(f, "Escape sequence should have two digits"),
124 AsciiCodeEscapeOutOfRange => {
125 write!(f, "Escape sequence should be between \\x00 and \\x7F")
126 }
127 MalformedAsciiCodeEscape => write!(f, "Escape sequence should be a hexadecimal number"),
128 UnclosedUnicodeEscape => write!(f, "Missing `}}`"),
129 MalformedUnicodeEscape => write!(f, "Malformed unicode escape sequence"),
130 EmptyUnicodeEcape => write!(f, "Empty unicode escape sequence"),
131 OverlongUnicodeEscape => {
132 write!(f, "Unicode escape sequence should have at most 6 digits")
133 }
134 UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
135 UnclosedString => write!(f, "Unclosed string literal"),
136 InvalidSuffix => write!(f, "Invalid literal suffix"),
137 InvalidBlockAttr => {
138 write!(f, "A block in this position cannot accept inner attributes")
139 }
140 InvalidMatchInnerAttr => {
141 write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression")
142 }
143 ParseError(msg) => write!(f, "{}", msg.0),
144 }
145 }
146}