about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJulian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com>2020-05-13 09:52:01 +0200
committerJulian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com>2020-05-13 09:52:01 +0200
commit18cc63d693a3a1d130ba533994c895b56fed3769 (patch)
treef98e9b155f0c9469db3cd14c629a348aaa3be813
parent1be5d1eabb957c8b0bd0f4564a5f7c8bef1826bb (diff)
downloadrust-18cc63d693a3a1d130ba533994c895b56fed3769.tar.gz
rust-18cc63d693a3a1d130ba533994c895b56fed3769.zip
Unified `validate_{byte,str,raw_str,raw_byte_str}_escape` methods into one method `validate_literal_escape` with a mode argument.
This enables simplifying the `match` in `cook_lexer_literal()`
and it eliminates 90 lines of repetition :)
-rw-r--r--src/librustc_parse/lexer/mod.rs152
1 files changed, 30 insertions, 122 deletions
diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs
index f676a34a1d1..1d67d6de4da 100644
--- a/src/librustc_parse/lexer/mod.rs
+++ b/src/librustc_parse/lexer/mod.rs
@@ -15,6 +15,7 @@ mod tokentrees;
 mod unescape_error_reporting;
 mod unicode_chars;
 
+use rustc_lexer::unescape::Mode;
 use unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 #[derive(Clone, Debug)]
@@ -326,38 +327,27 @@ impl<'a> StringReader<'a> {
         suffix_start: BytePos,
         kind: rustc_lexer::LiteralKind,
     ) -> (token::LitKind, Symbol) {
-        match kind {
+        // prefix means `"` or `br"` or `r###"`, ...
+        let (lit_kind, mode, prefix_len, postfix_len) = match kind {
             rustc_lexer::LiteralKind::Char { terminated } => {
                 if !terminated {
                     self.fatal_span_(start, suffix_start, "unterminated character literal").raise()
                 }
-                let content_start = start + BytePos(1);
-                let content_end = suffix_start - BytePos(1);
-                self.validate_char_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::Char, id)
+                (token::Char, Mode::Char, 1, 1) // ' '
             }
             rustc_lexer::LiteralKind::Byte { terminated } => {
                 if !terminated {
                     self.fatal_span_(start + BytePos(1), suffix_start, "unterminated byte constant")
                         .raise()
                 }
-                let content_start = start + BytePos(2);
-                let content_end = suffix_start - BytePos(1);
-                self.validate_byte_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::Byte, id)
+                (token::Byte, Mode::Byte, 2, 1) // b' '
             }
             rustc_lexer::LiteralKind::Str { terminated } => {
                 if !terminated {
                     self.fatal_span_(start, suffix_start, "unterminated double quote string")
                         .raise()
                 }
-                let content_start = start + BytePos(1);
-                let content_end = suffix_start - BytePos(1);
-                self.validate_str_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::Str, id)
+                (token::Str, Mode::Str, 1, 1) // " "
             }
             rustc_lexer::LiteralKind::ByteStr { terminated } => {
                 if !terminated {
@@ -368,42 +358,28 @@ impl<'a> StringReader<'a> {
                     )
                     .raise()
                 }
-                let content_start = start + BytePos(2);
-                let content_end = suffix_start - BytePos(1);
-                self.validate_byte_str_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::ByteStr, id)
+                (token::ByteStr, Mode::ByteStr, 2, 1) // b" "
             }
             rustc_lexer::LiteralKind::RawStr(unvalidated_raw_str) => {
                 let valid_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
                 let n_hashes = valid_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
-
-                let content_start = start + BytePos(2 + n);
-                let content_end = suffix_start - BytePos(1 + n);
-                self.validate_raw_str_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::StrRaw(n_hashes), id)
+                (token::StrRaw(n_hashes), Mode::RawStr, 2 + n, 1 + n) // r##" "##
             }
             rustc_lexer::LiteralKind::RawByteStr(unvalidated_raw_str) => {
                 let validated_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
                 let n_hashes = validated_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
-
-                let content_start = start + BytePos(3 + n);
-                let content_end = suffix_start - BytePos(1 + n);
-                self.validate_raw_byte_str_escape(content_start, content_end);
-                let id = self.symbol_from_to(content_start, content_end);
-                (token::ByteStrRaw(n_hashes), id)
+                (token::ByteStrRaw(n_hashes), Mode::RawByteStr, 3 + n, 1 + n) // br##" "##
             }
             rustc_lexer::LiteralKind::Int { base, empty_int } => {
-                if empty_int {
+                return if empty_int {
                     self.err_span_(start, suffix_start, "no valid digits found for number");
                     (token::Integer, sym::integer(0))
                 } else {
                     self.validate_int_literal(base, start, suffix_start);
                     (token::Integer, self.symbol_from_to(start, suffix_start))
-                }
+                };
             }
             rustc_lexer::LiteralKind::Float { base, empty_exponent } => {
                 if empty_exponent {
@@ -431,9 +407,14 @@ impl<'a> StringReader<'a> {
                 }
 
                 let id = self.symbol_from_to(start, suffix_start);
-                (token::Float, id)
+                return (token::Float, id);
             }
-        }
+        };
+        let content_start = start + BytePos(prefix_len);
+        let content_end = suffix_start - BytePos(postfix_len);
+        let id = self.symbol_from_to(content_start, content_end);
+        self.validate_literal_escape(mode, content_start, content_end);
+        return (lit_kind, id);
     }
 
     #[inline]
