| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 // ---------------------------------------------------------------------------- | 121 // ---------------------------------------------------------------------------- |
| 122 // The CHECK_OK macro is a convenient macro to enforce error | 122 // The CHECK_OK macro is a convenient macro to enforce error |
| 123 // handling for functions that may fail (by returning !*ok). | 123 // handling for functions that may fail (by returning !*ok). |
| 124 // | 124 // |
| 125 // CAUTION: This macro appends extra statements after a call, | 125 // CAUTION: This macro appends extra statements after a call, |
| 126 // thus it must never be used where only a single statement | 126 // thus it must never be used where only a single statement |
| 127 // is correct (e.g. an if statement branch w/o braces)! | 127 // is correct (e.g. an if statement branch w/o braces)! |
| 128 | 128 |
| 129 #define CHECK_OK_CUSTOM(x) ok); \ | 129 #define CHECK_OK_CUSTOM(x) ok); \ |
| 130 if (!*ok) return this->x(); \ | 130 if (!*ok) return impl()->x(); \ |
| 131 ((void)0 | 131 ((void)0 |
| 132 #define DUMMY ) // to make indentation work | 132 #define DUMMY ) // to make indentation work |
| 133 #undef DUMMY | 133 #undef DUMMY |
| 134 | 134 |
| 135 // Used in functions where the return type is ExpressionT. | 135 // Used in functions where the return type is ExpressionT. |
| 136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) | 136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) |
| 137 | 137 |
| 138 // Common base class template shared between parser and pre-parser. | 138 // Common base class template shared between parser and pre-parser. |
| 139 // The Impl parameter is the actual class of the parser/pre-parser, | 139 // The Impl parameter is the actual class of the parser/pre-parser, |
| 140 // following the Curiously Recurring Template Pattern (CRTP). | 140 // following the Curiously Recurring Template Pattern (CRTP). |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); | 811 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); |
| 812 } | 812 } |
| 813 | 813 |
| 814 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 814 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 815 // If so, reports an error. Only called for strict mode and template strings. | 815 // If so, reports an error. Only called for strict mode and template strings. |
| 816 void CheckOctalLiteral(int beg_pos, int end_pos, | 816 void CheckOctalLiteral(int beg_pos, int end_pos, |
| 817 MessageTemplate::Template message, bool* ok) { | 817 MessageTemplate::Template message, bool* ok) { |
| 818 Scanner::Location octal = scanner()->octal_position(); | 818 Scanner::Location octal = scanner()->octal_position(); |
| 819 if (octal.IsValid() && beg_pos <= octal.beg_pos && | 819 if (octal.IsValid() && beg_pos <= octal.beg_pos && |
| 820 octal.end_pos <= end_pos) { | 820 octal.end_pos <= end_pos) { |
| 821 ReportMessageAt(octal, message); | 821 impl()->ReportMessageAt(octal, message); |
| 822 scanner()->clear_octal_position(); | 822 scanner()->clear_octal_position(); |
| 823 *ok = false; | 823 *ok = false; |
| 824 } | 824 } |
| 825 } | 825 } |
| 826 // for now, this check just collects statistics. | 826 // for now, this check just collects statistics. |
| 827 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos, | 827 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos, |
| 828 int end_pos) { | 828 int end_pos) { |
| 829 Scanner::Location token_location = | 829 Scanner::Location token_location = |
| 830 scanner()->decimal_with_leading_zero_position(); | 830 scanner()->decimal_with_leading_zero_position(); |
| 831 if (token_location.IsValid() && beg_pos <= token_location.beg_pos && | 831 if (token_location.IsValid() && beg_pos <= token_location.beg_pos && |
| (...skipping 21 matching lines...) Expand all Loading... |
| 853 // Checking the name of a function literal. This has to be done after parsing | 853 // Checking the name of a function literal. This has to be done after parsing |
| 854 // the function, since the function can declare itself strict. | 854 // the function, since the function can declare itself strict. |
| 855 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 855 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
| 856 FunctionNameValidity function_name_validity, | 856 FunctionNameValidity function_name_validity, |
| 857 const Scanner::Location& function_name_loc, bool* ok) { | 857 const Scanner::Location& function_name_loc, bool* ok) { |
| 858 if (function_name_validity == kSkipFunctionNameCheck) return; | 858 if (function_name_validity == kSkipFunctionNameCheck) return; |
| 859 // The function name needs to be checked in strict mode. | 859 // The function name needs to be checked in strict mode. |
| 860 if (is_sloppy(language_mode)) return; | 860 if (is_sloppy(language_mode)) return; |
| 861 | 861 |
| 862 if (impl()->IsEvalOrArguments(function_name)) { | 862 if (impl()->IsEvalOrArguments(function_name)) { |
| 863 Traits::ReportMessageAt(function_name_loc, | 863 impl()->ReportMessageAt(function_name_loc, |
| 864 MessageTemplate::kStrictEvalArguments); | 864 MessageTemplate::kStrictEvalArguments); |
| 865 *ok = false; | 865 *ok = false; |
| 866 return; | 866 return; |
| 867 } | 867 } |
| 868 if (function_name_validity == kFunctionNameIsStrictReserved) { | 868 if (function_name_validity == kFunctionNameIsStrictReserved) { |
| 869 Traits::ReportMessageAt(function_name_loc, | 869 impl()->ReportMessageAt(function_name_loc, |
| 870 MessageTemplate::kUnexpectedStrictReserved); | 870 MessageTemplate::kUnexpectedStrictReserved); |
| 871 *ok = false; | 871 *ok = false; |
| 872 return; | 872 return; |
| 873 } | 873 } |
| 874 } | 874 } |
| 875 | 875 |
| 876 // Determine precedence of given token. | 876 // Determine precedence of given token. |
| 877 static int Precedence(Token::Value token, bool accept_IN) { | 877 static int Precedence(Token::Value token, bool accept_IN) { |
| 878 if (token == Token::IN && !accept_IN) | 878 if (token == Token::IN && !accept_IN) |
| 879 return 0; // 0 precedence will terminate binary expression parsing | 879 return 0; // 0 precedence will terminate binary expression parsing |
| 880 return Token::Precedence(token); | 880 return Token::Precedence(token); |
| 881 } | 881 } |
| 882 | 882 |
| 883 typename Traits::Type::Factory* factory() { return &ast_node_factory_; } | 883 typename Traits::Type::Factory* factory() { return &ast_node_factory_; } |
| 884 | 884 |
| 885 DeclarationScope* GetReceiverScope() const { | 885 DeclarationScope* GetReceiverScope() const { |
| 886 return scope()->GetReceiverScope(); | 886 return scope()->GetReceiverScope(); |
| 887 } | 887 } |
| 888 LanguageMode language_mode() { return scope()->language_mode(); } | 888 LanguageMode language_mode() { return scope()->language_mode(); } |
| 889 bool is_generator() const { return function_state_->is_generator(); } | 889 bool is_generator() const { return function_state_->is_generator(); } |
| 890 bool is_async_function() const { | 890 bool is_async_function() const { |
| 891 return function_state_->is_async_function(); | 891 return function_state_->is_async_function(); |
| 892 } | 892 } |
| 893 bool is_resumable() const { return function_state_->is_resumable(); } | 893 bool is_resumable() const { return function_state_->is_resumable(); } |
| 894 | 894 |
| 895 // Report syntax errors. | 895 // Report syntax errors. |
| 896 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 896 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
| 897 ParseErrorType error_type = kSyntaxError) { | 897 ParseErrorType error_type = kSyntaxError) { |
| 898 Scanner::Location source_location = scanner()->location(); | 898 Scanner::Location source_location = scanner()->location(); |
| 899 Traits::ReportMessageAt(source_location, message, arg, error_type); | 899 impl()->ReportMessageAt(source_location, message, arg, error_type); |
| 900 } | 900 } |
| 901 | 901 |
| 902 void ReportMessage(MessageTemplate::Template message, const AstRawString* arg, | 902 void ReportMessage(MessageTemplate::Template message, const AstRawString* arg, |
| 903 ParseErrorType error_type = kSyntaxError) { | 903 ParseErrorType error_type = kSyntaxError) { |
| 904 Scanner::Location source_location = scanner()->location(); | 904 Scanner::Location source_location = scanner()->location(); |
| 905 Traits::ReportMessageAt(source_location, message, arg, error_type); | 905 impl()->ReportMessageAt(source_location, message, arg, error_type); |
| 906 } | |
| 907 | |
| 908 void ReportMessageAt(Scanner::Location location, | |
| 909 MessageTemplate::Template message, | |
| 910 const char* arg = NULL, | |
| 911 ParseErrorType error_type = kSyntaxError) { | |
| 912 Traits::ReportMessageAt(location, message, arg, error_type); | |
| 913 } | |
| 914 | |
| 915 void ReportMessageAt(Scanner::Location location, | |
| 916 MessageTemplate::Template message, | |
| 917 const AstRawString* arg, | |
| 918 ParseErrorType error_type = kSyntaxError) { | |
| 919 Traits::ReportMessageAt(location, message, arg, error_type); | |
| 920 } | 906 } |
| 921 | 907 |
| 922 void ReportMessageAt(Scanner::Location location, | 908 void ReportMessageAt(Scanner::Location location, |
| 923 MessageTemplate::Template message, | 909 MessageTemplate::Template message, |
| 924 ParseErrorType error_type) { | 910 ParseErrorType error_type) { |
| 925 ReportMessageAt(location, message, static_cast<const char*>(nullptr), | 911 impl()->ReportMessageAt(location, message, |
| 926 error_type); | 912 static_cast<const char*>(nullptr), error_type); |
| 927 } | 913 } |
| 928 | 914 |
| 929 void GetUnexpectedTokenMessage( | 915 void GetUnexpectedTokenMessage( |
| 930 Token::Value token, MessageTemplate::Template* message, | 916 Token::Value token, MessageTemplate::Template* message, |
| 931 Scanner::Location* location, const char** arg, | 917 Scanner::Location* location, const char** arg, |
| 932 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 918 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
| 933 | 919 |
| 934 void ReportUnexpectedToken(Token::Value token); | 920 void ReportUnexpectedToken(Token::Value token); |
| 935 void ReportUnexpectedTokenAt( | 921 void ReportUnexpectedTokenAt( |
| 936 Scanner::Location location, Token::Value token, | 922 Scanner::Location location, Token::Value token, |
| 937 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 923 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
| 938 | 924 |
| 939 void ReportClassifierError( | 925 void ReportClassifierError( |
| 940 const typename ExpressionClassifier::Error& error) { | 926 const typename ExpressionClassifier::Error& error) { |
| 941 Traits::ReportMessageAt(error.location, error.message, error.arg, | 927 impl()->ReportMessageAt(error.location, error.message, error.arg, |
| 942 error.type); | 928 error.type); |
| 943 } | 929 } |
| 944 | 930 |
| 945 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 931 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
| 946 if (!classifier->is_valid_expression() || | 932 if (!classifier->is_valid_expression() || |
| 947 classifier->has_object_literal_error()) { | 933 classifier->has_object_literal_error()) { |
| 948 const Scanner::Location& a = classifier->expression_error().location; | 934 const Scanner::Location& a = classifier->expression_error().location; |
| 949 const Scanner::Location& b = | 935 const Scanner::Location& b = |
| 950 classifier->object_literal_error().location; | 936 classifier->object_literal_error().location; |
| 951 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { | 937 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 return is_any_identifier(token) || token == Token::LPAREN; | 985 return is_any_identifier(token) || token == Token::LPAREN; |
| 1000 } | 986 } |
| 1001 | 987 |
| 1002 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 988 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
| 1003 ExpressionT expr, | 989 ExpressionT expr, |
| 1004 bool parenthesized_formals, bool is_async, | 990 bool parenthesized_formals, bool is_async, |
| 1005 bool* ok) { | 991 bool* ok) { |
| 1006 if (classifier->is_valid_binding_pattern()) { | 992 if (classifier->is_valid_binding_pattern()) { |
| 1007 // A simple arrow formal parameter: IDENTIFIER => BODY. | 993 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 1008 if (!impl()->IsIdentifier(expr)) { | 994 if (!impl()->IsIdentifier(expr)) { |
| 1009 Traits::ReportMessageAt(scanner()->location(), | 995 impl()->ReportMessageAt(scanner()->location(), |
| 1010 MessageTemplate::kUnexpectedToken, | 996 MessageTemplate::kUnexpectedToken, |
| 1011 Token::String(scanner()->current_token())); | 997 Token::String(scanner()->current_token())); |
| 1012 *ok = false; | 998 *ok = false; |
| 1013 } | 999 } |
| 1014 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 1000 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
| 1015 // If after parsing the expr, we see an error but the expression is | 1001 // If after parsing the expr, we see an error but the expression is |
| 1016 // neither a valid binding pattern nor a valid parenthesized formal | 1002 // neither a valid binding pattern nor a valid parenthesized formal |
| 1017 // parameter list, show the "arrow formal parameters" error if the formals | 1003 // parameter list, show the "arrow formal parameters" error if the formals |
| 1018 // started with a parenthesis, and the binding pattern error otherwise. | 1004 // started with a parenthesis, and the binding pattern error otherwise. |
| 1019 const typename ExpressionClassifier::Error& error = | 1005 const typename ExpressionClassifier::Error& error = |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) { | 1392 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) { |
| 1407 return ReportUnexpectedTokenAt(scanner_->location(), token); | 1393 return ReportUnexpectedTokenAt(scanner_->location(), token); |
| 1408 } | 1394 } |
| 1409 | 1395 |
| 1410 template <typename Impl> | 1396 template <typename Impl> |
| 1411 void ParserBase<Impl>::ReportUnexpectedTokenAt( | 1397 void ParserBase<Impl>::ReportUnexpectedTokenAt( |
| 1412 Scanner::Location source_location, Token::Value token, | 1398 Scanner::Location source_location, Token::Value token, |
| 1413 MessageTemplate::Template message) { | 1399 MessageTemplate::Template message) { |
| 1414 const char* arg; | 1400 const char* arg; |
| 1415 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); | 1401 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); |
| 1416 Traits::ReportMessageAt(source_location, message, arg); | 1402 impl()->ReportMessageAt(source_location, message, arg); |
| 1417 } | 1403 } |
| 1418 | 1404 |
| 1419 template <typename Impl> | 1405 template <typename Impl> |
| 1420 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( | 1406 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( |
| 1421 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 1407 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
| 1422 ExpressionClassifier classifier(this); | 1408 ExpressionClassifier classifier(this); |
| 1423 auto result = | 1409 auto result = |
| 1424 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1410 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); |
| 1425 | 1411 |
| 1426 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { | 1412 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1452 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1467 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1453 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
| 1468 next == Token::LET || next == Token::STATIC || | 1454 next == Token::LET || next == Token::STATIC || |
| 1469 (next == Token::YIELD && !is_generator()))) { | 1455 (next == Token::YIELD && !is_generator()))) { |
| 1470 classifier->RecordStrictModeFormalParameterError( | 1456 classifier->RecordStrictModeFormalParameterError( |
| 1471 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); | 1457 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
| 1472 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1458 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1473 is_strict(language_mode())) { | 1459 is_strict(language_mode())) { |
| 1474 ReportUnexpectedToken(next); | 1460 ReportUnexpectedToken(next); |
| 1475 *ok = false; | 1461 *ok = false; |
| 1476 return Traits::EmptyIdentifier(); | 1462 return impl()->EmptyIdentifier(); |
| 1477 } | 1463 } |
| 1478 if (next == Token::LET || | 1464 if (next == Token::LET || |
| 1479 (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1465 (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1480 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { | 1466 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { |
| 1481 classifier->RecordLetPatternError(scanner()->location(), | 1467 classifier->RecordLetPatternError(scanner()->location(), |
| 1482 MessageTemplate::kLetInLexicalBinding); | 1468 MessageTemplate::kLetInLexicalBinding); |
| 1483 } | 1469 } |
| 1484 return this->GetSymbol(scanner()); | 1470 return this->GetSymbol(scanner()); |
| 1485 } else { | 1471 } else { |
| 1486 this->ReportUnexpectedToken(next); | 1472 this->ReportUnexpectedToken(next); |
| 1487 *ok = false; | 1473 *ok = false; |
| 1488 return Traits::EmptyIdentifier(); | 1474 return impl()->EmptyIdentifier(); |
| 1489 } | 1475 } |
| 1490 } | 1476 } |
| 1491 | 1477 |
| 1492 template <class Impl> | 1478 template <class Impl> |
| 1493 typename ParserBase<Impl>::IdentifierT | 1479 typename ParserBase<Impl>::IdentifierT |
| 1494 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( | 1480 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( |
| 1495 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { | 1481 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { |
| 1496 Token::Value next = Next(); | 1482 Token::Value next = Next(); |
| 1497 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && | 1483 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && |
| 1498 !IsAsyncFunction(function_kind)) || | 1484 !IsAsyncFunction(function_kind)) || |
| 1499 next == Token::ASYNC) { | 1485 next == Token::ASYNC) { |
| 1500 *is_strict_reserved = false; | 1486 *is_strict_reserved = false; |
| 1501 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1487 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 1502 next == Token::STATIC || | 1488 next == Token::STATIC || |
| 1503 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { | 1489 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { |
| 1504 *is_strict_reserved = true; | 1490 *is_strict_reserved = true; |
| 1505 } else { | 1491 } else { |
| 1506 ReportUnexpectedToken(next); | 1492 ReportUnexpectedToken(next); |
| 1507 *ok = false; | 1493 *ok = false; |
| 1508 return Traits::EmptyIdentifier(); | 1494 return impl()->EmptyIdentifier(); |
| 1509 } | 1495 } |
| 1510 | 1496 |
| 1511 return this->GetSymbol(scanner()); | 1497 return this->GetSymbol(scanner()); |
| 1512 } | 1498 } |
| 1513 | 1499 |
| 1514 template <typename Impl> | 1500 template <typename Impl> |
| 1515 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( | 1501 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( |
| 1516 bool* ok) { | 1502 bool* ok) { |
| 1517 Token::Value next = Next(); | 1503 Token::Value next = Next(); |
| 1518 if (next != Token::IDENTIFIER && next != Token::ASYNC && | 1504 if (next != Token::IDENTIFIER && next != Token::ASYNC && |
| 1519 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && | 1505 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && |
| 1520 next != Token::STATIC && next != Token::YIELD && | 1506 next != Token::STATIC && next != Token::YIELD && |
| 1521 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1507 next != Token::FUTURE_STRICT_RESERVED_WORD && |
| 1522 next != Token::ESCAPED_KEYWORD && | 1508 next != Token::ESCAPED_KEYWORD && |
| 1523 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1509 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| 1524 this->ReportUnexpectedToken(next); | 1510 this->ReportUnexpectedToken(next); |
| 1525 *ok = false; | 1511 *ok = false; |
| 1526 return Traits::EmptyIdentifier(); | 1512 return impl()->EmptyIdentifier(); |
| 1527 } | 1513 } |
| 1528 | 1514 |
| 1529 return this->GetSymbol(scanner()); | 1515 return this->GetSymbol(scanner()); |
| 1530 } | 1516 } |
| 1531 | 1517 |
| 1532 template <typename Impl> | 1518 template <typename Impl> |
| 1533 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( | 1519 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( |
| 1534 bool* ok) { | 1520 bool* ok) { |
| 1535 int pos = peek_position(); | 1521 int pos = peek_position(); |
| 1536 if (!scanner()->ScanRegExpPattern()) { | 1522 if (!scanner()->ScanRegExpPattern()) { |
| 1537 Next(); | 1523 Next(); |
| 1538 ReportMessage(MessageTemplate::kUnterminatedRegExp); | 1524 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
| 1539 *ok = false; | 1525 *ok = false; |
| 1540 return Traits::EmptyExpression(); | 1526 return impl()->EmptyExpression(); |
| 1541 } | 1527 } |
| 1542 | 1528 |
| 1543 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1529 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1544 | 1530 |
| 1545 IdentifierT js_pattern = this->GetNextSymbol(scanner()); | 1531 IdentifierT js_pattern = this->GetNextSymbol(scanner()); |
| 1546 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); | 1532 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); |
| 1547 if (flags.IsNothing()) { | 1533 if (flags.IsNothing()) { |
| 1548 Next(); | 1534 Next(); |
| 1549 ReportMessage(MessageTemplate::kMalformedRegExpFlags); | 1535 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
| 1550 *ok = false; | 1536 *ok = false; |
| 1551 return Traits::EmptyExpression(); | 1537 return impl()->EmptyExpression(); |
| 1552 } | 1538 } |
| 1553 int js_flags = flags.FromJust(); | 1539 int js_flags = flags.FromJust(); |
| 1554 Next(); | 1540 Next(); |
| 1555 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1541 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 1556 } | 1542 } |
| 1557 | 1543 |
| 1558 template <typename Impl> | 1544 template <typename Impl> |
| 1559 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( | 1545 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( |
| 1560 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 1546 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
| 1561 // PrimaryExpression :: | 1547 // PrimaryExpression :: |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 ExpressionT expr = this->ParseAssignmentExpression( | 1650 ExpressionT expr = this->ParseAssignmentExpression( |
| 1665 true, &binding_classifier, CHECK_OK); | 1651 true, &binding_classifier, CHECK_OK); |
| 1666 classifier->Accumulate(&binding_classifier, | 1652 classifier->Accumulate(&binding_classifier, |
| 1667 ExpressionClassifier::AllProductions); | 1653 ExpressionClassifier::AllProductions); |
| 1668 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { | 1654 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { |
| 1669 classifier->RecordArrowFormalParametersError( | 1655 classifier->RecordArrowFormalParametersError( |
| 1670 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), | 1656 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), |
| 1671 MessageTemplate::kInvalidRestParameter); | 1657 MessageTemplate::kInvalidRestParameter); |
| 1672 } | 1658 } |
| 1673 if (peek() == Token::COMMA) { | 1659 if (peek() == Token::COMMA) { |
| 1674 ReportMessageAt(scanner()->peek_location(), | 1660 impl()->ReportMessageAt(scanner()->peek_location(), |
| 1675 MessageTemplate::kParamAfterRest); | 1661 MessageTemplate::kParamAfterRest); |
| 1676 *ok = false; | 1662 *ok = false; |
| 1677 return this->EmptyExpression(); | 1663 return impl()->EmptyExpression(); |
| 1678 } | 1664 } |
| 1679 Expect(Token::RPAREN, CHECK_OK); | 1665 Expect(Token::RPAREN, CHECK_OK); |
| 1680 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); | 1666 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); |
| 1681 } | 1667 } |
| 1682 // Heuristically try to detect immediately called functions before | 1668 // Heuristically try to detect immediately called functions before |
| 1683 // seeing the call parentheses. | 1669 // seeing the call parentheses. |
| 1684 function_state_->set_next_function_is_parenthesized(peek() == | 1670 function_state_->set_next_function_is_parenthesized(peek() == |
| 1685 Token::FUNCTION); | 1671 Token::FUNCTION); |
| 1686 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); | 1672 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); |
| 1687 Expect(Token::RPAREN, CHECK_OK); | 1673 Expect(Token::RPAREN, CHECK_OK); |
| 1688 return expr; | 1674 return expr; |
| 1689 } | 1675 } |
| 1690 | 1676 |
| 1691 case Token::CLASS: { | 1677 case Token::CLASS: { |
| 1692 BindingPatternUnexpectedToken(classifier); | 1678 BindingPatternUnexpectedToken(classifier); |
| 1693 Consume(Token::CLASS); | 1679 Consume(Token::CLASS); |
| 1694 int class_token_position = position(); | 1680 int class_token_position = position(); |
| 1695 IdentifierT name = this->EmptyIdentifier(); | 1681 IdentifierT name = impl()->EmptyIdentifier(); |
| 1696 bool is_strict_reserved_name = false; | 1682 bool is_strict_reserved_name = false; |
| 1697 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1683 Scanner::Location class_name_location = Scanner::Location::invalid(); |
| 1698 if (peek_any_identifier()) { | 1684 if (peek_any_identifier()) { |
| 1699 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1685 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 1700 CHECK_OK); | 1686 CHECK_OK); |
| 1701 class_name_location = scanner()->location(); | 1687 class_name_location = scanner()->location(); |
| 1702 } | 1688 } |
| 1703 return impl()->ParseClassLiteral(classifier, name, class_name_location, | 1689 return impl()->ParseClassLiteral(classifier, name, class_name_location, |
| 1704 is_strict_reserved_name, | 1690 is_strict_reserved_name, |
| 1705 class_token_position, ok); | 1691 class_token_position, ok); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1724 return impl()->ParseDoExpression(ok); | 1710 return impl()->ParseDoExpression(ok); |
| 1725 } | 1711 } |
| 1726 break; | 1712 break; |
| 1727 | 1713 |
| 1728 default: | 1714 default: |
| 1729 break; | 1715 break; |
| 1730 } | 1716 } |
| 1731 | 1717 |
| 1732 ReportUnexpectedToken(Next()); | 1718 ReportUnexpectedToken(Next()); |
| 1733 *ok = false; | 1719 *ok = false; |
| 1734 return this->EmptyExpression(); | 1720 return impl()->EmptyExpression(); |
| 1735 } | 1721 } |
| 1736 | 1722 |
| 1737 template <typename Impl> | 1723 template <typename Impl> |
| 1738 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1724 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
| 1739 bool accept_IN, bool* ok) { | 1725 bool accept_IN, bool* ok) { |
| 1740 ExpressionClassifier classifier(this); | 1726 ExpressionClassifier classifier(this); |
| 1741 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1727 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 1742 impl()->RewriteNonPattern(&classifier, CHECK_OK); | 1728 impl()->RewriteNonPattern(&classifier, CHECK_OK); |
| 1743 return result; | 1729 return result; |
| 1744 } | 1730 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 // '[' Expression? (',' Expression?)* ']' | 1801 // '[' Expression? (',' Expression?)* ']' |
| 1816 | 1802 |
| 1817 int pos = peek_position(); | 1803 int pos = peek_position(); |
| 1818 typename Traits::Type::ExpressionList values = | 1804 typename Traits::Type::ExpressionList values = |
| 1819 this->NewExpressionList(4, zone_); | 1805 this->NewExpressionList(4, zone_); |
| 1820 int first_spread_index = -1; | 1806 int first_spread_index = -1; |
| 1821 Expect(Token::LBRACK, CHECK_OK); | 1807 Expect(Token::LBRACK, CHECK_OK); |
| 1822 while (peek() != Token::RBRACK) { | 1808 while (peek() != Token::RBRACK) { |
| 1823 ExpressionT elem; | 1809 ExpressionT elem; |
| 1824 if (peek() == Token::COMMA) { | 1810 if (peek() == Token::COMMA) { |
| 1825 elem = this->GetLiteralTheHole(peek_position(), factory()); | 1811 elem = impl()->GetLiteralTheHole(peek_position()); |
| 1826 } else if (peek() == Token::ELLIPSIS) { | 1812 } else if (peek() == Token::ELLIPSIS) { |
| 1827 int start_pos = peek_position(); | 1813 int start_pos = peek_position(); |
| 1828 Consume(Token::ELLIPSIS); | 1814 Consume(Token::ELLIPSIS); |
| 1829 int expr_pos = peek_position(); | 1815 int expr_pos = peek_position(); |
| 1830 ExpressionT argument = | 1816 ExpressionT argument = |
| 1831 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1817 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1832 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1818 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 1833 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1819 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
| 1834 | 1820 |
| 1835 if (first_spread_index < 0) { | 1821 if (first_spread_index < 0) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 literal_index, pos); | 1857 literal_index, pos); |
| 1872 if (first_spread_index >= 0) { | 1858 if (first_spread_index >= 0) { |
| 1873 result = factory()->NewRewritableExpression(result); | 1859 result = factory()->NewRewritableExpression(result); |
| 1874 impl()->QueueNonPatternForRewriting(result, ok); | 1860 impl()->QueueNonPatternForRewriting(result, ok); |
| 1875 if (!*ok) { | 1861 if (!*ok) { |
| 1876 // If the non-pattern rewriting mechanism is used in the future for | 1862 // If the non-pattern rewriting mechanism is used in the future for |
| 1877 // rewriting other things than spreads, this error message will have | 1863 // rewriting other things than spreads, this error message will have |
| 1878 // to change. Also, this error message will never appear while pre- | 1864 // to change. Also, this error message will never appear while pre- |
| 1879 // parsing (this is OK, as it is an implementation limitation). | 1865 // parsing (this is OK, as it is an implementation limitation). |
| 1880 ReportMessage(MessageTemplate::kTooManySpreads); | 1866 ReportMessage(MessageTemplate::kTooManySpreads); |
| 1881 return this->EmptyExpression(); | 1867 return impl()->EmptyExpression(); |
| 1882 } | 1868 } |
| 1883 } | 1869 } |
| 1884 return result; | 1870 return result; |
| 1885 } | 1871 } |
| 1886 | 1872 |
| 1887 template <class Impl> | 1873 template <class Impl> |
| 1888 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( | 1874 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
| 1889 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1875 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, |
| 1890 ExpressionClassifier* classifier, bool* ok) { | 1876 ExpressionClassifier* classifier, bool* ok) { |
| 1891 Token::Value token = peek(); | 1877 Token::Value token = peek(); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2086 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2101 | 2087 |
| 2102 return factory()->NewObjectLiteralProperty(name_expression, value, | 2088 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 2103 ObjectLiteralProperty::COMPUTED, | 2089 ObjectLiteralProperty::COMPUTED, |
| 2104 is_static, *is_computed_name); | 2090 is_static, *is_computed_name); |
| 2105 } | 2091 } |
| 2106 | 2092 |
| 2107 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { | 2093 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { |
| 2108 // ClassElement (static) | 2094 // ClassElement (static) |
| 2109 // 'static' MethodDefinition | 2095 // 'static' MethodDefinition |
| 2110 *name = this->EmptyIdentifier(); | 2096 *name = impl()->EmptyIdentifier(); |
| 2111 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2097 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
| 2112 checker, true, has_extends, MethodKind::kStatic, is_computed_name, | 2098 checker, true, has_extends, MethodKind::kStatic, is_computed_name, |
| 2113 nullptr, classifier, name, ok); | 2099 nullptr, classifier, name, ok); |
| 2114 impl()->RewriteNonPattern(classifier, ok); | 2100 impl()->RewriteNonPattern(classifier, ok); |
| 2115 return property; | 2101 return property; |
| 2116 } | 2102 } |
| 2117 | 2103 |
| 2118 if (is_get || is_set) { | 2104 if (is_get || is_set) { |
| 2119 // MethodDefinition (Accessors) | 2105 // MethodDefinition (Accessors) |
| 2120 // get PropertyName '(' ')' '{' FunctionBody '}' | 2106 // get PropertyName '(' ')' '{' FunctionBody '}' |
| 2121 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2107 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
| 2122 *name = this->EmptyIdentifier(); | 2108 *name = impl()->EmptyIdentifier(); |
| 2123 bool dont_care = false; | 2109 bool dont_care = false; |
| 2124 name_token = peek(); | 2110 name_token = peek(); |
| 2125 | 2111 |
| 2126 name_expression = ParsePropertyName( | 2112 name_expression = ParsePropertyName( |
| 2127 name, &dont_care, &dont_care, is_computed_name, classifier, | 2113 name, &dont_care, &dont_care, is_computed_name, classifier, |
| 2128 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2114 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2129 | 2115 |
| 2130 if (!*is_computed_name) { | 2116 if (!*is_computed_name) { |
| 2131 checker->CheckProperty(name_token, kAccessorProperty, method_kind, | 2117 checker->CheckProperty(name_token, kAccessorProperty, method_kind, |
| 2132 classifier, | 2118 classifier, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2149 | 2135 |
| 2150 return factory()->NewObjectLiteralProperty( | 2136 return factory()->NewObjectLiteralProperty( |
| 2151 name_expression, value, | 2137 name_expression, value, |
| 2152 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 2138 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
| 2153 is_static, *is_computed_name); | 2139 is_static, *is_computed_name); |
| 2154 } | 2140 } |
| 2155 | 2141 |
| 2156 Token::Value next = Next(); | 2142 Token::Value next = Next(); |
| 2157 ReportUnexpectedToken(next); | 2143 ReportUnexpectedToken(next); |
| 2158 *ok = false; | 2144 *ok = false; |
| 2159 return this->EmptyObjectLiteralProperty(); | 2145 return impl()->EmptyObjectLiteralProperty(); |
| 2160 } | 2146 } |
| 2161 | 2147 |
| 2162 template <typename Impl> | 2148 template <typename Impl> |
| 2163 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2149 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
| 2164 ExpressionClassifier* classifier, bool* ok) { | 2150 ExpressionClassifier* classifier, bool* ok) { |
| 2165 // ObjectLiteral :: | 2151 // ObjectLiteral :: |
| 2166 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2152 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| 2167 | 2153 |
| 2168 int pos = peek_position(); | 2154 int pos = peek_position(); |
| 2169 typename Traits::Type::PropertyList properties = | 2155 typename Traits::Type::PropertyList properties = |
| 2170 this->NewPropertyList(4, zone_); | 2156 this->NewPropertyList(4, zone_); |
| 2171 int number_of_boilerplate_properties = 0; | 2157 int number_of_boilerplate_properties = 0; |
| 2172 bool has_computed_names = false; | 2158 bool has_computed_names = false; |
| 2173 ObjectLiteralChecker checker(this); | 2159 ObjectLiteralChecker checker(this); |
| 2174 | 2160 |
| 2175 Expect(Token::LBRACE, CHECK_OK); | 2161 Expect(Token::LBRACE, CHECK_OK); |
| 2176 | 2162 |
| 2177 while (peek() != Token::RBRACE) { | 2163 while (peek() != Token::RBRACE) { |
| 2178 FuncNameInferrer::State fni_state(fni_); | 2164 FuncNameInferrer::State fni_state(fni_); |
| 2179 | 2165 |
| 2180 const bool in_class = false; | 2166 const bool in_class = false; |
| 2181 const bool has_extends = false; | 2167 const bool has_extends = false; |
| 2182 bool is_computed_name = false; | 2168 bool is_computed_name = false; |
| 2183 IdentifierT name = this->EmptyIdentifier(); | 2169 IdentifierT name = impl()->EmptyIdentifier(); |
| 2184 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2170 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| 2185 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name, | 2171 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name, |
| 2186 NULL, classifier, &name, CHECK_OK); | 2172 NULL, classifier, &name, CHECK_OK); |
| 2187 | 2173 |
| 2188 if (is_computed_name) { | 2174 if (is_computed_name) { |
| 2189 has_computed_names = true; | 2175 has_computed_names = true; |
| 2190 } | 2176 } |
| 2191 | 2177 |
| 2192 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2178 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 2193 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2179 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 if (is_spread) { | 2242 if (is_spread) { |
| 2257 was_unspread = false; | 2243 was_unspread = false; |
| 2258 } else if (!was_unspread) { | 2244 } else if (!was_unspread) { |
| 2259 was_unspread = true; | 2245 was_unspread = true; |
| 2260 unspread_sequences_count++; | 2246 unspread_sequences_count++; |
| 2261 } | 2247 } |
| 2262 | 2248 |
| 2263 if (result->length() > Code::kMaxArguments) { | 2249 if (result->length() > Code::kMaxArguments) { |
| 2264 ReportMessage(MessageTemplate::kTooManyArguments); | 2250 ReportMessage(MessageTemplate::kTooManyArguments); |
| 2265 *ok = false; | 2251 *ok = false; |
| 2266 return this->NullExpressionList(); | 2252 return impl()->NullExpressionList(); |
| 2267 } | 2253 } |
| 2268 done = (peek() != Token::COMMA); | 2254 done = (peek() != Token::COMMA); |
| 2269 if (!done) { | 2255 if (!done) { |
| 2270 Next(); | 2256 Next(); |
| 2271 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { | 2257 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { |
| 2272 // allow trailing comma | 2258 // allow trailing comma |
| 2273 done = true; | 2259 done = true; |
| 2274 } | 2260 } |
| 2275 } | 2261 } |
| 2276 } | 2262 } |
| 2277 Scanner::Location location = scanner_->location(); | 2263 Scanner::Location location = scanner_->location(); |
| 2278 if (Token::RPAREN != Next()) { | 2264 if (Token::RPAREN != Next()) { |
| 2279 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2265 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 2280 *ok = false; | 2266 *ok = false; |
| 2281 return this->NullExpressionList(); | 2267 return impl()->NullExpressionList(); |
| 2282 } | 2268 } |
| 2283 *first_spread_arg_loc = spread_arg; | 2269 *first_spread_arg_loc = spread_arg; |
| 2284 | 2270 |
| 2285 if (!maybe_arrow || peek() != Token::ARROW) { | 2271 if (!maybe_arrow || peek() != Token::ARROW) { |
| 2286 if (maybe_arrow) { | 2272 if (maybe_arrow) { |
| 2287 impl()->RewriteNonPattern(classifier, | 2273 impl()->RewriteNonPattern(classifier, |
| 2288 CHECK_OK_CUSTOM(NullExpressionList)); | 2274 CHECK_OK_CUSTOM(NullExpressionList)); |
| 2289 } | 2275 } |
| 2290 if (spread_arg.IsValid()) { | 2276 if (spread_arg.IsValid()) { |
| 2291 // Unspread parameter sequences are translated into array literals in the | 2277 // Unspread parameter sequences are translated into array literals in the |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2513 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2499 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 2514 int pos = peek_position(); | 2500 int pos = peek_position(); |
| 2515 classifier->RecordPatternError(scanner()->peek_location(), | 2501 classifier->RecordPatternError(scanner()->peek_location(), |
| 2516 MessageTemplate::kInvalidDestructuringTarget); | 2502 MessageTemplate::kInvalidDestructuringTarget); |
| 2517 classifier->RecordFormalParameterInitializerError( | 2503 classifier->RecordFormalParameterInitializerError( |
| 2518 scanner()->peek_location(), MessageTemplate::kYieldInParameter); | 2504 scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
| 2519 Expect(Token::YIELD, CHECK_OK); | 2505 Expect(Token::YIELD, CHECK_OK); |
| 2520 ExpressionT generator_object = | 2506 ExpressionT generator_object = |
| 2521 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2507 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
| 2522 // The following initialization is necessary. | 2508 // The following initialization is necessary. |
| 2523 ExpressionT expression = Traits::EmptyExpression(); | 2509 ExpressionT expression = impl()->EmptyExpression(); |
| 2524 bool delegating = false; // yield* | 2510 bool delegating = false; // yield* |
| 2525 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2511 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2526 if (Check(Token::MUL)) delegating = true; | 2512 if (Check(Token::MUL)) delegating = true; |
| 2527 switch (peek()) { | 2513 switch (peek()) { |
| 2528 case Token::EOS: | 2514 case Token::EOS: |
| 2529 case Token::SEMICOLON: | 2515 case Token::SEMICOLON: |
| 2530 case Token::RBRACE: | 2516 case Token::RBRACE: |
| 2531 case Token::RBRACK: | 2517 case Token::RBRACK: |
| 2532 case Token::RPAREN: | 2518 case Token::RPAREN: |
| 2533 case Token::COLON: | 2519 case Token::COLON: |
| 2534 case Token::COMMA: | 2520 case Token::COMMA: |
| 2535 // The above set of tokens is the complete set of tokens that can appear | 2521 // The above set of tokens is the complete set of tokens that can appear |
| 2536 // after an AssignmentExpression, and none of them can start an | 2522 // after an AssignmentExpression, and none of them can start an |
| 2537 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2523 // AssignmentExpression. This allows us to avoid looking for an RHS for |
| 2538 // a regular yield, given only one look-ahead token. | 2524 // a regular yield, given only one look-ahead token. |
| 2539 if (!delegating) break; | 2525 if (!delegating) break; |
| 2540 // Delegating yields require an RHS; fall through. | 2526 // Delegating yields require an RHS; fall through. |
| 2541 default: | 2527 default: |
| 2542 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2528 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
| 2543 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2529 impl()->RewriteNonPattern(classifier, CHECK_OK); |
| 2544 break; | 2530 break; |
| 2545 } | 2531 } |
| 2546 } | 2532 } |
| 2547 | 2533 |
| 2548 if (delegating) { | 2534 if (delegating) { |
| 2549 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2535 return impl()->RewriteYieldStar(generator_object, expression, pos); |
| 2550 } | 2536 } |
| 2551 | 2537 |
| 2552 expression = Traits::BuildIteratorResult(expression, false); | 2538 expression = impl()->BuildIteratorResult(expression, false); |
| 2553 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2539 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| 2554 // TODO(verwaest): Come up with a better solution. | 2540 // TODO(verwaest): Come up with a better solution. |
| 2555 typename Traits::Type::YieldExpression yield = factory()->NewYield( | 2541 typename Traits::Type::YieldExpression yield = factory()->NewYield( |
| 2556 generator_object, expression, pos, Yield::kOnExceptionThrow); | 2542 generator_object, expression, pos, Yield::kOnExceptionThrow); |
| 2557 return yield; | 2543 return yield; |
| 2558 } | 2544 } |
| 2559 | 2545 |
| 2560 template <typename Impl> | 2546 template <typename Impl> |
| 2561 typename ParserBase<Impl>::ExpressionT | 2547 typename ParserBase<Impl>::ExpressionT |
| 2562 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, | 2548 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, |
| 2563 bool* ok) { | 2549 bool* ok) { |
| 2564 // TailCallExpression:: | 2550 // TailCallExpression:: |
| 2565 // 'continue' MemberExpression Arguments | 2551 // 'continue' MemberExpression Arguments |
| 2566 // 'continue' CallExpression Arguments | 2552 // 'continue' CallExpression Arguments |
| 2567 // 'continue' MemberExpression TemplateLiteral | 2553 // 'continue' MemberExpression TemplateLiteral |
| 2568 // 'continue' CallExpression TemplateLiteral | 2554 // 'continue' CallExpression TemplateLiteral |
| 2569 Expect(Token::CONTINUE, CHECK_OK); | 2555 Expect(Token::CONTINUE, CHECK_OK); |
| 2570 int pos = position(); | 2556 int pos = position(); |
| 2571 int sub_expression_pos = peek_position(); | 2557 int sub_expression_pos = peek_position(); |
| 2572 ExpressionT expression = | 2558 ExpressionT expression = |
| 2573 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2559 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 2574 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2560 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2575 | 2561 |
| 2576 Scanner::Location loc(pos, scanner()->location().end_pos); | 2562 Scanner::Location loc(pos, scanner()->location().end_pos); |
| 2577 if (!expression->IsCall()) { | 2563 if (!expression->IsCall()) { |
| 2578 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); | 2564 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
| 2579 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall); | 2565 impl()->ReportMessageAt(sub_loc, |
| 2566 MessageTemplate::kUnexpectedInsideTailCall); |
| 2580 *ok = false; | 2567 *ok = false; |
| 2581 return Traits::EmptyExpression(); | 2568 return impl()->EmptyExpression(); |
| 2582 } | 2569 } |
| 2583 if (impl()->IsDirectEvalCall(expression)) { | 2570 if (impl()->IsDirectEvalCall(expression)) { |
| 2584 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); | 2571 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
| 2585 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval); | 2572 impl()->ReportMessageAt(sub_loc, |
| 2573 MessageTemplate::kUnexpectedTailCallOfEval); |
| 2586 *ok = false; | 2574 *ok = false; |
| 2587 return Traits::EmptyExpression(); | 2575 return impl()->EmptyExpression(); |
| 2588 } | 2576 } |
| 2589 if (!is_strict(language_mode())) { | 2577 if (!is_strict(language_mode())) { |
| 2590 ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall); | 2578 impl()->ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall); |
| 2591 *ok = false; | 2579 *ok = false; |
| 2592 return Traits::EmptyExpression(); | 2580 return impl()->EmptyExpression(); |
| 2593 } | 2581 } |
| 2594 ReturnExprContext return_expr_context = | 2582 ReturnExprContext return_expr_context = |
| 2595 function_state_->return_expr_context(); | 2583 function_state_->return_expr_context(); |
| 2596 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { | 2584 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { |
| 2597 MessageTemplate::Template msg = MessageTemplate::kNone; | 2585 MessageTemplate::Template msg = MessageTemplate::kNone; |
| 2598 switch (return_expr_context) { | 2586 switch (return_expr_context) { |
| 2599 case ReturnExprContext::kInsideValidReturnStatement: | 2587 case ReturnExprContext::kInsideValidReturnStatement: |
| 2600 UNREACHABLE(); | 2588 UNREACHABLE(); |
| 2601 return Traits::EmptyExpression(); | 2589 return impl()->EmptyExpression(); |
| 2602 case ReturnExprContext::kInsideValidBlock: | 2590 case ReturnExprContext::kInsideValidBlock: |
| 2603 msg = MessageTemplate::kUnexpectedTailCall; | 2591 msg = MessageTemplate::kUnexpectedTailCall; |
| 2604 break; | 2592 break; |
| 2605 case ReturnExprContext::kInsideTryBlock: | 2593 case ReturnExprContext::kInsideTryBlock: |
| 2606 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; | 2594 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; |
| 2607 break; | 2595 break; |
| 2608 case ReturnExprContext::kInsideForInOfBody: | 2596 case ReturnExprContext::kInsideForInOfBody: |
| 2609 msg = MessageTemplate::kUnexpectedTailCallInForInOf; | 2597 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
| 2610 break; | 2598 break; |
| 2611 } | 2599 } |
| 2612 ReportMessageAt(loc, msg); | 2600 impl()->ReportMessageAt(loc, msg); |
| 2613 *ok = false; | 2601 *ok = false; |
| 2614 return Traits::EmptyExpression(); | 2602 return impl()->EmptyExpression(); |
| 2615 } | 2603 } |
| 2616 classifier->RecordTailCallExpressionError( | 2604 classifier->RecordTailCallExpressionError( |
| 2617 loc, MessageTemplate::kUnexpectedTailCall); | 2605 loc, MessageTemplate::kUnexpectedTailCall); |
| 2618 function_state_->AddExplicitTailCallExpression(expression, loc); | 2606 function_state_->AddExplicitTailCallExpression(expression, loc); |
| 2619 return expression; | 2607 return expression; |
| 2620 } | 2608 } |
| 2621 | 2609 |
| 2622 // Precedence = 3 | 2610 // Precedence = 3 |
| 2623 template <typename Impl> | 2611 template <typename Impl> |
| 2624 typename ParserBase<Impl>::ExpressionT | 2612 typename ParserBase<Impl>::ExpressionT |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2733 int pos = position(); | 2721 int pos = position(); |
| 2734 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2722 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2735 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2723 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2736 impl()->RewriteNonPattern(classifier, CHECK_OK); | 2724 impl()->RewriteNonPattern(classifier, CHECK_OK); |
| 2737 | 2725 |
| 2738 if (op == Token::DELETE && is_strict(language_mode())) { | 2726 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2739 if (impl()->IsIdentifier(expression)) { | 2727 if (impl()->IsIdentifier(expression)) { |
| 2740 // "delete identifier" is a syntax error in strict mode. | 2728 // "delete identifier" is a syntax error in strict mode. |
| 2741 ReportMessage(MessageTemplate::kStrictDelete); | 2729 ReportMessage(MessageTemplate::kStrictDelete); |
| 2742 *ok = false; | 2730 *ok = false; |
| 2743 return this->EmptyExpression(); | 2731 return impl()->EmptyExpression(); |
| 2744 } | 2732 } |
| 2745 } | 2733 } |
| 2746 | 2734 |
| 2747 if (peek() == Token::EXP) { | 2735 if (peek() == Token::EXP) { |
| 2748 ReportUnexpectedToken(Next()); | 2736 ReportUnexpectedToken(Next()); |
| 2749 *ok = false; | 2737 *ok = false; |
| 2750 return this->EmptyExpression(); | 2738 return impl()->EmptyExpression(); |
| 2751 } | 2739 } |
| 2752 | 2740 |
| 2753 // Allow Traits do rewrite the expression. | 2741 // Allow Traits do rewrite the expression. |
| 2754 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2742 return impl()->BuildUnaryExpression(expression, op, pos); |
| 2755 } else if (Token::IsCountOp(op)) { | 2743 } else if (Token::IsCountOp(op)) { |
| 2756 BindingPatternUnexpectedToken(classifier); | 2744 BindingPatternUnexpectedToken(classifier); |
| 2757 ArrowFormalParametersUnexpectedToken(classifier); | 2745 ArrowFormalParametersUnexpectedToken(classifier); |
| 2758 op = Next(); | 2746 op = Next(); |
| 2759 int beg_pos = peek_position(); | 2747 int beg_pos = peek_position(); |
| 2760 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2748 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 2761 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2749 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2762 expression = this->CheckAndRewriteReferenceExpression( | 2750 expression = this->CheckAndRewriteReferenceExpression( |
| 2763 expression, beg_pos, scanner()->location().end_pos, | 2751 expression, beg_pos, scanner()->location().end_pos, |
| 2764 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2752 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2880 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); | 2868 args = ParseArguments(&spread_pos, true, &async_classifier, CHECK_OK); |
| 2881 if (peek() == Token::ARROW) { | 2869 if (peek() == Token::ARROW) { |
| 2882 if (fni_) { | 2870 if (fni_) { |
| 2883 fni_->RemoveAsyncKeywordFromEnd(); | 2871 fni_->RemoveAsyncKeywordFromEnd(); |
| 2884 } | 2872 } |
| 2885 ValidateBindingPattern(&async_classifier, CHECK_OK); | 2873 ValidateBindingPattern(&async_classifier, CHECK_OK); |
| 2886 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { | 2874 if (!async_classifier.is_valid_async_arrow_formal_parameters()) { |
| 2887 ReportClassifierError( | 2875 ReportClassifierError( |
| 2888 async_classifier.async_arrow_formal_parameters_error()); | 2876 async_classifier.async_arrow_formal_parameters_error()); |
| 2889 *ok = false; | 2877 *ok = false; |
| 2890 return this->EmptyExpression(); | 2878 return impl()->EmptyExpression(); |
| 2891 } | 2879 } |
| 2892 if (args->length()) { | 2880 if (args->length()) { |
| 2893 // async ( Arguments ) => ... | 2881 // async ( Arguments ) => ... |
| 2894 return Traits::ExpressionListToExpression(args); | 2882 return Traits::ExpressionListToExpression(args); |
| 2895 } | 2883 } |
| 2896 // async () => ... | 2884 // async () => ... |
| 2897 return factory()->NewEmptyParentheses(pos); | 2885 return factory()->NewEmptyParentheses(pos); |
| 2898 } else { | 2886 } else { |
| 2899 classifier->Accumulate(&async_classifier, | 2887 classifier->Accumulate(&async_classifier, |
| 2900 ExpressionClassifier::AllProductions); | 2888 ExpressionClassifier::AllProductions); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3050 Consume(Token::FUNCTION); | 3038 Consume(Token::FUNCTION); |
| 3051 int function_token_position = position(); | 3039 int function_token_position = position(); |
| 3052 | 3040 |
| 3053 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { | 3041 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { |
| 3054 // function.sent | 3042 // function.sent |
| 3055 int pos = position(); | 3043 int pos = position(); |
| 3056 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); | 3044 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); |
| 3057 | 3045 |
| 3058 if (!is_generator()) { | 3046 if (!is_generator()) { |
| 3059 // TODO(neis): allow escaping into closures? | 3047 // TODO(neis): allow escaping into closures? |
| 3060 ReportMessageAt(scanner()->location(), | 3048 impl()->ReportMessageAt(scanner()->location(), |
| 3061 MessageTemplate::kUnexpectedFunctionSent); | 3049 MessageTemplate::kUnexpectedFunctionSent); |
| 3062 *ok = false; | 3050 *ok = false; |
| 3063 return this->EmptyExpression(); | 3051 return impl()->EmptyExpression(); |
| 3064 } | 3052 } |
| 3065 | 3053 |
| 3066 return this->FunctionSentExpression(factory(), pos); | 3054 return this->FunctionSentExpression(factory(), pos); |
| 3067 } | 3055 } |
| 3068 | 3056 |
| 3069 FunctionKind function_kind = Check(Token::MUL) | 3057 FunctionKind function_kind = Check(Token::MUL) |
| 3070 ? FunctionKind::kGeneratorFunction | 3058 ? FunctionKind::kGeneratorFunction |
| 3071 : FunctionKind::kNormalFunction; | 3059 : FunctionKind::kNormalFunction; |
| 3072 IdentifierT name = this->EmptyIdentifier(); | 3060 IdentifierT name = impl()->EmptyIdentifier(); |
| 3073 bool is_strict_reserved_name = false; | 3061 bool is_strict_reserved_name = false; |
| 3074 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3062 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3075 FunctionLiteral::FunctionType function_type = | 3063 FunctionLiteral::FunctionType function_type = |
| 3076 FunctionLiteral::kAnonymousExpression; | 3064 FunctionLiteral::kAnonymousExpression; |
| 3077 if (peek_any_identifier()) { | 3065 if (peek_any_identifier()) { |
| 3078 name = ParseIdentifierOrStrictReservedWord( | 3066 name = ParseIdentifierOrStrictReservedWord( |
| 3079 function_kind, &is_strict_reserved_name, CHECK_OK); | 3067 function_kind, &is_strict_reserved_name, CHECK_OK); |
| 3080 function_name_location = scanner()->location(); | 3068 function_name_location = scanner()->location(); |
| 3081 function_type = FunctionLiteral::kNamedExpression; | 3069 function_type = FunctionLiteral::kNamedExpression; |
| 3082 } | 3070 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3114 } | 3102 } |
| 3115 // new super() is never allowed. | 3103 // new super() is never allowed. |
| 3116 // super() is only allowed in derived constructor | 3104 // super() is only allowed in derived constructor |
| 3117 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3105 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3118 // TODO(rossberg): This might not be the correct FunctionState for the | 3106 // TODO(rossberg): This might not be the correct FunctionState for the |
| 3119 // method here. | 3107 // method here. |
| 3120 return this->NewSuperCallReference(factory(), pos); | 3108 return this->NewSuperCallReference(factory(), pos); |
| 3121 } | 3109 } |
| 3122 } | 3110 } |
| 3123 | 3111 |
| 3124 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); | 3112 impl()->ReportMessageAt(scanner()->location(), |
| 3113 MessageTemplate::kUnexpectedSuper); |
| 3125 *ok = false; | 3114 *ok = false; |
| 3126 return this->EmptyExpression(); | 3115 return impl()->EmptyExpression(); |
| 3127 } | 3116 } |
| 3128 | 3117 |
| 3129 template <typename Impl> | 3118 template <typename Impl> |
| 3130 void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name, | 3119 void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name, |
| 3131 const char* full_name, int pos, | 3120 const char* full_name, int pos, |
| 3132 bool* ok) { | 3121 bool* ok) { |
| 3133 Consume(Token::PERIOD); | 3122 Consume(Token::PERIOD); |
| 3134 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void)); | 3123 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void)); |
| 3135 if (scanner()->literal_contains_escapes()) { | 3124 if (scanner()->literal_contains_escapes()) { |
| 3136 Traits::ReportMessageAt( | 3125 impl()->ReportMessageAt( |
| 3137 Scanner::Location(pos, scanner()->location().end_pos), | 3126 Scanner::Location(pos, scanner()->location().end_pos), |
| 3138 MessageTemplate::kInvalidEscapedMetaProperty, full_name); | 3127 MessageTemplate::kInvalidEscapedMetaProperty, full_name); |
| 3139 *ok = false; | 3128 *ok = false; |
| 3140 } | 3129 } |
| 3141 } | 3130 } |
| 3142 | 3131 |
| 3143 template <typename Impl> | 3132 template <typename Impl> |
| 3144 typename ParserBase<Impl>::ExpressionT | 3133 typename ParserBase<Impl>::ExpressionT |
| 3145 ParserBase<Impl>::ParseNewTargetExpression(bool* ok) { | 3134 ParserBase<Impl>::ParseNewTargetExpression(bool* ok) { |
| 3146 int pos = position(); | 3135 int pos = position(); |
| 3147 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); | 3136 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); |
| 3148 | 3137 |
| 3149 if (!GetReceiverScope()->is_function_scope()) { | 3138 if (!GetReceiverScope()->is_function_scope()) { |
| 3150 ReportMessageAt(scanner()->location(), | 3139 impl()->ReportMessageAt(scanner()->location(), |
| 3151 MessageTemplate::kUnexpectedNewTarget); | 3140 MessageTemplate::kUnexpectedNewTarget); |
| 3152 *ok = false; | 3141 *ok = false; |
| 3153 return this->EmptyExpression(); | 3142 return impl()->EmptyExpression(); |
| 3154 } | 3143 } |
| 3155 | 3144 |
| 3156 return this->NewTargetExpression(pos); | 3145 return this->NewTargetExpression(pos); |
| 3157 } | 3146 } |
| 3158 | 3147 |
| 3159 template <typename Impl> | 3148 template <typename Impl> |
| 3160 typename ParserBase<Impl>::ExpressionT | 3149 typename ParserBase<Impl>::ExpressionT |
| 3161 ParserBase<Impl>::ParseMemberExpressionContinuation( | 3150 ParserBase<Impl>::ParseMemberExpressionContinuation( |
| 3162 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3151 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
| 3163 bool* ok) { | 3152 bool* ok) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3215 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3204 expression->AsFunctionLiteral()->set_should_eager_compile(); |
| 3216 } | 3205 } |
| 3217 } | 3206 } |
| 3218 expression = | 3207 expression = |
| 3219 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | 3208 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); |
| 3220 break; | 3209 break; |
| 3221 } | 3210 } |
| 3222 case Token::ILLEGAL: { | 3211 case Token::ILLEGAL: { |
| 3223 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); | 3212 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); |
| 3224 *ok = false; | 3213 *ok = false; |
| 3225 return this->EmptyExpression(); | 3214 return impl()->EmptyExpression(); |
| 3226 } | 3215 } |
| 3227 default: | 3216 default: |
| 3228 return expression; | 3217 return expression; |
| 3229 } | 3218 } |
| 3230 } | 3219 } |
| 3231 DCHECK(false); | 3220 DCHECK(false); |
| 3232 return this->EmptyExpression(); | 3221 return impl()->EmptyExpression(); |
| 3233 } | 3222 } |
| 3234 | 3223 |
| 3235 template <typename Impl> | 3224 template <typename Impl> |
| 3236 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, | 3225 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, |
| 3237 ExpressionClassifier* classifier, | 3226 ExpressionClassifier* classifier, |
| 3238 bool* ok) { | 3227 bool* ok) { |
| 3239 // FormalParameter[Yield,GeneratorParameter] : | 3228 // FormalParameter[Yield,GeneratorParameter] : |
| 3240 // BindingElement[?Yield, ?GeneratorParameter] | 3229 // BindingElement[?Yield, ?GeneratorParameter] |
| 3241 bool is_rest = parameters->has_rest; | 3230 bool is_rest = parameters->has_rest; |
| 3242 | 3231 |
| 3243 ExpressionT pattern = | 3232 ExpressionT pattern = |
| 3244 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); | 3233 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); |
| 3245 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); | 3234 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); |
| 3246 | 3235 |
| 3247 if (!impl()->IsIdentifier(pattern)) { | 3236 if (!impl()->IsIdentifier(pattern)) { |
| 3248 parameters->is_simple = false; | 3237 parameters->is_simple = false; |
| 3249 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); | 3238 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); |
| 3250 classifier->RecordNonSimpleParameter(); | 3239 classifier->RecordNonSimpleParameter(); |
| 3251 } | 3240 } |
| 3252 | 3241 |
| 3253 ExpressionT initializer = Traits::EmptyExpression(); | 3242 ExpressionT initializer = impl()->EmptyExpression(); |
| 3254 if (!is_rest && Check(Token::ASSIGN)) { | 3243 if (!is_rest && Check(Token::ASSIGN)) { |
| 3255 ExpressionClassifier init_classifier(this); | 3244 ExpressionClassifier init_classifier(this); |
| 3256 initializer = ParseAssignmentExpression(true, &init_classifier, | 3245 initializer = ParseAssignmentExpression(true, &init_classifier, |
| 3257 CHECK_OK_CUSTOM(Void)); | 3246 CHECK_OK_CUSTOM(Void)); |
| 3258 impl()->RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3247 impl()->RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); |
| 3259 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3248 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); |
| 3260 parameters->is_simple = false; | 3249 parameters->is_simple = false; |
| 3261 init_classifier.Discard(); | 3250 init_classifier.Discard(); |
| 3262 classifier->RecordNonSimpleParameter(); | 3251 classifier->RecordNonSimpleParameter(); |
| 3263 | 3252 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3291 *ok = false; | 3280 *ok = false; |
| 3292 return; | 3281 return; |
| 3293 } | 3282 } |
| 3294 parameters->has_rest = Check(Token::ELLIPSIS); | 3283 parameters->has_rest = Check(Token::ELLIPSIS); |
| 3295 ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void)); | 3284 ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void)); |
| 3296 | 3285 |
| 3297 if (parameters->has_rest) { | 3286 if (parameters->has_rest) { |
| 3298 parameters->is_simple = false; | 3287 parameters->is_simple = false; |
| 3299 classifier->RecordNonSimpleParameter(); | 3288 classifier->RecordNonSimpleParameter(); |
| 3300 if (peek() == Token::COMMA) { | 3289 if (peek() == Token::COMMA) { |
| 3301 ReportMessageAt(scanner()->peek_location(), | 3290 impl()->ReportMessageAt(scanner()->peek_location(), |
| 3302 MessageTemplate::kParamAfterRest); | 3291 MessageTemplate::kParamAfterRest); |
| 3303 *ok = false; | 3292 *ok = false; |
| 3304 return; | 3293 return; |
| 3305 } | 3294 } |
| 3306 break; | 3295 break; |
| 3307 } | 3296 } |
| 3308 if (!Check(Token::COMMA)) break; | 3297 if (!Check(Token::COMMA)) break; |
| 3309 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { | 3298 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { |
| 3310 // allow the trailing comma | 3299 // allow the trailing comma |
| 3311 break; | 3300 break; |
| 3312 } | 3301 } |
| 3313 } | 3302 } |
| 3314 } | 3303 } |
| 3315 | 3304 |
| 3316 for (int i = 0; i < parameters->Arity(); ++i) { | 3305 for (int i = 0; i < parameters->Arity(); ++i) { |
| 3317 auto parameter = parameters->at(i); | 3306 auto parameter = parameters->at(i); |
| 3318 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); | 3307 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); |
| 3319 } | 3308 } |
| 3320 } | 3309 } |
| 3321 | 3310 |
| 3322 template <typename Impl> | 3311 template <typename Impl> |
| 3323 void ParserBase<Impl>::CheckArityRestrictions(int param_count, | 3312 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
| 3324 FunctionKind function_kind, | 3313 FunctionKind function_kind, |
| 3325 bool has_rest, | 3314 bool has_rest, |
| 3326 int formals_start_pos, | 3315 int formals_start_pos, |
| 3327 int formals_end_pos, bool* ok) { | 3316 int formals_end_pos, bool* ok) { |
| 3328 if (IsGetterFunction(function_kind)) { | 3317 if (IsGetterFunction(function_kind)) { |
| 3329 if (param_count != 0) { | 3318 if (param_count != 0) { |
| 3330 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3319 impl()->ReportMessageAt( |
| 3331 MessageTemplate::kBadGetterArity); | 3320 Scanner::Location(formals_start_pos, formals_end_pos), |
| 3321 MessageTemplate::kBadGetterArity); |
| 3332 *ok = false; | 3322 *ok = false; |
| 3333 } | 3323 } |
| 3334 } else if (IsSetterFunction(function_kind)) { | 3324 } else if (IsSetterFunction(function_kind)) { |
| 3335 if (param_count != 1) { | 3325 if (param_count != 1) { |
| 3336 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3326 impl()->ReportMessageAt( |
| 3337 MessageTemplate::kBadSetterArity); | 3327 Scanner::Location(formals_start_pos, formals_end_pos), |
| 3328 MessageTemplate::kBadSetterArity); |
| 3338 *ok = false; | 3329 *ok = false; |
| 3339 } | 3330 } |
| 3340 if (has_rest) { | 3331 if (has_rest) { |
| 3341 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3332 impl()->ReportMessageAt( |
| 3342 MessageTemplate::kBadSetterRestParameter); | 3333 Scanner::Location(formals_start_pos, formals_end_pos), |
| 3334 MessageTemplate::kBadSetterRestParameter); |
| 3343 *ok = false; | 3335 *ok = false; |
| 3344 } | 3336 } |
| 3345 } | 3337 } |
| 3346 } | 3338 } |
| 3347 | 3339 |
| 3348 template <typename Impl> | 3340 template <typename Impl> |
| 3349 bool ParserBase<Impl>::IsNextLetKeyword() { | 3341 bool ParserBase<Impl>::IsNextLetKeyword() { |
| 3350 DCHECK(peek() == Token::LET); | 3342 DCHECK(peek() == Token::LET); |
| 3351 Token::Value next_next = PeekAhead(); | 3343 Token::Value next_next = PeekAhead(); |
| 3352 switch (next_next) { | 3344 switch (next_next) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3392 typename ParserBase<Impl>::ExpressionT | 3384 typename ParserBase<Impl>::ExpressionT |
| 3393 ParserBase<Impl>::ParseArrowFunctionLiteral( | 3385 ParserBase<Impl>::ParseArrowFunctionLiteral( |
| 3394 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, | 3386 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
| 3395 const ExpressionClassifier& formals_classifier, bool* ok) { | 3387 const ExpressionClassifier& formals_classifier, bool* ok) { |
| 3396 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3388 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3397 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3389 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3398 // `=> ...` is never a valid expression, so report as syntax error. | 3390 // `=> ...` is never a valid expression, so report as syntax error. |
| 3399 // If next token is not `=>`, it's a syntax error anyways. | 3391 // If next token is not `=>`, it's a syntax error anyways. |
| 3400 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3392 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3401 *ok = false; | 3393 *ok = false; |
| 3402 return this->EmptyExpression(); | 3394 return impl()->EmptyExpression(); |
| 3403 } | 3395 } |
| 3404 | 3396 |
| 3405 typename Traits::Type::StatementList body; | 3397 typename Traits::Type::StatementList body; |
| 3406 int num_parameters = formal_parameters.scope->num_parameters(); | 3398 int num_parameters = formal_parameters.scope->num_parameters(); |
| 3407 int materialized_literal_count = -1; | 3399 int materialized_literal_count = -1; |
| 3408 int expected_property_count = -1; | 3400 int expected_property_count = -1; |
| 3409 | 3401 |
| 3410 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; | 3402 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
| 3411 { | 3403 { |
| 3412 FunctionState function_state(&function_state_, &scope_state_, | 3404 FunctionState function_state(&function_state_, &scope_state_, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3428 if (is_lazily_parsed) { | 3420 if (is_lazily_parsed) { |
| 3429 body = this->NewStatementList(0, zone()); | 3421 body = this->NewStatementList(0, zone()); |
| 3430 impl()->SkipLazyFunctionBody(&materialized_literal_count, | 3422 impl()->SkipLazyFunctionBody(&materialized_literal_count, |
| 3431 &expected_property_count, CHECK_OK); | 3423 &expected_property_count, CHECK_OK); |
| 3432 if (formal_parameters.materialized_literals_count > 0) { | 3424 if (formal_parameters.materialized_literals_count > 0) { |
| 3433 materialized_literal_count += | 3425 materialized_literal_count += |
| 3434 formal_parameters.materialized_literals_count; | 3426 formal_parameters.materialized_literals_count; |
| 3435 } | 3427 } |
| 3436 } else { | 3428 } else { |
| 3437 body = impl()->ParseEagerFunctionBody( | 3429 body = impl()->ParseEagerFunctionBody( |
| 3438 this->EmptyIdentifier(), kNoSourcePosition, formal_parameters, | 3430 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, |
| 3439 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3431 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| 3440 materialized_literal_count = | 3432 materialized_literal_count = |
| 3441 function_state.materialized_literal_count(); | 3433 function_state.materialized_literal_count(); |
| 3442 expected_property_count = function_state.expected_property_count(); | 3434 expected_property_count = function_state.expected_property_count(); |
| 3443 } | 3435 } |
| 3444 } else { | 3436 } else { |
| 3445 // Single-expression body | 3437 // Single-expression body |
| 3446 int pos = position(); | 3438 int pos = position(); |
| 3447 DCHECK(ReturnExprContext::kInsideValidBlock == | 3439 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 3448 function_state_->return_expr_context()); | 3440 function_state_->return_expr_context()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3485 if (is_strict(language_mode())) { | 3477 if (is_strict(language_mode())) { |
| 3486 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3478 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
| 3487 scanner()->location().end_pos, CHECK_OK); | 3479 scanner()->location().end_pos, CHECK_OK); |
| 3488 } | 3480 } |
| 3489 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3481 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
| 3490 | 3482 |
| 3491 impl()->RewriteDestructuringAssignments(); | 3483 impl()->RewriteDestructuringAssignments(); |
| 3492 } | 3484 } |
| 3493 | 3485 |
| 3494 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3486 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 3495 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3487 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
| 3496 materialized_literal_count, expected_property_count, num_parameters, | 3488 materialized_literal_count, expected_property_count, num_parameters, |
| 3497 FunctionLiteral::kNoDuplicateParameters, | 3489 FunctionLiteral::kNoDuplicateParameters, |
| 3498 FunctionLiteral::kAnonymousExpression, | 3490 FunctionLiteral::kAnonymousExpression, |
| 3499 FunctionLiteral::kShouldLazyCompile, arrow_kind, | 3491 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
| 3500 formal_parameters.scope->start_position()); | 3492 formal_parameters.scope->start_position()); |
| 3501 | 3493 |
| 3502 function_literal->set_function_token_position( | 3494 function_literal->set_function_token_position( |
| 3503 formal_parameters.scope->start_position()); | 3495 formal_parameters.scope->start_position()); |
| 3504 | 3496 |
| 3505 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); | 3497 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3541 Token::Value next; | 3533 Token::Value next; |
| 3542 | 3534 |
| 3543 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, | 3535 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, |
| 3544 // and repeat if the following token is a TEMPLATE_SPAN as well (in this | 3536 // and repeat if the following token is a TEMPLATE_SPAN as well (in this |
| 3545 // case, representing a TemplateMiddle). | 3537 // case, representing a TemplateMiddle). |
| 3546 | 3538 |
| 3547 do { | 3539 do { |
| 3548 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3540 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
| 3549 next = peek(); | 3541 next = peek(); |
| 3550 if (next == Token::EOS) { | 3542 if (next == Token::EOS) { |
| 3551 ReportMessageAt(Scanner::Location(start, peek_position()), | 3543 impl()->ReportMessageAt(Scanner::Location(start, peek_position()), |
| 3552 MessageTemplate::kUnterminatedTemplate); | 3544 MessageTemplate::kUnterminatedTemplate); |
| 3553 *ok = false; | 3545 *ok = false; |
| 3554 return Traits::EmptyExpression(); | 3546 return impl()->EmptyExpression(); |
| 3555 } else if (next == Token::ILLEGAL) { | 3547 } else if (next == Token::ILLEGAL) { |
| 3556 Traits::ReportMessageAt( | 3548 impl()->ReportMessageAt( |
| 3557 Scanner::Location(position() + 1, peek_position()), | 3549 Scanner::Location(position() + 1, peek_position()), |
| 3558 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3550 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3559 *ok = false; | 3551 *ok = false; |
| 3560 return Traits::EmptyExpression(); | 3552 return impl()->EmptyExpression(); |
| 3561 } | 3553 } |
| 3562 | 3554 |
| 3563 int expr_pos = peek_position(); | 3555 int expr_pos = peek_position(); |
| 3564 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3556 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
| 3565 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3557 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 3566 impl()->RewriteNonPattern(classifier, CHECK_OK); | 3558 impl()->RewriteNonPattern(classifier, CHECK_OK); |
| 3567 impl()->AddTemplateExpression(&ts, expression); | 3559 impl()->AddTemplateExpression(&ts, expression); |
| 3568 | 3560 |
| 3569 if (peek() != Token::RBRACE) { | 3561 if (peek() != Token::RBRACE) { |
| 3570 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3562 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
| 3571 MessageTemplate::kUnterminatedTemplateExpr); | 3563 MessageTemplate::kUnterminatedTemplateExpr); |
| 3572 *ok = false; | 3564 *ok = false; |
| 3573 return Traits::EmptyExpression(); | 3565 return impl()->EmptyExpression(); |
| 3574 } | 3566 } |
| 3575 | 3567 |
| 3576 // If we didn't die parsing that expression, our next token should be a | 3568 // If we didn't die parsing that expression, our next token should be a |
| 3577 // TEMPLATE_SPAN or TEMPLATE_TAIL. | 3569 // TEMPLATE_SPAN or TEMPLATE_TAIL. |
| 3578 next = scanner()->ScanTemplateContinuation(); | 3570 next = scanner()->ScanTemplateContinuation(); |
| 3579 Next(); | 3571 Next(); |
| 3580 pos = position(); | 3572 pos = position(); |
| 3581 | 3573 |
| 3582 if (next == Token::EOS) { | 3574 if (next == Token::EOS) { |
| 3583 ReportMessageAt(Scanner::Location(start, pos), | 3575 impl()->ReportMessageAt(Scanner::Location(start, pos), |
| 3584 MessageTemplate::kUnterminatedTemplate); | 3576 MessageTemplate::kUnterminatedTemplate); |
| 3585 *ok = false; | 3577 *ok = false; |
| 3586 return Traits::EmptyExpression(); | 3578 return impl()->EmptyExpression(); |
| 3587 } else if (next == Token::ILLEGAL) { | 3579 } else if (next == Token::ILLEGAL) { |
| 3588 Traits::ReportMessageAt( | 3580 impl()->ReportMessageAt( |
| 3589 Scanner::Location(position() + 1, peek_position()), | 3581 Scanner::Location(position() + 1, peek_position()), |
| 3590 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3582 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3591 *ok = false; | 3583 *ok = false; |
| 3592 return Traits::EmptyExpression(); | 3584 return impl()->EmptyExpression(); |
| 3593 } | 3585 } |
| 3594 | 3586 |
| 3595 impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3587 impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
| 3596 } while (next == Token::TEMPLATE_SPAN); | 3588 } while (next == Token::TEMPLATE_SPAN); |
| 3597 | 3589 |
| 3598 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3590 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
| 3599 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3591 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
| 3600 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3592 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
| 3601 return impl()->CloseTemplateLiteral(&ts, start, tag); | 3593 return impl()->CloseTemplateLiteral(&ts, start, tag); |
| 3602 } | 3594 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3613 template <typename Impl> | 3605 template <typename Impl> |
| 3614 typename ParserBase<Impl>::ExpressionT | 3606 typename ParserBase<Impl>::ExpressionT |
| 3615 ParserBase<Impl>::CheckAndRewriteReferenceExpression( | 3607 ParserBase<Impl>::CheckAndRewriteReferenceExpression( |
| 3616 ExpressionT expression, int beg_pos, int end_pos, | 3608 ExpressionT expression, int beg_pos, int end_pos, |
| 3617 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 3609 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
| 3618 if (impl()->IsIdentifier(expression) && is_strict(language_mode()) && | 3610 if (impl()->IsIdentifier(expression) && is_strict(language_mode()) && |
| 3619 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) { | 3611 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) { |
| 3620 ReportMessageAt(Scanner::Location(beg_pos, end_pos), | 3612 ReportMessageAt(Scanner::Location(beg_pos, end_pos), |
| 3621 MessageTemplate::kStrictEvalArguments, kSyntaxError); | 3613 MessageTemplate::kStrictEvalArguments, kSyntaxError); |
| 3622 *ok = false; | 3614 *ok = false; |
| 3623 return this->EmptyExpression(); | 3615 return impl()->EmptyExpression(); |
| 3624 } | 3616 } |
| 3625 if (expression->IsValidReferenceExpression()) { | 3617 if (expression->IsValidReferenceExpression()) { |
| 3626 return expression; | 3618 return expression; |
| 3627 } | 3619 } |
| 3628 if (expression->IsCall()) { | 3620 if (expression->IsCall()) { |
| 3629 // If it is a call, make it a runtime error for legacy web compatibility. | 3621 // If it is a call, make it a runtime error for legacy web compatibility. |
| 3630 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3622 // Rewrite `expr' to `expr[throw ReferenceError]'. |
| 3631 ExpressionT error = this->NewThrowReferenceError(message, beg_pos); | 3623 ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos); |
| 3632 return factory()->NewProperty(expression, error, beg_pos); | 3624 return factory()->NewProperty(expression, error, beg_pos); |
| 3633 } | 3625 } |
| 3634 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); | 3626 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); |
| 3635 *ok = false; | 3627 *ok = false; |
| 3636 return this->EmptyExpression(); | 3628 return impl()->EmptyExpression(); |
| 3637 } | 3629 } |
| 3638 | 3630 |
| 3639 template <typename Impl> | 3631 template <typename Impl> |
| 3640 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { | 3632 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { |
| 3641 return IsAssignableIdentifier(expression) || expression->IsProperty(); | 3633 return IsAssignableIdentifier(expression) || expression->IsProperty(); |
| 3642 } | 3634 } |
| 3643 | 3635 |
| 3644 template <typename Impl> | 3636 template <typename Impl> |
| 3645 void ParserBase<Impl>::CheckDestructuringElement( | 3637 void ParserBase<Impl>::CheckDestructuringElement( |
| 3646 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3638 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 has_seen_constructor_ = true; | 3702 has_seen_constructor_ = true; |
| 3711 return; | 3703 return; |
| 3712 } | 3704 } |
| 3713 } | 3705 } |
| 3714 | 3706 |
| 3715 | 3707 |
| 3716 } // namespace internal | 3708 } // namespace internal |
| 3717 } // namespace v8 | 3709 } // namespace v8 |
| 3718 | 3710 |
| 3719 #endif // V8_PARSING_PARSER_BASE_H | 3711 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |