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 |