diff options
Diffstat (limited to 'crates/ra_syntax/src/validation/byte.rs')
-rw-r--r-- | crates/ra_syntax/src/validation/byte.rs | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/crates/ra_syntax/src/validation/byte.rs b/crates/ra_syntax/src/validation/byte.rs index 3d2806c4e..7baf3c1d7 100644 --- a/crates/ra_syntax/src/validation/byte.rs +++ b/crates/ra_syntax/src/validation/byte.rs | |||
@@ -20,26 +20,7 @@ pub(super) fn validate_byte_node(node: ast::Byte, errors: &mut Vec<SyntaxError>) | |||
20 | len += 1; | 20 | len += 1; |
21 | let text = &literal_text[component.range]; | 21 | let text = &literal_text[component.range]; |
22 | let range = component.range + literal_range.start(); | 22 | let range = component.range + literal_range.start(); |
23 | 23 | validate_byte_component(text, component.kind, range, errors); | |
24 | use self::CharComponentKind::*; | ||
25 | match component.kind { | ||
26 | AsciiEscape => validate_byte_escape(text, range, errors), | ||
27 | AsciiCodeEscape => validate_byte_code_escape(text, range, errors), | ||
28 | UnicodeEscape => errors.push(SyntaxError::new(UnicodeEscapeForbidden, range)), | ||
29 | CodePoint => { | ||
30 | let c = text.chars().next().expect("Code points should be one character long"); | ||
31 | |||
32 | // These bytes must always be escaped | ||
33 | if c == '\t' || c == '\r' || c == '\n' { | ||
34 | errors.push(SyntaxError::new(UnescapedByte, range)); | ||
35 | } | ||
36 | |||
37 | // Only ASCII bytes are allowed | ||
38 | if c > 0x7F as char { | ||
39 | errors.push(SyntaxError::new(ByteOutOfRange, range)); | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | } | 24 | } |
44 | 25 | ||
45 | if !components.has_closing_quote { | 26 | if !components.has_closing_quote { |
@@ -55,6 +36,33 @@ pub(super) fn validate_byte_node(node: ast::Byte, errors: &mut Vec<SyntaxError>) | |||
55 | } | 36 | } |
56 | } | 37 | } |
57 | 38 | ||
39 | pub(super) fn validate_byte_component( | ||
40 | text: &str, | ||
41 | kind: CharComponentKind, | ||
42 | range: TextRange, | ||
43 | errors: &mut Vec<SyntaxError>, | ||
44 | ) { | ||
45 | use self::CharComponentKind::*; | ||
46 | match kind { | ||
47 | AsciiEscape => validate_byte_escape(text, range, errors), | ||
48 | AsciiCodeEscape => validate_byte_code_escape(text, range, errors), | ||
49 | UnicodeEscape => errors.push(SyntaxError::new(UnicodeEscapeForbidden, range)), | ||
50 | CodePoint => { | ||
51 | let c = text.chars().next().expect("Code points should be one character long"); | ||
52 | |||
53 | // These bytes must always be escaped | ||
54 | if c == '\t' || c == '\r' || c == '\n' { | ||
55 | errors.push(SyntaxError::new(UnescapedByte, range)); | ||
56 | } | ||
57 | |||
58 | // Only ASCII bytes are allowed | ||
59 | if c > 0x7F as char { | ||
60 | errors.push(SyntaxError::new(ByteOutOfRange, range)); | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | |||
58 | fn validate_byte_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { | 66 | fn validate_byte_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { |
59 | if text.len() == 1 { | 67 | if text.len() == 1 { |
60 | // Escape sequence consists only of leading `\` | 68 | // Escape sequence consists only of leading `\` |
@@ -141,7 +149,7 @@ mod test { | |||
141 | #[test] | 149 | #[test] |
142 | fn test_valid_byte_escape() { | 150 | fn test_valid_byte_escape() { |
143 | let valid = [ | 151 | let valid = [ |
144 | r"\'", "\"", "\\\\", "\\\"", r"\n", r"\r", r"\t", r"\0", "a", "b", | 152 | r"\'", "\"", "\\\\", "\\\"", r"\n", r"\r", r"\t", r"\0", |
145 | ]; | 153 | ]; |
146 | for c in &valid { | 154 | for c in &valid { |
147 | assert_valid_byte(c); | 155 | assert_valid_byte(c); |