diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_syntax/src/string_lexing/parser.rs | 10 | ||||
-rw-r--r-- | crates/ra_syntax/src/string_lexing/string.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation/byte.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation/byte_string.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation/char.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation/string.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/syntax_error.rs | 2 |
7 files changed, 40 insertions, 2 deletions
diff --git a/crates/ra_syntax/src/string_lexing/parser.rs b/crates/ra_syntax/src/string_lexing/parser.rs index 13f3db889..14c6015c2 100644 --- a/crates/ra_syntax/src/string_lexing/parser.rs +++ b/crates/ra_syntax/src/string_lexing/parser.rs | |||
@@ -139,6 +139,16 @@ impl<'a> Parser<'a> { | |||
139 | )) | 139 | )) |
140 | } | 140 | } |
141 | } | 141 | } |
142 | |||
143 | pub fn parse_suffix(&mut self) -> Option<TextRange> { | ||
144 | let start = self.get_pos(); | ||
145 | let _ = self.peek()?; | ||
146 | while let Some(_) = self.peek() { | ||
147 | self.advance(); | ||
148 | } | ||
149 | let end = self.get_pos(); | ||
150 | Some(TextRange::from_to(start, end)) | ||
151 | } | ||
142 | } | 152 | } |
143 | 153 | ||
144 | #[derive(Debug, Eq, PartialEq, Clone)] | 154 | #[derive(Debug, Eq, PartialEq, Clone)] |
diff --git a/crates/ra_syntax/src/string_lexing/string.rs b/crates/ra_syntax/src/string_lexing/string.rs index 7476fea13..064f08544 100644 --- a/crates/ra_syntax/src/string_lexing/string.rs +++ b/crates/ra_syntax/src/string_lexing/string.rs | |||
@@ -1,12 +1,15 @@ | |||
1 | use crate::string_lexing::{ | 1 | use crate::{ |
2 | TextRange, | ||
3 | string_lexing::{ | ||
2 | parser::Parser, | 4 | parser::Parser, |
3 | StringComponent, | 5 | StringComponent, |
4 | }; | 6 | }}; |
5 | 7 | ||
6 | pub fn parse_string_literal(src: &str) -> StringComponentIterator { | 8 | pub fn parse_string_literal(src: &str) -> StringComponentIterator { |
7 | StringComponentIterator { | 9 | StringComponentIterator { |
8 | parser: Parser::new(src, b'"'), | 10 | parser: Parser::new(src, b'"'), |
9 | has_closing_quote: false, | 11 | has_closing_quote: false, |
12 | suffix: None, | ||
10 | prefix: None, | 13 | prefix: None, |
11 | quote: b'"', | 14 | quote: b'"', |
12 | } | 15 | } |
@@ -16,6 +19,7 @@ pub fn parse_byte_string_literal(src: &str) -> StringComponentIterator { | |||
16 | StringComponentIterator { | 19 | StringComponentIterator { |
17 | parser: Parser::new(src, b'"'), | 20 | parser: Parser::new(src, b'"'), |
18 | has_closing_quote: false, | 21 | has_closing_quote: false, |
22 | suffix: None, | ||
19 | prefix: Some(b'b'), | 23 | prefix: Some(b'b'), |
20 | quote: b'"', | 24 | quote: b'"', |
21 | } | 25 | } |
@@ -25,6 +29,7 @@ pub fn parse_char_literal(src: &str) -> StringComponentIterator { | |||
25 | StringComponentIterator { | 29 | StringComponentIterator { |
26 | parser: Parser::new(src, b'\''), | 30 | parser: Parser::new(src, b'\''), |
27 | has_closing_quote: false, | 31 | has_closing_quote: false, |
32 | suffix: None, | ||
28 | prefix: None, | 33 | prefix: None, |
29 | quote: b'\'', | 34 | quote: b'\'', |
30 | } | 35 | } |
@@ -34,6 +39,7 @@ pub fn parse_byte_literal(src: &str) -> StringComponentIterator { | |||
34 | StringComponentIterator { | 39 | StringComponentIterator { |
35 | parser: Parser::new(src, b'\''), | 40 | parser: Parser::new(src, b'\''), |
36 | has_closing_quote: false, | 41 | has_closing_quote: false, |
42 | suffix: None, | ||
37 | prefix: Some(b'b'), | 43 | prefix: Some(b'b'), |
38 | quote: b'\'', | 44 | quote: b'\'', |
39 | } | 45 | } |
@@ -42,6 +48,7 @@ pub fn parse_byte_literal(src: &str) -> StringComponentIterator { | |||
42 | pub struct StringComponentIterator<'a> { | 48 | pub struct StringComponentIterator<'a> { |
43 | parser: Parser<'a>, | 49 | parser: Parser<'a>, |
44 | pub has_closing_quote: bool, | 50 | pub has_closing_quote: bool, |
51 | pub suffix: Option<TextRange>, | ||
45 | prefix: Option<u8>, | 52 | prefix: Option<u8>, |
46 | quote: u8, | 53 | quote: u8, |
47 | } | 54 | } |
@@ -72,6 +79,9 @@ impl<'a> Iterator for StringComponentIterator<'a> { | |||
72 | if self.parser.peek() == Some(self.quote as char) { | 79 | if self.parser.peek() == Some(self.quote as char) { |
73 | self.parser.advance(); | 80 | self.parser.advance(); |
74 | self.has_closing_quote = true; | 81 | self.has_closing_quote = true; |
82 | if let Some(range) = self.parser.parse_suffix() { | ||
83 | self.suffix = Some(range); | ||
84 | } | ||
75 | } | 85 | } |
76 | 86 | ||
77 | assert!( | 87 | assert!( |
diff --git a/crates/ra_syntax/src/validation/byte.rs b/crates/ra_syntax/src/validation/byte.rs index e3603e761..2f9b7fac7 100644 --- a/crates/ra_syntax/src/validation/byte.rs +++ b/crates/ra_syntax/src/validation/byte.rs | |||
@@ -27,6 +27,10 @@ pub(super) fn validate_byte_node(node: ast::Byte, errors: &mut Vec<SyntaxError>) | |||
27 | errors.push(SyntaxError::new(UnclosedByte, literal_range)); | 27 | errors.push(SyntaxError::new(UnclosedByte, literal_range)); |
28 | } | 28 | } |
29 | 29 | ||
30 | if let Some(range) = components.suffix { | ||
31 | errors.push(SyntaxError::new(InvalidSuffix, range)); | ||
32 | } | ||
33 | |||
30 | if len == 0 { | 34 | if len == 0 { |
31 | errors.push(SyntaxError::new(EmptyByte, literal_range)); | 35 | errors.push(SyntaxError::new(EmptyByte, literal_range)); |
32 | } | 36 | } |
diff --git a/crates/ra_syntax/src/validation/byte_string.rs b/crates/ra_syntax/src/validation/byte_string.rs index 2f98472f4..bf4c934a7 100644 --- a/crates/ra_syntax/src/validation/byte_string.rs +++ b/crates/ra_syntax/src/validation/byte_string.rs | |||
@@ -32,6 +32,10 @@ pub(crate) fn validate_byte_string_node(node: ast::ByteString, errors: &mut Vec< | |||
32 | if !components.has_closing_quote { | 32 | if !components.has_closing_quote { |
33 | errors.push(SyntaxError::new(UnclosedString, literal_range)); | 33 | errors.push(SyntaxError::new(UnclosedString, literal_range)); |
34 | } | 34 | } |
35 | |||
36 | if let Some(range) = components.suffix { | ||
37 | errors.push(SyntaxError::new(InvalidSuffix, range)); | ||
38 | } | ||
35 | } | 39 | } |
36 | 40 | ||
37 | #[cfg(test)] | 41 | #[cfg(test)] |
diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs index deb5b0a9e..50184aaf8 100644 --- a/crates/ra_syntax/src/validation/char.rs +++ b/crates/ra_syntax/src/validation/char.rs | |||
@@ -30,6 +30,10 @@ pub(super) fn validate_char_node(node: ast::Char, errors: &mut Vec<SyntaxError>) | |||
30 | errors.push(SyntaxError::new(UnclosedChar, literal_range)); | 30 | errors.push(SyntaxError::new(UnclosedChar, literal_range)); |
31 | } | 31 | } |
32 | 32 | ||
33 | if let Some(range) = components.suffix { | ||
34 | errors.push(SyntaxError::new(InvalidSuffix, range)); | ||
35 | } | ||
36 | |||
33 | if len == 0 { | 37 | if len == 0 { |
34 | errors.push(SyntaxError::new(EmptyChar, literal_range)); | 38 | errors.push(SyntaxError::new(EmptyChar, literal_range)); |
35 | } | 39 | } |
diff --git a/crates/ra_syntax/src/validation/string.rs b/crates/ra_syntax/src/validation/string.rs index 456180ab6..ff1fb6edc 100644 --- a/crates/ra_syntax/src/validation/string.rs +++ b/crates/ra_syntax/src/validation/string.rs | |||
@@ -27,6 +27,10 @@ pub(crate) fn validate_string_node(node: ast::String, errors: &mut Vec<SyntaxErr | |||
27 | if !components.has_closing_quote { | 27 | if !components.has_closing_quote { |
28 | errors.push(SyntaxError::new(UnclosedString, literal_range)); | 28 | errors.push(SyntaxError::new(UnclosedString, literal_range)); |
29 | } | 29 | } |
30 | |||
31 | if let Some(range) = components.suffix { | ||
32 | errors.push(SyntaxError::new(InvalidSuffix, range)); | ||
33 | } | ||
30 | } | 34 | } |
31 | 35 | ||
32 | #[cfg(test)] | 36 | #[cfg(test)] |
diff --git a/crates/ra_syntax/src/yellow/syntax_error.rs b/crates/ra_syntax/src/yellow/syntax_error.rs index c32ee650d..534f3511e 100644 --- a/crates/ra_syntax/src/yellow/syntax_error.rs +++ b/crates/ra_syntax/src/yellow/syntax_error.rs | |||
@@ -93,6 +93,7 @@ pub enum SyntaxErrorKind { | |||
93 | OverlongUnicodeEscape, | 93 | OverlongUnicodeEscape, |
94 | UnicodeEscapeOutOfRange, | 94 | UnicodeEscapeOutOfRange, |
95 | UnclosedString, | 95 | UnclosedString, |
96 | InvalidSuffix, | ||
96 | } | 97 | } |
97 | 98 | ||
98 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 99 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -134,6 +135,7 @@ impl fmt::Display for SyntaxErrorKind { | |||
134 | } | 135 | } |
135 | UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"), | 136 | UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"), |
136 | UnclosedString => write!(f, "Unclosed string literal"), | 137 | UnclosedString => write!(f, "Unclosed string literal"), |
138 | InvalidSuffix => write!(f, "Invalid literal suffix"), | ||
137 | ParseError(msg) => write!(f, "{}", msg.0), | 139 | ParseError(msg) => write!(f, "{}", msg.0), |
138 | } | 140 | } |
139 | } | 141 | } |