aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/src/string_lexing/parser.rs10
-rw-r--r--crates/ra_syntax/src/string_lexing/string.rs14
-rw-r--r--crates/ra_syntax/src/validation/byte.rs4
-rw-r--r--crates/ra_syntax/src/validation/byte_string.rs4
-rw-r--r--crates/ra_syntax/src/validation/char.rs4
-rw-r--r--crates/ra_syntax/src/validation/string.rs4
-rw-r--r--crates/ra_syntax/src/yellow/syntax_error.rs2
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 @@
1use crate::string_lexing::{ 1use crate::{
2 TextRange,
3 string_lexing::{
2 parser::Parser, 4 parser::Parser,
3 StringComponent, 5 StringComponent,
4}; 6}};
5 7
6pub fn parse_string_literal(src: &str) -> StringComponentIterator { 8pub 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 {
42pub struct StringComponentIterator<'a> { 48pub 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 }