Chromium Code Reviews| Index: src/preparser.h |
| diff --git a/src/preparser.h b/src/preparser.h |
| index 8bbd9e688ccb6adcf2b8e80a890e17fb5c4e71e8..e07a28872b9b2bb90fd015153df2fdb522630d5c 100644 |
| --- a/src/preparser.h |
| +++ b/src/preparser.h |
| @@ -685,6 +685,7 @@ class ParserBase : public Traits { |
| ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| bool* is_static, bool* is_computed_name, |
| + bool* is_identifier, bool* is_escaped_keyword, |
| ExpressionClassifier* classifier, bool* ok); |
| ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| ObjectLiteralPropertyT ParsePropertyDefinition( |
| @@ -1999,6 +2000,11 @@ void ParserBase<Traits>::GetUnexpectedTokenMessage( |
| *message = MessageTemplate::kUnexpectedTemplateString; |
| *arg = nullptr; |
| break; |
| + case Token::ESCAPED_STRICT_RESERVED_WORD: |
| + case Token::ESCAPED_KEYWORD: |
| + *message = MessageTemplate::kInvalidEscapedReservedWord; |
| + *arg = nullptr; |
| + break; |
| default: |
| const char* name = Token::String(token); |
| DCHECK(name != NULL); |
| @@ -2050,6 +2056,14 @@ typename ParserBase<Traits>::IdentifierT |
| ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
| bool* ok) { |
| Token::Value next = Next(); |
| + if (next == Token::ESCAPED_STRICT_RESERVED_WORD) { |
|
rossberg
2015/11/06 13:31:04
Any reason not to put this into an else-if branch
caitp (gmail)
2015/11/06 16:10:30
The duplicate finder bit doesn't seem to stop `var
|
| + if (is_strict(language_mode())) { |
| + ReportUnexpectedToken(next); |
| + *ok = false; |
| + return Traits::EmptyIdentifier(); |
| + } |
| + next = Token::IDENTIFIER; |
| + } |
| if (next == Token::IDENTIFIER) { |
| IdentifierT name = this->GetSymbol(scanner()); |
| // When this function is used to read a formal parameter, we don't always |
| @@ -2144,7 +2158,9 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
| Token::Value next = Next(); |
| if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
| next != Token::LET && next != Token::STATIC && next != Token::YIELD && |
| - next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| + next != Token::FUTURE_STRICT_RESERVED_WORD && |
| + next != Token::ESCAPED_KEYWORD && |
| + next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| this->ReportUnexpectedToken(next); |
| *ok = false; |
| return Traits::EmptyIdentifier(); |
| @@ -2271,6 +2287,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| case Token::LET: |
| case Token::STATIC: |
| case Token::YIELD: |
| + case Token::ESCAPED_STRICT_RESERVED_WORD: |
| case Token::FUTURE_STRICT_RESERVED_WORD: { |
| // Using eval or arguments in this context is OK even in strict mode. |
| IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| @@ -2547,7 +2564,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
| - bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
| + bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword, |
| + ExpressionClassifier* classifier, bool* ok) { |
| Token::Value token = peek(); |
| int pos = peek_position(); |
| @@ -2588,11 +2606,18 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| return expression; |
| } |
| + case Token::ESCAPED_KEYWORD: |
| + *is_escaped_keyword = true; |
| + *is_identifier = true; |
| + *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
| + break; |
| + |
| case Token::STATIC: |
| *is_static = true; |
| // Fall through. |
| default: |
| + *is_identifier = true; |
| *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
| break; |
| } |
| @@ -2621,8 +2646,11 @@ ParserBase<Traits>::ParsePropertyDefinition( |
| Token::Value name_token = peek(); |
| int next_beg_pos = scanner()->peek_location().beg_pos; |
| int next_end_pos = scanner()->peek_location().end_pos; |
| + bool is_identifier = false; |
| + bool is_escaped_keyword = false; |
| ExpressionT name_expression = ParsePropertyName( |
| - &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
| + &name, &is_get, &is_set, &name_is_static, is_computed_name, |
| + &is_identifier, &is_escaped_keyword, classifier, |
| CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| if (fni_ != nullptr && !*is_computed_name) { |
| @@ -2646,16 +2674,28 @@ ParserBase<Traits>::ParsePropertyDefinition( |
| *is_computed_name); |
| } |
| - if (Token::IsIdentifier(name_token, language_mode(), |
| - this->is_generator()) && |
| - (peek() == Token::COMMA || peek() == Token::RBRACE || |
| - peek() == Token::ASSIGN)) { |
| + if (is_identifier && (peek() == Token::COMMA || peek() == Token::RBRACE || |
| + peek() == Token::ASSIGN)) { |
| // PropertyDefinition |
| // IdentifierReference |
| // CoverInitializedName |
| // |
| // CoverInitializedName |
| // IdentifierReference Initializer? |
| + if (!Token::IsIdentifier(name_token, language_mode(), |
| + this->is_generator())) { |
| + ReportUnexpectedTokenAt(scanner()->location(), name_token); |
| + *ok = false; |
| + return this->EmptyObjectLiteralProperty(); |
| + } |
| + if (is_escaped_keyword) { |
| + classifier->RecordExpressionError( |
| + scanner()->location(), |
| + MessageTemplate::kInvalidEscapedReservedWord); |
| + classifier->RecordBindingPatternError( |
| + scanner()->location(), |
| + MessageTemplate::kInvalidEscapedReservedWord); |
| + } |
| if (classifier->duplicate_finder() != nullptr && |
| scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| @@ -2737,8 +2777,8 @@ ParserBase<Traits>::ParsePropertyDefinition( |
| name_token = peek(); |
| name_expression = ParsePropertyName( |
| - &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| + &name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, |
| + &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| if (!*is_computed_name) { |
| checker->CheckProperty(name_token, kAccessorProperty, is_static, |