| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 5b66e9a11401c5406795c891e637bae475cf4b99..e3ff9e0639f1c6543faa0ebbaa993456c7d2ae41 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -684,6 +684,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(
|
| @@ -2016,6 +2017,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);
|
| @@ -2115,10 +2121,17 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
|
| return name;
|
| } else if (is_sloppy(language_mode()) &&
|
| (next == Token::FUTURE_STRICT_RESERVED_WORD ||
|
| + next == Token::ESCAPED_STRICT_RESERVED_WORD ||
|
| next == Token::LET || next == Token::STATIC ||
|
| (next == Token::YIELD && !is_generator()))) {
|
| classifier->RecordStrictModeFormalParameterError(
|
| scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
|
| + if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
|
| + is_strict(language_mode())) {
|
| + ReportUnexpectedToken(next);
|
| + *ok = false;
|
| + return Traits::EmptyIdentifier();
|
| + }
|
| if (next == Token::LET) {
|
| classifier->RecordLetPatternError(scanner()->location(),
|
| MessageTemplate::kLetInLexicalBinding);
|
| @@ -2161,7 +2174,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();
|
| @@ -2278,6 +2293,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);
|
| @@ -2542,7 +2558,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();
|
|
|
| @@ -2583,11 +2600,17 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
|
| return expression;
|
| }
|
|
|
| + case Token::ESCAPED_KEYWORD:
|
| + *is_escaped_keyword = 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;
|
| }
|
| @@ -2616,14 +2639,21 @@ 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) {
|
| this->PushLiteralName(fni_, name);
|
| }
|
|
|
| + bool escaped_static =
|
| + is_escaped_keyword &&
|
| + scanner()->is_literal_contextual_keyword(CStrVector("static"));
|
| +
|
| if (!in_class && !is_generator) {
|
| DCHECK(!is_static);
|
|
|
| @@ -2641,8 +2671,7 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| *is_computed_name);
|
| }
|
|
|
| - if (Token::IsIdentifier(name_token, language_mode(),
|
| - this->is_generator()) &&
|
| + if ((is_identifier || is_escaped_keyword) &&
|
| (peek() == Token::COMMA || peek() == Token::RBRACE ||
|
| peek() == Token::ASSIGN)) {
|
| // PropertyDefinition
|
| @@ -2651,6 +2680,14 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| //
|
| // CoverInitializedName
|
| // IdentifierReference Initializer?
|
| + if (!Token::IsIdentifier(name_token, language_mode(),
|
| + this->is_generator())) {
|
| + if (!escaped_static) {
|
| + ReportUnexpectedTokenAt(scanner()->location(), name_token);
|
| + *ok = false;
|
| + return this->EmptyObjectLiteralProperty();
|
| + }
|
| + }
|
| if (classifier->duplicate_finder() != nullptr &&
|
| scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
|
| classifier->RecordDuplicateFormalParameterError(scanner()->location());
|
| @@ -2683,6 +2720,11 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| }
|
| }
|
|
|
| + if (in_class && escaped_static && !is_static) {
|
| + ReportUnexpectedTokenAt(scanner()->location(), name_token);
|
| + *ok = false;
|
| + return this->EmptyObjectLiteralProperty();
|
| + }
|
|
|
| if (is_generator || peek() == Token::LPAREN) {
|
| // MethodDefinition
|
| @@ -2732,8 +2774,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,
|
|
|