]> git.lizzy.rs Git - rust.git/commitdiff
support literal suffixes
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 27 Dec 2018 12:03:18 +0000 (15:03 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 27 Dec 2018 12:03:18 +0000 (15:03 +0300)
crates/ra_syntax/src/string_lexing/parser.rs
crates/ra_syntax/src/string_lexing/string.rs
crates/ra_syntax/src/validation/byte.rs
crates/ra_syntax/src/validation/byte_string.rs
crates/ra_syntax/src/validation/char.rs
crates/ra_syntax/src/validation/string.rs
crates/ra_syntax/src/yellow/syntax_error.rs

index 13f3db8899b79d7cbd817bfd4b41d9547cf7909f..14c6015c2a9168d1e245a84c05587b4a6a3b586a 100644 (file)
@@ -139,6 +139,16 @@ pub fn parse_component(&mut self) -> Option<StringComponent> {
             ))
         }
     }
+
+    pub fn parse_suffix(&mut self) -> Option<TextRange> {
+        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)]
index 7476fea13ca3e759d821f1ae489c04b17a0e6f7d..064f085447fef857552f03c9a6b204295dd5c74c 100644 (file)
@@ -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<TextRange>,
     prefix: Option<u8>,
     quote: u8,
 }
@@ -72,6 +79,9 @@ fn next(&mut self) -> Option<StringComponent> {
         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!(
index e3603e7616ef6d3b13406f68e71820b42a698ef0..2f9b7fac7db541bbac8d5c9bb267dfbeed3cfc97 100644 (file)
@@ -27,6 +27,10 @@ pub(super) fn validate_byte_node(node: ast::Byte, errors: &mut Vec<SyntaxError>)
         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));
     }
index 2f98472f47d92eb781a20ba339c74351d5c38e11..bf4c934a7e7d34b137fe09547522fba86950a786 100644 (file)
@@ -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)]
index deb5b0a9e1ce2c2fffd76d8b8474052cbae57fce..50184aaf8151d1667032b3cd323c66e8ccc75552 100644 (file)
@@ -30,6 +30,10 @@ pub(super) fn validate_char_node(node: ast::Char, errors: &mut Vec<SyntaxError>)
         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));
     }
index 456180ab66eba71b3c28afb8477cc69943a0c401..ff1fb6edc4e621996030967ece896cbe9233e4c3 100644 (file)
@@ -27,6 +27,10 @@ pub(crate) fn validate_string_node(node: ast::String, errors: &mut Vec<SyntaxErr
     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)]
index c32ee650dd880ea75bd65694e94ef2ba7130e710..534f3511e3f05a022fbdcb67cee75932dafd9f35 100644 (file)
@@ -93,6 +93,7 @@ pub enum SyntaxErrorKind {
     OverlongUnicodeEscape,
     UnicodeEscapeOutOfRange,
     UnclosedString,
+    InvalidSuffix,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -134,6 +135,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
             UnicodeEscapeOutOfRange => 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),
         }
     }