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_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 void CheckFunctionParameterNames(LanguageMode language_mode, | 520 void CheckFunctionParameterNames(LanguageMode language_mode, |
521 bool strict_params, | 521 bool strict_params, |
522 const FormalParameterErrorLocations& locs, | 522 const FormalParameterErrorLocations& locs, |
523 bool* ok) { | 523 bool* ok) { |
524 if (is_sloppy(language_mode) && !strict_params) return; | 524 if (is_sloppy(language_mode) && !strict_params) return; |
525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { | 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { |
526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); | 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); |
527 *ok = false; | 527 *ok = false; |
528 return; | 528 return; |
529 } | 529 } |
| 530 if (is_strict(language_mode) && locs.reserved.IsValid()) { |
| 531 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); |
| 532 *ok = false; |
| 533 return; |
| 534 } |
530 if (is_strong(language_mode) && locs.undefined.IsValid()) { | 535 if (is_strong(language_mode) && locs.undefined.IsValid()) { |
531 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); | 536 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); |
532 *ok = false; | 537 *ok = false; |
533 return; | 538 return; |
534 } | 539 } |
535 // TODO(arv): When we add support for destructuring in setters we also need | 540 // TODO(arv): When we add support for destructuring in setters we also need |
536 // to check for duplicate names. | 541 // to check for duplicate names. |
537 if (locs.duplicate.IsValid()) { | 542 if (locs.duplicate.IsValid()) { |
538 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); | 543 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); |
539 *ok = false; | 544 *ok = false; |
540 return; | 545 return; |
541 } | 546 } |
542 if (locs.reserved.IsValid()) { | |
543 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); | |
544 *ok = false; | |
545 return; | |
546 } | |
547 } | 547 } |
548 | 548 |
549 // Determine precedence of given token. | 549 // Determine precedence of given token. |
550 static int Precedence(Token::Value token, bool accept_IN) { | 550 static int Precedence(Token::Value token, bool accept_IN) { |
551 if (token == Token::IN && !accept_IN) | 551 if (token == Token::IN && !accept_IN) |
552 return 0; // 0 precedence will terminate binary expression parsing | 552 return 0; // 0 precedence will terminate binary expression parsing |
553 return Token::Precedence(token); | 553 return Token::Precedence(token); |
554 } | 554 } |
555 | 555 |
556 typename Traits::Type::Factory* factory() { | 556 typename Traits::Type::Factory* factory() { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 ExpressionT ParseYieldExpression(bool* ok); | 614 ExpressionT ParseYieldExpression(bool* ok); |
615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
617 ExpressionT ParseUnaryExpression(bool* ok); | 617 ExpressionT ParseUnaryExpression(bool* ok); |
618 ExpressionT ParsePostfixExpression(bool* ok); | 618 ExpressionT ParsePostfixExpression(bool* ok); |
619 ExpressionT ParseLeftHandSideExpression(bool* ok); | 619 ExpressionT ParseLeftHandSideExpression(bool* ok); |
620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
621 ExpressionT ParseMemberExpression(bool* ok); | 621 ExpressionT ParseMemberExpression(bool* ok); |
622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
623 bool* ok); | 623 bool* ok); |
624 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 624 ExpressionT ParseArrowFunctionLiteral( |
625 bool* ok); | 625 Scope* function_scope, const FormalParameterErrorLocations& error_locs, |
| 626 bool has_rest, bool* ok); |
626 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
627 void AddTemplateExpression(ExpressionT); | 628 void AddTemplateExpression(ExpressionT); |
628 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
629 | 630 |
630 void ParseFormalParameter(FormalParameterScopeT* scope, | 631 void ParseFormalParameter(FormalParameterScopeT* scope, |
631 FormalParameterErrorLocations* locs, bool is_rest, | 632 FormalParameterErrorLocations* locs, bool is_rest, |
632 bool* ok); | 633 bool* ok); |
633 int ParseFormalParameterList(FormalParameterScopeT* scope, | 634 int ParseFormalParameterList(FormalParameterScopeT* scope, |
634 FormalParameterErrorLocations* locs, | 635 FormalParameterErrorLocations* locs, |
635 bool* has_rest, bool* ok); | 636 bool* has_rest, bool* ok); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 ValidArrowParam valid_arrow_param_list = | 840 ValidArrowParam valid_arrow_param_list = |
840 (op == Token::COMMA && !left.is_parenthesized() && | 841 (op == Token::COMMA && !left.is_parenthesized() && |
841 !right.is_parenthesized()) ? | 842 !right.is_parenthesized()) ? |
842 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) | 843 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) |
843 : kInvalidArrowParam; | 844 : kInvalidArrowParam; |
844 return PreParserExpression( | 845 return PreParserExpression( |
845 TypeField::encode(kBinaryOperationExpression) | | 846 TypeField::encode(kBinaryOperationExpression) | |
846 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 847 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
847 } | 848 } |
848 | 849 |
849 static PreParserExpression EmptyArrowParamList() { | |
850 // Any expression for which IsValidArrowParamList() returns true | |
851 // will work here. | |
852 return FromIdentifier(PreParserIdentifier::Default()); | |
853 } | |
854 | |
855 static PreParserExpression StringLiteral() { | 850 static PreParserExpression StringLiteral() { |
856 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 851 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
857 } | 852 } |
858 | 853 |
859 static PreParserExpression UseStrictStringLiteral() { | 854 static PreParserExpression UseStrictStringLiteral() { |
860 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 855 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
861 IsUseStrictField::encode(true)); | 856 IsUseStrictField::encode(true)); |
862 } | 857 } |
863 | 858 |
864 static PreParserExpression UseStrongStringLiteral() { | 859 static PreParserExpression UseStrongStringLiteral() { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 | 930 |
936 bool IsCall() const { | 931 bool IsCall() const { |
937 return TypeField::decode(code_) == kExpression && | 932 return TypeField::decode(code_) == kExpression && |
938 ExpressionTypeField::decode(code_) == kCallExpression; | 933 ExpressionTypeField::decode(code_) == kCallExpression; |
939 } | 934 } |
940 | 935 |
941 bool IsValidReferenceExpression() const { | 936 bool IsValidReferenceExpression() const { |
942 return IsIdentifier() || IsProperty(); | 937 return IsIdentifier() || IsProperty(); |
943 } | 938 } |
944 | 939 |
945 bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const { | 940 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, |
| 941 const Scanner::Location& params_loc) const { |
946 ValidArrowParam valid = ValidateArrowParams(); | 942 ValidArrowParam valid = ValidateArrowParams(); |
947 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 943 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
948 return false; | 944 return false; |
949 } | 945 } |
950 if (valid == kValidArrowParam) { | 946 switch (valid) { |
951 return true; | 947 case kInvalidArrowParam: |
952 } else if (valid == kInvalidStrongArrowParam) { | 948 return false; |
953 // Return true for now regardless of strong mode for compatibility with | 949 case kInvalidStrongArrowParam: |
954 // parser. | 950 locs->undefined = params_loc; |
955 locs->undefined = Scanner::Location(); | 951 return true; |
956 return true; | 952 case kInvalidStrictReservedArrowParam: |
957 } else { | 953 locs->reserved = params_loc; |
958 return false; | 954 return true; |
| 955 case kInvalidStrictEvalArgumentsArrowParam: |
| 956 locs->eval_or_arguments = params_loc; |
| 957 return true; |
| 958 default: |
| 959 DCHECK_EQ(valid, kValidArrowParam); |
| 960 return true; |
959 } | 961 } |
960 } | 962 } |
961 | 963 |
962 // At the moment PreParser doesn't track these expression types. | 964 // At the moment PreParser doesn't track these expression types. |
963 bool IsFunctionLiteral() const { return false; } | 965 bool IsFunctionLiteral() const { return false; } |
964 bool IsCallNew() const { return false; } | 966 bool IsCallNew() const { return false; } |
965 | 967 |
966 bool IsNoTemplateTag() const { | 968 bool IsNoTemplateTag() const { |
967 return TypeField::decode(code_) == kExpression && | 969 return TypeField::decode(code_) == kExpression && |
968 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 970 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 }; | 1017 }; |
1016 | 1018 |
1017 enum ExpressionType { | 1019 enum ExpressionType { |
1018 kThisExpression, | 1020 kThisExpression, |
1019 kThisPropertyExpression, | 1021 kThisPropertyExpression, |
1020 kPropertyExpression, | 1022 kPropertyExpression, |
1021 kCallExpression, | 1023 kCallExpression, |
1022 kNoTemplateTagExpression | 1024 kNoTemplateTagExpression |
1023 }; | 1025 }; |
1024 | 1026 |
| 1027 // These validity constraints are ordered such that a value of N implies lack |
| 1028 // of errors M < N. |
1025 enum ValidArrowParam { | 1029 enum ValidArrowParam { |
1026 kInvalidArrowParam, | 1030 kInvalidArrowParam, |
| 1031 kInvalidStrictEvalArgumentsArrowParam, |
| 1032 kInvalidStrictReservedArrowParam, |
1027 kInvalidStrongArrowParam, | 1033 kInvalidStrongArrowParam, |
1028 kValidArrowParam | 1034 kValidArrowParam |
1029 }; | 1035 }; |
1030 | 1036 |
1031 explicit PreParserExpression(uint32_t expression_code) | 1037 explicit PreParserExpression(uint32_t expression_code) |
1032 : code_(expression_code) {} | 1038 : code_(expression_code) {} |
1033 | 1039 |
1034 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1040 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
1035 if (IsBinaryOperation()) { | 1041 if (IsBinaryOperation()) { |
1036 return IsValidArrowParamListField::decode(code_); | 1042 return IsValidArrowParamListField::decode(code_); |
1037 } | 1043 } |
1038 if (!IsIdentifier()) { | 1044 if (!IsIdentifier()) { |
1039 return kInvalidArrowParam; | 1045 return kInvalidArrowParam; |
1040 } | 1046 } |
1041 PreParserIdentifier ident = AsIdentifier(); | 1047 PreParserIdentifier ident = AsIdentifier(); |
1042 // A valid identifier can be an arrow function parameter | 1048 // In strict mode, eval and arguments are not valid formal parameter names. |
1043 // except for eval, arguments, yield, and reserved keywords. | 1049 if (ident.IsEval() || ident.IsArguments()) { |
1044 if (ident.IsEval() || ident.IsArguments() || | 1050 return kInvalidStrictEvalArgumentsArrowParam; |
1045 ident.IsFutureStrictReserved()) { | |
1046 return kInvalidArrowParam; | |
1047 } | 1051 } |
1048 // In strong mode, 'undefined' is similarly restricted. | 1052 // In strict mode, future reserved words are not valid either, and as they |
| 1053 // produce different errors we allot them their own error code. |
| 1054 if (ident.IsFutureStrictReserved()) { |
| 1055 return kInvalidStrictReservedArrowParam; |
| 1056 } |
| 1057 // In strong mode, 'undefined' isn't a valid formal parameter name either. |
1049 if (ident.IsUndefined()) { | 1058 if (ident.IsUndefined()) { |
1050 return kInvalidStrongArrowParam; | 1059 return kInvalidStrongArrowParam; |
1051 } | 1060 } |
1052 return kValidArrowParam; | 1061 return kValidArrowParam; |
1053 } | 1062 } |
1054 | 1063 |
1055 // The first five bits are for the Type and Parenthesization. | 1064 // The first five bits are for the Type and Parenthesization. |
1056 typedef BitField<Type, 0, 3> TypeField; | 1065 typedef BitField<Type, 0, 3> TypeField; |
1057 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1066 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
1058 | 1067 |
1059 // The rest of the bits are interpreted depending on the value | 1068 // The rest of the bits are interpreted depending on the value |
1060 // of the Type field, so they can share the storage. | 1069 // of the Type field, so they can share the storage. |
1061 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1070 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
1062 ExpressionTypeField; | 1071 ExpressionTypeField; |
1063 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1072 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
1064 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1073 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1065 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> | 1074 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3> |
1066 IsValidArrowParamListField; | 1075 IsValidArrowParamListField; |
1067 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1076 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
1068 IdentifierTypeField; | 1077 IdentifierTypeField; |
1069 | 1078 |
1070 uint32_t code_; | 1079 uint32_t code_; |
1071 }; | 1080 }; |
1072 | 1081 |
1073 | 1082 |
1074 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1083 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1075 // the like. | 1084 // the like. |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 // "null" return type creators. | 1465 // "null" return type creators. |
1457 static PreParserIdentifier EmptyIdentifier() { | 1466 static PreParserIdentifier EmptyIdentifier() { |
1458 return PreParserIdentifier::Default(); | 1467 return PreParserIdentifier::Default(); |
1459 } | 1468 } |
1460 static PreParserIdentifier EmptyIdentifierString() { | 1469 static PreParserIdentifier EmptyIdentifierString() { |
1461 return PreParserIdentifier::Default(); | 1470 return PreParserIdentifier::Default(); |
1462 } | 1471 } |
1463 static PreParserExpression EmptyExpression() { | 1472 static PreParserExpression EmptyExpression() { |
1464 return PreParserExpression::Default(); | 1473 return PreParserExpression::Default(); |
1465 } | 1474 } |
1466 static PreParserExpression EmptyArrowParamList() { | |
1467 return PreParserExpression::EmptyArrowParamList(); | |
1468 } | |
1469 static PreParserExpression EmptyLiteral() { | 1475 static PreParserExpression EmptyLiteral() { |
1470 return PreParserExpression::Default(); | 1476 return PreParserExpression::Default(); |
1471 } | 1477 } |
1472 static PreParserExpression EmptyObjectLiteralProperty() { | 1478 static PreParserExpression EmptyObjectLiteralProperty() { |
1473 return PreParserExpression::Default(); | 1479 return PreParserExpression::Default(); |
1474 } | 1480 } |
1475 static PreParserExpression EmptyFunctionLiteral() { | 1481 static PreParserExpression EmptyFunctionLiteral() { |
1476 return PreParserExpression::Default(); | 1482 return PreParserExpression::Default(); |
1477 } | 1483 } |
1478 static PreParserExpressionList NullExpressionList() { | 1484 static PreParserExpressionList NullExpressionList() { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 int* materialized_literal_count, | 1552 int* materialized_literal_count, |
1547 int* expected_property_count, bool* ok) { | 1553 int* expected_property_count, bool* ok) { |
1548 UNREACHABLE(); | 1554 UNREACHABLE(); |
1549 } | 1555 } |
1550 | 1556 |
1551 V8_INLINE PreParserStatementList | 1557 V8_INLINE PreParserStatementList |
1552 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1558 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1553 Variable* fvar, Token::Value fvar_init_op, | 1559 Variable* fvar, Token::Value fvar_init_op, |
1554 FunctionKind kind, bool* ok); | 1560 FunctionKind kind, bool* ok); |
1555 | 1561 |
1556 // Utility functions | 1562 V8_INLINE void ParseArrowFunctionFormalParameters( |
1557 V8_INLINE int DeclareArrowParametersFromExpression( | 1563 Scope* scope, PreParserExpression expression, |
1558 PreParserExpression expression, Scope* scope, | 1564 const Scanner::Location& params_loc, |
1559 FormalParameterErrorLocations* locs, bool* ok) { | 1565 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); |
1560 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or | |
1561 // arguments. Detect reserved words. | |
1562 *ok = expression.IsValidArrowParamList(locs); | |
1563 return 0; | |
1564 } | |
1565 | 1566 |
1566 struct TemplateLiteralState {}; | 1567 struct TemplateLiteralState {}; |
1567 | 1568 |
1568 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1569 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1569 return TemplateLiteralState(); | 1570 return TemplateLiteralState(); |
1570 } | 1571 } |
1571 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1572 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1572 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1573 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
1573 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1574 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
1574 PreParserExpression tag) { | 1575 PreParserExpression tag) { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1779 } | 1780 } |
1780 | 1781 |
1781 | 1782 |
1782 bool PreParserTraits::DeclareFormalParameter( | 1783 bool PreParserTraits::DeclareFormalParameter( |
1783 DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, | 1784 DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, |
1784 bool is_rest) { | 1785 bool is_rest) { |
1785 return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; | 1786 return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; |
1786 } | 1787 } |
1787 | 1788 |
1788 | 1789 |
| 1790 void PreParserTraits::ParseArrowFunctionFormalParameters( |
| 1791 Scope* scope, PreParserExpression params, |
| 1792 const Scanner::Location& params_loc, |
| 1793 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { |
| 1794 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
| 1795 // lists that are too long. |
| 1796 if (!params.IsValidArrowParamList(error_locs, params_loc)) { |
| 1797 *ok = false; |
| 1798 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 1799 return; |
| 1800 } |
| 1801 } |
| 1802 |
| 1803 |
1789 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1804 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1790 PreParserIdentifier function_name, int pos, Variable* fvar, | 1805 PreParserIdentifier function_name, int pos, Variable* fvar, |
1791 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1806 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1792 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1807 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1793 | 1808 |
1794 ParseStatementList(Token::RBRACE, ok); | 1809 ParseStatementList(Token::RBRACE, ok); |
1795 if (!*ok) return PreParserStatementList(); | 1810 if (!*ok) return PreParserStatementList(); |
1796 | 1811 |
1797 Expect(Token::RBRACE, ok); | 1812 Expect(Token::RBRACE, ok); |
1798 return PreParserStatementList(); | 1813 return PreParserStatementList(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 case Token::LBRACK: | 2089 case Token::LBRACK: |
2075 result = this->ParseArrayLiteral(CHECK_OK); | 2090 result = this->ParseArrayLiteral(CHECK_OK); |
2076 break; | 2091 break; |
2077 | 2092 |
2078 case Token::LBRACE: | 2093 case Token::LBRACE: |
2079 result = this->ParseObjectLiteral(CHECK_OK); | 2094 result = this->ParseObjectLiteral(CHECK_OK); |
2080 break; | 2095 break; |
2081 | 2096 |
2082 case Token::LPAREN: | 2097 case Token::LPAREN: |
2083 Consume(Token::LPAREN); | 2098 Consume(Token::LPAREN); |
2084 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2099 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2085 // Arrow functions are the only expression type constructions | 2100 // As a primary expression, the only thing that can follow "()" is "=>". |
2086 // for which an empty parameter list "()" is valid input. | 2101 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
2087 Consume(Token::RPAREN); | 2102 scope->set_start_position(beg_pos); |
2088 result = this->ParseArrowFunctionLiteral( | 2103 FormalParameterErrorLocations error_locs; |
2089 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2104 bool has_rest = false; |
| 2105 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
| 2106 CHECK_OK); |
2090 } else { | 2107 } else { |
2091 // Heuristically try to detect immediately called functions before | 2108 // Heuristically try to detect immediately called functions before |
2092 // seeing the call parentheses. | 2109 // seeing the call parentheses. |
2093 parenthesized_function_ = (peek() == Token::FUNCTION); | 2110 parenthesized_function_ = (peek() == Token::FUNCTION); |
2094 result = this->ParseExpression(true, CHECK_OK); | 2111 result = this->ParseExpression(true, CHECK_OK); |
2095 result->increase_parenthesization_level(); | 2112 result->increase_parenthesization_level(); |
2096 Expect(Token::RPAREN, CHECK_OK); | 2113 Expect(Token::RPAREN, CHECK_OK); |
2097 } | 2114 } |
2098 break; | 2115 break; |
2099 | 2116 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2537 return this->ParseYieldExpression(ok); | 2554 return this->ParseYieldExpression(ok); |
2538 } | 2555 } |
2539 | 2556 |
2540 if (fni_ != NULL) fni_->Enter(); | 2557 if (fni_ != NULL) fni_->Enter(); |
2541 ParserBase<Traits>::Checkpoint checkpoint(this); | 2558 ParserBase<Traits>::Checkpoint checkpoint(this); |
2542 ExpressionT expression = | 2559 ExpressionT expression = |
2543 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2560 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
2544 | 2561 |
2545 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2562 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2546 checkpoint.Restore(); | 2563 checkpoint.Restore(); |
2547 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2564 FormalParameterErrorLocations error_locs; |
2548 expression, CHECK_OK); | 2565 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2566 bool has_rest = false; |
| 2567 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 2568 scope->set_start_position(lhs_location.beg_pos); |
| 2569 this->ParseArrowFunctionFormalParameters(scope, expression, loc, |
| 2570 &error_locs, &has_rest, CHECK_OK); |
| 2571 expression = |
| 2572 this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, CHECK_OK); |
2549 return expression; | 2573 return expression; |
2550 } | 2574 } |
2551 | 2575 |
2552 if (!Token::IsAssignmentOp(peek())) { | 2576 if (!Token::IsAssignmentOp(peek())) { |
2553 if (fni_ != NULL) fni_->Leave(); | 2577 if (fni_ != NULL) fni_->Leave(); |
2554 // Parsed conditional expression only (no assignment). | 2578 // Parsed conditional expression only (no assignment). |
2555 return expression; | 2579 return expression; |
2556 } | 2580 } |
2557 | 2581 |
2558 expression = this->CheckAndRewriteReferenceExpression( | 2582 expression = this->CheckAndRewriteReferenceExpression( |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3166 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3190 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3167 "bad_setter_arity"); | 3191 "bad_setter_arity"); |
3168 *ok = false; | 3192 *ok = false; |
3169 } | 3193 } |
3170 break; | 3194 break; |
3171 default: | 3195 default: |
3172 break; | 3196 break; |
3173 } | 3197 } |
3174 } | 3198 } |
3175 | 3199 |
| 3200 |
3176 template <class Traits> | 3201 template <class Traits> |
3177 typename ParserBase<Traits>::ExpressionT | 3202 typename ParserBase<Traits>::ExpressionT |
3178 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3203 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3179 ExpressionT params_ast, | 3204 Scope* scope, const FormalParameterErrorLocations& error_locs, |
3180 bool* ok) { | 3205 bool has_rest, bool* ok) { |
3181 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3206 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3182 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3207 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3183 // `=> ...` is never a valid expression, so report as syntax error. | 3208 // `=> ...` is never a valid expression, so report as syntax error. |
3184 // If next token is not `=>`, it's a syntax error anyways. | 3209 // If next token is not `=>`, it's a syntax error anyways. |
3185 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3210 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3186 *ok = false; | 3211 *ok = false; |
3187 return this->EmptyExpression(); | 3212 return this->EmptyExpression(); |
3188 } | 3213 } |
3189 | 3214 |
3190 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | |
3191 typename Traits::Type::StatementList body; | 3215 typename Traits::Type::StatementList body; |
3192 int num_parameters = -1; | 3216 int num_parameters = scope->num_parameters(); |
3193 int materialized_literal_count = -1; | 3217 int materialized_literal_count = -1; |
3194 int expected_property_count = -1; | 3218 int expected_property_count = -1; |
3195 int handler_count = 0; | 3219 int handler_count = 0; |
3196 Scanner::Location super_loc; | 3220 Scanner::Location super_loc; |
3197 | 3221 |
3198 { | 3222 { |
3199 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3223 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3200 FunctionState function_state(&function_state_, &scope_, scope, | 3224 FunctionState function_state(&function_state_, &scope_, scope, |
3201 kArrowFunction, &function_factory); | 3225 kArrowFunction, &function_factory); |
3202 FormalParameterErrorLocations error_locs; | |
3203 num_parameters = Traits::DeclareArrowParametersFromExpression( | |
3204 params_ast, scope_, &error_locs, ok); | |
3205 if (!*ok) { | |
3206 ReportMessageAt( | |
3207 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
3208 "malformed_arrow_function_parameter_list"); | |
3209 return this->EmptyExpression(); | |
3210 } | |
3211 | |
3212 if (error_locs.undefined.IsValid()) { | |
3213 // Workaround for preparser not keeping track of positions. | |
3214 error_locs.undefined = | |
3215 Scanner::Location(start_pos, scanner()->location().end_pos); | |
3216 } | |
3217 if (num_parameters > Code::kMaxArguments) { | |
3218 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
3219 "too_many_parameters"); | |
3220 *ok = false; | |
3221 return this->EmptyExpression(); | |
3222 } | |
3223 | 3226 |
3224 Expect(Token::ARROW, CHECK_OK); | 3227 Expect(Token::ARROW, CHECK_OK); |
3225 | 3228 |
3226 if (peek() == Token::LBRACE) { | 3229 if (peek() == Token::LBRACE) { |
3227 // Multiple statement body | 3230 // Multiple statement body |
3228 Consume(Token::LBRACE); | 3231 Consume(Token::LBRACE); |
3229 bool is_lazily_parsed = | 3232 bool is_lazily_parsed = |
3230 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3233 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3231 if (is_lazily_parsed) { | 3234 if (is_lazily_parsed) { |
3232 body = this->NewStatementList(0, zone()); | 3235 body = this->NewStatementList(0, zone()); |
(...skipping 15 matching lines...) Expand all Loading... |
3248 parenthesized_function_ = false; | 3251 parenthesized_function_ = false; |
3249 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3252 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
3250 body = this->NewStatementList(1, zone()); | 3253 body = this->NewStatementList(1, zone()); |
3251 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3254 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3252 materialized_literal_count = function_state.materialized_literal_count(); | 3255 materialized_literal_count = function_state.materialized_literal_count(); |
3253 expected_property_count = function_state.expected_property_count(); | 3256 expected_property_count = function_state.expected_property_count(); |
3254 handler_count = function_state.handler_count(); | 3257 handler_count = function_state.handler_count(); |
3255 } | 3258 } |
3256 super_loc = function_state.super_call_location(); | 3259 super_loc = function_state.super_call_location(); |
3257 | 3260 |
3258 scope->set_start_position(start_pos); | |
3259 scope->set_end_position(scanner()->location().end_pos); | 3261 scope->set_end_position(scanner()->location().end_pos); |
3260 | 3262 |
3261 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3263 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3262 // which is not the same as "parameters of a strict function"; it only means | 3264 // which is not the same as "parameters of a strict function"; it only means |
3263 // that duplicates are not allowed. Of course, the arrow function may | 3265 // that duplicates are not allowed. Of course, the arrow function may |
3264 // itself be strict as well. | 3266 // itself be strict as well. |
3265 const bool use_strict_params = true; | 3267 const bool use_strict_params = true; |
3266 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3268 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
3267 error_locs, CHECK_OK); | 3269 error_locs, CHECK_OK); |
3268 | 3270 |
3269 // Validate strict mode. | 3271 // Validate strict mode. |
3270 if (is_strict(language_mode())) { | 3272 if (is_strict(language_mode())) { |
3271 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3273 CheckStrictOctalLiteral(scope->start_position(), |
3272 CHECK_OK); | 3274 scanner()->location().end_pos, CHECK_OK); |
3273 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3275 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
3274 } | 3276 } |
3275 } | 3277 } |
3276 | 3278 |
3277 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3279 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3278 this->EmptyIdentifierString(), ast_value_factory(), scope, body, | 3280 this->EmptyIdentifierString(), ast_value_factory(), scope, body, |
3279 materialized_literal_count, expected_property_count, handler_count, | 3281 materialized_literal_count, expected_property_count, handler_count, |
3280 num_parameters, FunctionLiteral::kNoDuplicateParameters, | 3282 num_parameters, FunctionLiteral::kNoDuplicateParameters, |
3281 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 3283 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
3282 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, | 3284 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, |
3283 start_pos); | 3285 scope->start_position()); |
3284 | 3286 |
3285 function_literal->set_function_token_position(start_pos); | 3287 function_literal->set_function_token_position(scope->start_position()); |
3286 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); | 3288 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); |
3287 | 3289 |
3288 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3290 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3289 | 3291 |
3290 return function_literal; | 3292 return function_literal; |
3291 } | 3293 } |
3292 | 3294 |
3293 | 3295 |
3294 template <typename Traits> | 3296 template <typename Traits> |
3295 typename ParserBase<Traits>::ExpressionT | 3297 typename ParserBase<Traits>::ExpressionT |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3470 *ok = false; | 3472 *ok = false; |
3471 return; | 3473 return; |
3472 } | 3474 } |
3473 has_seen_constructor_ = true; | 3475 has_seen_constructor_ = true; |
3474 return; | 3476 return; |
3475 } | 3477 } |
3476 } | 3478 } |
3477 } } // v8::internal | 3479 } } // v8::internal |
3478 | 3480 |
3479 #endif // V8_PREPARSER_H | 3481 #endif // V8_PREPARSER_H |
OLD | NEW |