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 |