Chromium Code Reviews| Index: src/parsing/scanner.h |
| diff --git a/src/parsing/scanner.h b/src/parsing/scanner.h |
| index 075b9ca6b2ba0c1d9468e7eef7e3598c85a5cd36..3ff7a3c6d76241807fd17842cb735424584c9f47 100644 |
| --- a/src/parsing/scanner.h |
| +++ b/src/parsing/scanner.h |
| @@ -209,10 +209,27 @@ class Scanner { |
| // (the token last returned by Next()). |
| Location location() const { return current_.location; } |
| + // This error is specifically an invalid hex or unicode escape sequence. |
| bool has_error() const { return scanner_error_ != MessageTemplate::kNone; } |
| MessageTemplate::Template error() const { return scanner_error_; } |
| Location error_location() const { return scanner_error_location_; } |
| + bool has_invalid_template_escape() const { |
| + return invalid_template_escape_message_ != MessageTemplate::kNone; |
| + } |
| + MessageTemplate::Template invalid_template_escape_message() const { |
| + return invalid_template_escape_message_; |
| + } |
| + Location invalid_template_escape_location() const { |
| + return invalid_template_escape_location_; |
| + } |
| + |
| + void clear_invalid_template_escape() { |
| + DCHECK(has_invalid_template_escape()); |
| + invalid_template_escape_message_ = MessageTemplate::kNone; |
| + invalid_template_escape_location_ = Location::invalid(); |
| + } |
| + |
| // Similar functions for the upcoming token. |
| // One token look-ahead (past the token returned by Next()). |
| @@ -345,6 +362,46 @@ class Scanner { |
| bool complete_; |
| }; |
| + // Scoped helper for saving & restoring scanner error state. |
| + // This is used for tagged template literals, in which normally forbidden |
| + // escape sequences are allowed. |
| + class ErrorState { |
|
vogelheim
2017/02/22 10:03:02
One more nitpick: I'd prefer if this moved to scan
bakkot1
2017/02/22 20:23:53
Sounds good to me! I'm always happier having less
|
| + public: |
| + ErrorState(MessageTemplate::Template* message_stack, |
| + Location* location_stack) |
| + : message_stack_(message_stack), |
| + old_message_(*message_stack), |
| + location_stack_(location_stack), |
| + old_location_(*location_stack) { |
| + *message_stack_ = MessageTemplate::kNone; |
| + *location_stack_ = Location::invalid(); |
| + } |
| + |
| + ~ErrorState() { |
| + *message_stack_ = old_message_; |
| + *location_stack_ = old_location_; |
| + } |
| + |
| + void MoveErrorTo(MessageTemplate::Template* message_dest, |
| + Location* location_dest) { |
| + if (*message_stack_ == MessageTemplate::kNone) { |
| + return; |
| + } |
| + if (*message_dest == MessageTemplate::kNone) { |
| + *message_dest = *message_stack_; |
| + *location_dest = *location_stack_; |
| + } |
| + *message_stack_ = MessageTemplate::kNone; |
| + *location_stack_ = Location::invalid(); |
| + } |
| + |
| + private: |
| + MessageTemplate::Template* const message_stack_; |
| + MessageTemplate::Template const old_message_; |
| + Location* const location_stack_; |
| + Location const old_location_; |
| + }; |
| + |
| // LiteralBuffer - Collector of chars of literals. |
| class LiteralBuffer { |
| public: |
| @@ -466,6 +523,7 @@ class Scanner { |
| next_next_.raw_literal_chars = NULL; |
| found_html_comment_ = false; |
| scanner_error_ = MessageTemplate::kNone; |
| + invalid_template_escape_message_ = MessageTemplate::kNone; |
| } |
| void ReportScannerError(const Location& location, |
| @@ -756,6 +814,9 @@ class Scanner { |
| MessageTemplate::Template scanner_error_; |
| Location scanner_error_location_; |
| + |
| + MessageTemplate::Template invalid_template_escape_message_; |
| + Location invalid_template_escape_location_; |
| }; |
| } // namespace internal |