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 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 *ok = false; | 532 *ok = false; |
533 return; | 533 return; |
534 } | 534 } |
535 // TODO(arv): When we add support for destructuring in setters we also need | 535 // TODO(arv): When we add support for destructuring in setters we also need |
536 // to check for duplicate names. | 536 // to check for duplicate names. |
537 if (locs.duplicate_.IsValid()) { | 537 if (locs.duplicate_.IsValid()) { |
538 Traits::ReportMessageAt(locs.duplicate_, "strict_param_dupe"); | 538 Traits::ReportMessageAt(locs.duplicate_, "strict_param_dupe"); |
539 *ok = false; | 539 *ok = false; |
540 return; | 540 return; |
541 } | 541 } |
542 if (locs.reserved_.IsValid()) { | 542 if (is_strict(language_mode) && locs.reserved_.IsValid()) { |
543 Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved"); | 543 Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved"); |
544 *ok = false; | 544 *ok = false; |
545 return; | 545 return; |
546 } | 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 |
(...skipping 61 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 int start_pos, FormalParameterListT params, |
| 626 const FormalParameterErrorLocations& error_locs, 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 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, | 631 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, |
631 FormalParameterErrorLocations* locs, | 632 FormalParameterErrorLocations* locs, |
632 bool* ok); | 633 bool* ok); |
633 FormalParameterListT ParseFormalParameterList( | 634 FormalParameterListT ParseFormalParameterList( |
634 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); | 635 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); |
635 void CheckArityRestrictions( | 636 void CheckArityRestrictions( |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 | 935 |
935 bool IsCall() const { | 936 bool IsCall() const { |
936 return TypeField::decode(code_) == kExpression && | 937 return TypeField::decode(code_) == kExpression && |
937 ExpressionTypeField::decode(code_) == kCallExpression; | 938 ExpressionTypeField::decode(code_) == kCallExpression; |
938 } | 939 } |
939 | 940 |
940 bool IsValidReferenceExpression() const { | 941 bool IsValidReferenceExpression() const { |
941 return IsIdentifier() || IsProperty(); | 942 return IsIdentifier() || IsProperty(); |
942 } | 943 } |
943 | 944 |
944 bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const { | 945 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, |
| 946 const Scanner::Location& params_loc) const { |
945 ValidArrowParam valid = ValidateArrowParams(); | 947 ValidArrowParam valid = ValidateArrowParams(); |
946 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 948 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
947 return false; | 949 return false; |
948 } | 950 } |
949 if (valid == kValidArrowParam) { | 951 if (valid == kValidArrowParam) { |
950 return true; | 952 return true; |
951 } else if (valid == kInvalidStrongArrowParam) { | 953 } else if (valid == kInvalidStrongArrowParam) { |
952 // Return true for now regardless of strong mode for compatibility with | 954 // Return true for now regardless of strong mode for compatibility with |
953 // parser. | 955 // parser. |
954 locs->undefined_ = Scanner::Location(); | 956 locs->undefined_ = params_loc; |
| 957 return true; |
| 958 } else if (valid == kInvalidStrictArrowParam) { |
| 959 // TODO(wingo): Distinguish eval/arguments from other words reserved in |
| 960 // strict mode. |
| 961 locs->reserved_ = params_loc; |
955 return true; | 962 return true; |
956 } else { | 963 } else { |
957 return false; | 964 return false; |
958 } | 965 } |
959 } | 966 } |
960 | 967 |
961 // At the moment PreParser doesn't track these expression types. | 968 // At the moment PreParser doesn't track these expression types. |
962 bool IsFunctionLiteral() const { return false; } | 969 bool IsFunctionLiteral() const { return false; } |
963 bool IsCallNew() const { return false; } | 970 bool IsCallNew() const { return false; } |
964 | 971 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 enum ExpressionType { | 1023 enum ExpressionType { |
1017 kThisExpression, | 1024 kThisExpression, |
1018 kThisPropertyExpression, | 1025 kThisPropertyExpression, |
1019 kPropertyExpression, | 1026 kPropertyExpression, |
1020 kCallExpression, | 1027 kCallExpression, |
1021 kNoTemplateTagExpression | 1028 kNoTemplateTagExpression |
1022 }; | 1029 }; |
1023 | 1030 |
1024 enum ValidArrowParam { | 1031 enum ValidArrowParam { |
1025 kInvalidArrowParam, | 1032 kInvalidArrowParam, |
| 1033 kInvalidStrictArrowParam, |
1026 kInvalidStrongArrowParam, | 1034 kInvalidStrongArrowParam, |
1027 kValidArrowParam | 1035 kValidArrowParam |
1028 }; | 1036 }; |
1029 | 1037 |
1030 explicit PreParserExpression(uint32_t expression_code) | 1038 explicit PreParserExpression(uint32_t expression_code) |
1031 : code_(expression_code) {} | 1039 : code_(expression_code) {} |
1032 | 1040 |
1033 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1041 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
1034 if (IsBinaryOperation()) { | 1042 if (IsBinaryOperation()) { |
1035 return IsValidArrowParamListField::decode(code_); | 1043 return IsValidArrowParamListField::decode(code_); |
1036 } | 1044 } |
1037 if (!IsIdentifier()) { | 1045 if (!IsIdentifier()) { |
1038 return kInvalidArrowParam; | 1046 return kInvalidArrowParam; |
1039 } | 1047 } |
1040 PreParserIdentifier ident = AsIdentifier(); | 1048 PreParserIdentifier ident = AsIdentifier(); |
1041 // A valid identifier can be an arrow function parameter | 1049 // A valid identifier can be an arrow function parameter |
1042 // except for eval, arguments, yield, and reserved keywords. | 1050 // except for eval, arguments, yield, and reserved keywords. |
1043 if (ident.IsEval() || ident.IsArguments() || | 1051 if (ident.IsEval() || ident.IsArguments() || |
1044 ident.IsFutureStrictReserved()) { | 1052 ident.IsFutureStrictReserved()) { |
1045 return kInvalidArrowParam; | 1053 return kInvalidStrictArrowParam; |
1046 } | 1054 } |
1047 // In strong mode, 'undefined' is similarly restricted. | 1055 // In strong mode, 'undefined' is similarly restricted. |
1048 if (ident.IsUndefined()) { | 1056 if (ident.IsUndefined()) { |
1049 return kInvalidStrongArrowParam; | 1057 return kInvalidStrongArrowParam; |
1050 } | 1058 } |
1051 return kValidArrowParam; | 1059 return kValidArrowParam; |
1052 } | 1060 } |
1053 | 1061 |
1054 // The first five bits are for the Type and Parenthesization. | 1062 // The first five bits are for the Type and Parenthesization. |
1055 typedef BitField<Type, 0, 3> TypeField; | 1063 typedef BitField<Type, 0, 3> TypeField; |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 int* materialized_literal_count, | 1556 int* materialized_literal_count, |
1549 int* expected_property_count, bool* ok) { | 1557 int* expected_property_count, bool* ok) { |
1550 UNREACHABLE(); | 1558 UNREACHABLE(); |
1551 } | 1559 } |
1552 | 1560 |
1553 V8_INLINE PreParserStatementList | 1561 V8_INLINE PreParserStatementList |
1554 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1562 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1555 Variable* fvar, Token::Value fvar_init_op, | 1563 Variable* fvar, Token::Value fvar_init_op, |
1556 FunctionKind kind, bool* ok); | 1564 FunctionKind kind, bool* ok); |
1557 | 1565 |
1558 // Utility functions | 1566 V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList( |
1559 V8_INLINE int DeclareArrowParametersFromExpression( | 1567 PreParserExpression expression, const Scanner::Location& params_loc, |
1560 PreParserExpression expression, Scope* scope, | 1568 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); |
1561 FormalParameterErrorLocations* locs, bool* ok) { | |
1562 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or | |
1563 // arguments. Detect reserved words. | |
1564 *ok = expression.IsValidArrowParamList(locs); | |
1565 return 0; | |
1566 } | |
1567 | 1569 |
1568 struct TemplateLiteralState {}; | 1570 struct TemplateLiteralState {}; |
1569 | 1571 |
1570 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1572 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1571 return TemplateLiteralState(); | 1573 return TemplateLiteralState(); |
1572 } | 1574 } |
1573 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1575 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1574 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1576 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
1575 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1577 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
1576 PreParserExpression tag) { | 1578 PreParserExpression tag) { |
1577 if (IsTaggedTemplate(tag)) { | 1579 if (IsTaggedTemplate(tag)) { |
1578 // Emulate generation of array literals for tag callsite | 1580 // Emulate generation of array literals for tag callsite |
1579 // 1st is array of cooked strings, second is array of raw strings | 1581 // 1st is array of cooked strings, second is array of raw strings |
1580 MaterializeTemplateCallsiteLiterals(); | 1582 MaterializeTemplateCallsiteLiterals(); |
1581 } | 1583 } |
1582 return EmptyExpression(); | 1584 return EmptyExpression(); |
1583 } | 1585 } |
1584 inline void MaterializeTemplateCallsiteLiterals(); | 1586 inline void MaterializeTemplateCallsiteLiterals(); |
1585 PreParserExpression NoTemplateTag() { | 1587 PreParserExpression NoTemplateTag() { |
1586 return PreParserExpression::NoTemplateTag(); | 1588 return PreParserExpression::NoTemplateTag(); |
1587 } | 1589 } |
1588 static bool IsTaggedTemplate(const PreParserExpression tag) { | 1590 static bool IsTaggedTemplate(const PreParserExpression tag) { |
1589 return !tag.IsNoTemplateTag(); | 1591 return !tag.IsNoTemplateTag(); |
1590 } | 1592 } |
1591 | 1593 |
| 1594 int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope, |
| 1595 bool has_rest, bool* ok) { |
| 1596 return params->length(); |
| 1597 } |
| 1598 |
1592 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1599 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1593 | 1600 |
1594 // Temporary glue; these functions will move to ParserBase. | 1601 // Temporary glue; these functions will move to ParserBase. |
1595 PreParserExpression ParseV8Intrinsic(bool* ok); | 1602 PreParserExpression ParseV8Intrinsic(bool* ok); |
1596 PreParserExpression ParseFunctionLiteral( | 1603 PreParserExpression ParseFunctionLiteral( |
1597 PreParserIdentifier name, Scanner::Location function_name_location, | 1604 PreParserIdentifier name, Scanner::Location function_name_location, |
1598 bool name_is_strict_reserved, FunctionKind kind, | 1605 bool name_is_strict_reserved, FunctionKind kind, |
1599 int function_token_position, FunctionLiteral::FunctionType type, | 1606 int function_token_position, FunctionLiteral::FunctionType type, |
1600 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1607 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1601 | 1608 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 return pre_parser_->factory()->NewCall(function, args, pos); | 1777 return pre_parser_->factory()->NewCall(function, args, pos); |
1771 } | 1778 } |
1772 | 1779 |
1773 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1780 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
1774 PreParserExpressionList args, | 1781 PreParserExpressionList args, |
1775 int pos) { | 1782 int pos) { |
1776 return pre_parser_->factory()->NewCallNew(function, args, pos); | 1783 return pre_parser_->factory()->NewCallNew(function, args, pos); |
1777 } | 1784 } |
1778 | 1785 |
1779 | 1786 |
| 1787 PreParserFormalParameterList |
| 1788 PreParserTraits::ParseArrowFunctionFormalParameterList( |
| 1789 PreParserExpression params, const Scanner::Location& params_loc, |
| 1790 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { |
| 1791 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
| 1792 // lists that are too long. |
| 1793 if (!params.IsValidArrowParamList(error_locs, params_loc)) { |
| 1794 *ok = false; |
| 1795 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 1796 return this->NullFormalParameterList(); |
| 1797 } |
| 1798 |
| 1799 return PreParserFormalParameterList(); |
| 1800 } |
| 1801 |
| 1802 |
1780 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1803 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1781 PreParserIdentifier function_name, int pos, Variable* fvar, | 1804 PreParserIdentifier function_name, int pos, Variable* fvar, |
1782 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1805 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1783 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1806 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1784 | 1807 |
1785 ParseStatementList(Token::RBRACE, ok); | 1808 ParseStatementList(Token::RBRACE, ok); |
1786 if (!*ok) return PreParserStatementList(); | 1809 if (!*ok) return PreParserStatementList(); |
1787 | 1810 |
1788 Expect(Token::RBRACE, ok); | 1811 Expect(Token::RBRACE, ok); |
1789 return PreParserStatementList(); | 1812 return PreParserStatementList(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2065 case Token::LBRACK: | 2088 case Token::LBRACK: |
2066 result = this->ParseArrayLiteral(CHECK_OK); | 2089 result = this->ParseArrayLiteral(CHECK_OK); |
2067 break; | 2090 break; |
2068 | 2091 |
2069 case Token::LBRACE: | 2092 case Token::LBRACE: |
2070 result = this->ParseObjectLiteral(CHECK_OK); | 2093 result = this->ParseObjectLiteral(CHECK_OK); |
2071 break; | 2094 break; |
2072 | 2095 |
2073 case Token::LPAREN: | 2096 case Token::LPAREN: |
2074 Consume(Token::LPAREN); | 2097 Consume(Token::LPAREN); |
2075 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2098 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2076 // Arrow functions are the only expression type constructions | 2099 // Arrow functions are the only expression type constructions |
2077 // for which an empty parameter list "()" is valid input. | 2100 // for which an empty parameter list "()" is valid input. |
2078 Consume(Token::RPAREN); | 2101 FormalParameterListT params = this->NewFormalParameterList(0, zone()); |
2079 result = this->ParseArrowFunctionLiteral( | 2102 FormalParameterErrorLocations error_locs; |
2080 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2103 bool has_rest = false; |
| 2104 result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs, |
| 2105 has_rest, CHECK_OK); |
2081 } else { | 2106 } else { |
2082 // Heuristically try to detect immediately called functions before | 2107 // Heuristically try to detect immediately called functions before |
2083 // seeing the call parentheses. | 2108 // seeing the call parentheses. |
2084 parenthesized_function_ = (peek() == Token::FUNCTION); | 2109 parenthesized_function_ = (peek() == Token::FUNCTION); |
2085 result = this->ParseExpression(true, CHECK_OK); | 2110 result = this->ParseExpression(true, CHECK_OK); |
2086 result->increase_parenthesization_level(); | 2111 result->increase_parenthesization_level(); |
2087 Expect(Token::RPAREN, CHECK_OK); | 2112 Expect(Token::RPAREN, CHECK_OK); |
2088 } | 2113 } |
2089 break; | 2114 break; |
2090 | 2115 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2528 return this->ParseYieldExpression(ok); | 2553 return this->ParseYieldExpression(ok); |
2529 } | 2554 } |
2530 | 2555 |
2531 if (fni_ != NULL) fni_->Enter(); | 2556 if (fni_ != NULL) fni_->Enter(); |
2532 ParserBase<Traits>::Checkpoint checkpoint(this); | 2557 ParserBase<Traits>::Checkpoint checkpoint(this); |
2533 ExpressionT expression = | 2558 ExpressionT expression = |
2534 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2559 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
2535 | 2560 |
2536 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2561 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2537 checkpoint.Restore(); | 2562 checkpoint.Restore(); |
2538 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2563 FormalParameterErrorLocations error_locs; |
2539 expression, CHECK_OK); | 2564 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2565 bool has_rest = false; |
| 2566 FormalParameterListT params = this->ParseArrowFunctionFormalParameterList( |
| 2567 expression, loc, &error_locs, &has_rest, CHECK_OK); |
| 2568 expression = this->ParseArrowFunctionLiteral( |
| 2569 lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK); |
2540 return expression; | 2570 return expression; |
2541 } | 2571 } |
2542 | 2572 |
2543 if (!Token::IsAssignmentOp(peek())) { | 2573 if (!Token::IsAssignmentOp(peek())) { |
2544 if (fni_ != NULL) fni_->Leave(); | 2574 if (fni_ != NULL) fni_->Leave(); |
2545 // Parsed conditional expression only (no assignment). | 2575 // Parsed conditional expression only (no assignment). |
2546 return expression; | 2576 return expression; |
2547 } | 2577 } |
2548 | 2578 |
2549 expression = this->CheckAndRewriteReferenceExpression( | 2579 expression = this->CheckAndRewriteReferenceExpression( |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3187 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3158 "bad_setter_arity"); | 3188 "bad_setter_arity"); |
3159 *ok = false; | 3189 *ok = false; |
3160 } | 3190 } |
3161 break; | 3191 break; |
3162 default: | 3192 default: |
3163 break; | 3193 break; |
3164 } | 3194 } |
3165 } | 3195 } |
3166 | 3196 |
| 3197 |
3167 template <class Traits> | 3198 template <class Traits> |
3168 typename ParserBase<Traits>::ExpressionT | 3199 typename ParserBase<Traits>::ExpressionT |
3169 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3200 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3170 ExpressionT params_ast, | 3201 int start_pos, FormalParameterListT params, |
3171 bool* ok) { | 3202 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) { |
3172 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3203 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3173 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3204 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3174 // `=> ...` is never a valid expression, so report as syntax error. | 3205 // `=> ...` is never a valid expression, so report as syntax error. |
3175 // If next token is not `=>`, it's a syntax error anyways. | 3206 // If next token is not `=>`, it's a syntax error anyways. |
3176 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3207 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3177 *ok = false; | 3208 *ok = false; |
3178 return this->EmptyExpression(); | 3209 return this->EmptyExpression(); |
3179 } | 3210 } |
3180 | 3211 |
3181 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3212 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
3182 typename Traits::Type::StatementList body; | 3213 typename Traits::Type::StatementList body; |
3183 int num_parameters = -1; | 3214 int num_parameters = -1; |
3184 int materialized_literal_count = -1; | 3215 int materialized_literal_count = -1; |
3185 int expected_property_count = -1; | 3216 int expected_property_count = -1; |
3186 int handler_count = 0; | 3217 int handler_count = 0; |
3187 Scanner::Location super_loc; | 3218 Scanner::Location super_loc; |
3188 | 3219 |
3189 { | 3220 { |
3190 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3221 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3191 FunctionState function_state(&function_state_, &scope_, scope, | 3222 FunctionState function_state(&function_state_, &scope_, scope, |
3192 kArrowFunction, &function_factory); | 3223 kArrowFunction, &function_factory); |
3193 FormalParameterErrorLocations error_locs; | 3224 num_parameters = |
3194 num_parameters = Traits::DeclareArrowParametersFromExpression( | 3225 this->DeclareFormalParameters(params, scope_, has_rest, CHECK_OK); |
3195 params_ast, scope_, &error_locs, ok); | |
3196 if (!*ok) { | |
3197 ReportMessageAt( | |
3198 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
3199 "malformed_arrow_function_parameter_list"); | |
3200 return this->EmptyExpression(); | |
3201 } | |
3202 | |
3203 if (error_locs.undefined_.IsValid()) { | |
3204 // Workaround for preparser not keeping track of positions. | |
3205 error_locs.undefined_ = | |
3206 Scanner::Location(start_pos, scanner()->location().end_pos); | |
3207 } | |
3208 if (num_parameters > Code::kMaxArguments) { | |
3209 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
3210 "too_many_parameters"); | |
3211 *ok = false; | |
3212 return this->EmptyExpression(); | |
3213 } | |
3214 | 3226 |
3215 Expect(Token::ARROW, CHECK_OK); | 3227 Expect(Token::ARROW, CHECK_OK); |
3216 | 3228 |
3217 if (peek() == Token::LBRACE) { | 3229 if (peek() == Token::LBRACE) { |
3218 // Multiple statement body | 3230 // Multiple statement body |
3219 Consume(Token::LBRACE); | 3231 Consume(Token::LBRACE); |
3220 bool is_lazily_parsed = | 3232 bool is_lazily_parsed = |
3221 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3233 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3222 if (is_lazily_parsed) { | 3234 if (is_lazily_parsed) { |
3223 body = this->NewStatementList(0, zone()); | 3235 body = this->NewStatementList(0, zone()); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3461 *ok = false; | 3473 *ok = false; |
3462 return; | 3474 return; |
3463 } | 3475 } |
3464 has_seen_constructor_ = true; | 3476 has_seen_constructor_ = true; |
3465 return; | 3477 return; |
3466 } | 3478 } |
3467 } | 3479 } |
3468 } } // v8::internal | 3480 } } // v8::internal |
3469 | 3481 |
3470 #endif // V8_PREPARSER_H | 3482 #endif // V8_PREPARSER_H |
OLD | NEW |