diff options
| author | Julian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com> | 2020-05-13 09:52:01 +0200 |
|---|---|---|
| committer | Julian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com> | 2020-05-13 09:52:01 +0200 |
| commit | 18cc63d693a3a1d130ba533994c895b56fed3769 (patch) | |
| tree | f98e9b155f0c9469db3cd14c629a348aaa3be813 | |
| parent | 1be5d1eabb957c8b0bd0f4564a5f7c8bef1826bb (diff) | |
| download | rust-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.rs | 152 |
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) { |
