diff --git a/crates/ra_syntax/src/string_lexing/parser.rs b/crates/ra_syntax/src/string_lexing/parser.rs index 13f3db8899b..14c6015c2a9 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> { )) } } + + pub fn parse_suffix(&mut self) -> Option { + let start = self.get_pos(); + let _ = self.peek()?; + while let Some(_) = self.peek() { + self.advance(); + } + let end = self.get_pos(); + Some(TextRange::from_to(start, end)) + } } #[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 7476fea13ca..064f085447f 100644 --- a/crates/ra_syntax/src/string_lexing/string.rs +++ b/crates/ra_syntax/src/string_lexing/string.rs @@ -1,12 +1,15 @@ -use crate::string_lexing::{ +use crate::{ + TextRange, + string_lexing::{ parser::Parser, StringComponent, -}; +}}; pub fn parse_string_literal(src: &str) -> StringComponentIterator { StringComponentIterator { parser: Parser::new(src, b'"'), has_closing_quote: false, + suffix: None, prefix: None, quote: b'"', } @@ -16,6 +19,7 @@ pub fn parse_byte_string_literal(src: &str) -> StringComponentIterator { StringComponentIterator { parser: Parser::new(src, b'"'), has_closing_quote: false, + suffix: None, prefix: Some(b'b'), quote: b'"', } @@ -25,6 +29,7 @@ pub fn parse_char_literal(src: &str) -> StringComponentIterator { StringComponentIterator { parser: Parser::new(src, b'\''), has_closing_quote: false, + suffix: None, prefix: None, quote: b'\'', } @@ -34,6 +39,7 @@ pub fn parse_byte_literal(src: &str) -> StringComponentIterator { StringComponentIterator { parser: Parser::new(src, b'\''), has_closing_quote: false, + suffix: None, prefix: Some(b'b'), quote: b'\'', } @@ -42,6 +48,7 @@ pub fn parse_byte_literal(src: &str) -> StringComponentIterator { pub struct StringComponentIterator<'a> { parser: Parser<'a>, pub has_closing_quote: bool, + pub suffix: Option, prefix: Option, quote: u8, } @@ -72,6 +79,9 @@ impl<'a> Iterator for StringComponentIterator<'a> { if self.parser.peek() == Some(self.quote as char) { self.parser.advance(); self.has_closing_quote = true; + if let Some(range) = self.parser.parse_suffix() { + self.suffix = Some(range); + } } assert!( diff --git a/crates/ra_syntax/src/validation/byte.rs b/crates/ra_syntax/src/validation/byte.rs index e3603e7616e..2f9b7fac7db 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) errors.push(SyntaxError::new(UnclosedByte, literal_range)); } + if let Some(range) = components.suffix { + errors.push(SyntaxError::new(InvalidSuffix, range)); + } + if len == 0 { errors.push(SyntaxError::new(EmptyByte, literal_range)); } diff --git a/crates/ra_syntax/src/validation/byte_string.rs b/crates/ra_syntax/src/validation/byte_string.rs index 2f98472f47d..bf4c934a7e7 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< if !components.has_closing_quote { errors.push(SyntaxError::new(UnclosedString, literal_range)); } + + if let Some(range) = components.suffix { + errors.push(SyntaxError::new(InvalidSuffix, range)); + } } #[cfg(test)] diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs index deb5b0a9e1c..50184aaf815 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) errors.push(SyntaxError::new(UnclosedChar, literal_range)); } + if let Some(range) = components.suffix { + errors.push(SyntaxError::new(InvalidSuffix, range)); + } + if len == 0 { errors.push(SyntaxError::new(EmptyChar, literal_range)); } diff --git a/crates/ra_syntax/src/validation/string.rs b/crates/ra_syntax/src/validation/string.rs index 456180ab66e..ff1fb6edc4e 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 write!(f, "Unicode escape code should be at most 0x10FFFF"), UnclosedString => write!(f, "Unclosed string literal"), + InvalidSuffix => write!(f, "Invalid literal suffix"), ParseError(msg) => write!(f, "{}", msg.0), } }