Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: src/preparser.h

Issue 1077153005: Allow eval/arguments in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698