@@ -555,96 +536,23 @@ impl<'a> StringReader<'a> {
         .raise();
     }
 
-    fn validate_char_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        if let Err((off, err)) = unescape::unescape_char(lit) {
-            emit_unescape_error(
-                &self.sess.span_diagnostic,
-                lit,
-                self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                unescape::Mode::Char,
-                0..off,
-                err,
-            )
-        }
-    }
-
-    fn validate_byte_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        if let Err((off, err)) = unescape::unescape_byte(lit) {
-            emit_unescape_error(
-                &self.sess.span_diagnostic,
-                lit,
-                self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                unescape::Mode::Byte,
-                0..off,
-                err,
-            )
-        }
-    }
-
-    fn validate_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        unescape::unescape_str(lit, &mut |range, c| {
-            if let Err(err) = c {
+    fn validate_literal_escape(&self, mode: Mode, content_start: BytePos, content_end: BytePos) {
+        let lit_content = self.str_from_to(content_start, content_end);
+        unescape::unescape_literal(lit_content, mode, &mut |range, result| {
+            // Here we only check for errors. The actual unescaping is done later.
+            if let Err(err) = result {
+                let span_with_quotes =
+                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1));
                 emit_unescape_error(
                     &self.sess.span_diagnostic,
-                    lit,
-                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                    unescape::Mode::Str,
+                    lit_content,
+                    span_with_quotes,
+                    mode,
                     range,
                     err,
-                )
-            }
-        })
-    }
-
-    fn validate_raw_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        unescape::unescape_raw_str(lit, &mut |range, c| {
-            if let Err(err) = c {
-                emit_unescape_error(
-                    &self.sess.span_diagnostic,
-                    lit,
-                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                    unescape::Mode::Str,
-                    range,
-                    err,
-                )
-            }
-        })
-    }
-
-    fn validate_raw_byte_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        unescape::unescape_raw_byte_str(lit, &mut |range, c| {
-            if let Err(err) = c {
-                emit_unescape_error(
-                    &self.sess.span_diagnostic,
-                    lit,
-                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                    unescape::Mode::ByteStr,
-                    range,
-                    err,
-                )
-            }
-        })
-    }
-
-    fn validate_byte_str_escape(&self, content_start: BytePos, content_end: BytePos) {
-        let lit = self.str_from_to(content_start, content_end);
-        unescape::unescape_byte_str(lit, &mut |range, c| {
-            if let Err(err) = c {
-                emit_unescape_error(
-                    &self.sess.span_diagnostic,
-                    lit,
-                    self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)),
-                    unescape::Mode::ByteStr,
-                    range,
-                    err,
-                )
+                );
             }
-        })
+        });
     }
 
     fn validate_int_literal(&self, base: Base, content_start: BytePos, content_end: BytePos) {