Chromium Code Reviews| 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 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 bool* is_strict_reserved, | 556 bool* is_strict_reserved, |
| 557 bool* ok); | 557 bool* ok); |
| 558 IdentifierT ParseIdentifierName(bool* ok); | 558 IdentifierT ParseIdentifierName(bool* ok); |
| 559 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 559 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
| 560 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 560 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 561 bool* is_set, | 561 bool* is_set, |
| 562 bool* ok); | 562 bool* ok); |
| 563 | 563 |
| 564 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 564 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
| 565 | 565 |
| 566 ExpressionT ParsePrimaryExpression(bool* ok); | 566 ExpressionT ParsePrimaryExpression(bool maybeArrow, bool* ok); |
| 567 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 567 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 568 ExpressionT ParseArrayLiteral(bool* ok); | 568 ExpressionT ParseArrayLiteral(bool* ok); |
| 569 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 569 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 570 bool* is_static, bool* is_computed_name, | 570 bool* is_static, bool* is_computed_name, |
| 571 bool* ok); | 571 bool* ok); |
| 572 ExpressionT ParseObjectLiteral(bool* ok); | 572 ExpressionT ParseObjectLiteral(bool* ok); |
| 573 ObjectLiteralPropertyT ParsePropertyDefinition( | 573 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 574 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 574 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 575 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 575 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 576 bool* ok); | 576 bool* ok); |
| 577 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 577 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
| 578 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 578 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 579 ExpressionT ParseYieldExpression(bool* ok); | 579 ExpressionT ParseYieldExpression(bool* ok); |
| 580 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 580 ExpressionT ParseConditionalExpression(bool accept_IN, bool maybeArrow, |
| 581 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 581 bool* ok); |
| 582 ExpressionT ParseUnaryExpression(bool* ok); | 582 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool maybeArrow, |
| 583 ExpressionT ParsePostfixExpression(bool* ok); | 583 bool* ok); |
| 584 ExpressionT ParseLeftHandSideExpression(bool* ok); | 584 ExpressionT ParseUnaryExpression(bool maybeArrow, bool* ok); |
| 585 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 585 ExpressionT ParsePostfixExpression(bool maybeArrow, bool* ok); |
| 586 ExpressionT ParseMemberExpression(bool* ok); | 586 ExpressionT ParseLeftHandSideExpression(bool maybeArrow, bool* ok); |
| 587 ExpressionT ParseMemberWithNewPrefixesExpression(bool maybeArrow, bool* ok); | |
| 588 ExpressionT ParseMemberExpression(bool maybeArrow, bool* ok); | |
| 587 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 589 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 588 bool* ok); | 590 bool* ok); |
| 589 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 591 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 590 bool* ok); | 592 bool* ok); |
| 591 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 593 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 592 void AddTemplateExpression(ExpressionT); | 594 void AddTemplateExpression(ExpressionT); |
| 593 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 595 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 594 | 596 |
| 595 // Checks if the expression is a valid reference expression (e.g., on the | 597 // Checks if the expression is a valid reference expression (e.g., on the |
| 596 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 598 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 771 friend class PreParserExpression; | 773 friend class PreParserExpression; |
| 772 }; | 774 }; |
| 773 | 775 |
| 774 | 776 |
| 775 class PreParserExpression { | 777 class PreParserExpression { |
| 776 public: | 778 public: |
| 777 static PreParserExpression Default() { | 779 static PreParserExpression Default() { |
| 778 return PreParserExpression(TypeField::encode(kExpression)); | 780 return PreParserExpression(TypeField::encode(kExpression)); |
| 779 } | 781 } |
| 780 | 782 |
| 783 static PreParserExpression Spread(PreParserExpression expression) { | |
| 784 return PreParserExpression( | |
| 785 expression.code_ | TypeField::encode(kSpreadExpression)); | |
| 786 } | |
| 787 | |
| 781 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 788 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 782 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 789 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
| 783 IdentifierTypeField::encode(id.type_)); | 790 IdentifierTypeField::encode(id.type_)); |
| 784 } | 791 } |
| 785 | 792 |
| 786 static PreParserExpression BinaryOperation(PreParserExpression left, | 793 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 787 Token::Value op, | 794 Token::Value op, |
| 788 PreParserExpression right) { | 795 PreParserExpression right) { |
| 789 bool valid_arrow_param_list = | 796 bool valid_arrow_param_list = |
| 790 op == Token::COMMA && !left.is_parenthesized() && | 797 op == Token::COMMA && !left.is_parenthesized() && |
| 791 !right.is_parenthesized() && left.IsValidArrowParams() && | 798 !right.is_parenthesized() && left.IsValidArrowParams() && |
| 792 right.IsValidArrowParams(); | 799 right.IsValidArrowParams() && !left.IsSpread(); |
| 793 return PreParserExpression( | 800 return PreParserExpression( |
| 794 TypeField::encode(kBinaryOperationExpression) | | 801 TypeField::encode(kBinaryOperationExpression) | |
| 795 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 802 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
| 796 } | 803 } |
| 797 | 804 |
| 798 static PreParserExpression EmptyArrowParamList() { | 805 static PreParserExpression EmptyArrowParamList() { |
| 799 // Any expression for which IsValidArrowParamList() returns true | 806 // Any expression for which IsValidArrowParamList() returns true |
| 800 // will work here. | 807 // will work here. |
| 801 return FromIdentifier(PreParserIdentifier::Default()); | 808 return FromIdentifier(PreParserIdentifier::Default()); |
| 802 } | 809 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 915 bool is_parenthesized() const { | 922 bool is_parenthesized() const { |
| 916 return ParenthesizationField::decode(code_) != kNotParenthesized; | 923 return ParenthesizationField::decode(code_) != kNotParenthesized; |
| 917 } | 924 } |
| 918 | 925 |
| 919 void increase_parenthesization_level() { | 926 void increase_parenthesization_level() { |
| 920 code_ = ParenthesizationField::update( | 927 code_ = ParenthesizationField::update( |
| 921 code_, is_parenthesized() ? kMultiParenthesizedExpression | 928 code_, is_parenthesized() ? kMultiParenthesizedExpression |
| 922 : kParanthesizedExpression); | 929 : kParanthesizedExpression); |
| 923 } | 930 } |
| 924 | 931 |
| 932 bool IsSpread() const { | |
| 933 // Is<NodeType> queries other than IsSpread() should always fail | |
| 934 return TypeField::decode(code_) & kSpreadExpression; | |
| 935 } | |
| 936 | |
| 937 PreParserExpression SpreadExpression() const { | |
| 938 return PreParserExpression(code_ & ~TypeField::encode(kSpreadExpression)); | |
| 939 } | |
| 940 | |
| 925 // Dummy implementation for making expression->somefunc() work in both Parser | 941 // Dummy implementation for making expression->somefunc() work in both Parser |
| 926 // and PreParser. | 942 // and PreParser. |
| 927 PreParserExpression* operator->() { return this; } | 943 PreParserExpression* operator->() { return this; } |
| 928 | 944 |
| 929 // More dummy implementations of things PreParser doesn't need to track: | 945 // More dummy implementations of things PreParser doesn't need to track: |
| 930 void set_index(int index) {} // For YieldExpressions | 946 void set_index(int index) {} // For YieldExpressions |
| 931 void set_parenthesized() {} | 947 void set_parenthesized() {} |
| 932 | 948 |
| 933 int position() const { return RelocInfo::kNoPosition; } | 949 int position() const { return RelocInfo::kNoPosition; } |
| 934 void set_function_token_position(int position) {} | 950 void set_function_token_position(int position) {} |
| 935 | 951 |
| 936 private: | 952 private: |
| 937 enum Type { | 953 enum Type { |
| 938 kExpression, | 954 kExpression, |
| 939 kIdentifierExpression, | 955 kIdentifierExpression, |
| 940 kStringLiteralExpression, | 956 kStringLiteralExpression, |
| 941 kBinaryOperationExpression | 957 kBinaryOperationExpression, |
| 958 kSpreadExpression | |
| 942 }; | 959 }; |
| 943 | 960 |
| 944 enum Parenthesization { | 961 enum Parenthesization { |
| 945 kNotParenthesized, | 962 kNotParenthesized, |
| 946 kParanthesizedExpression, | 963 kParanthesizedExpression, |
| 947 kMultiParenthesizedExpression | 964 kMultiParenthesizedExpression |
| 948 }; | 965 }; |
| 949 | 966 |
| 950 enum ExpressionType { | 967 enum ExpressionType { |
| 951 kThisExpression, | 968 kThisExpression, |
| 952 kThisPropertyExpression, | 969 kThisPropertyExpression, |
| 953 kPropertyExpression, | 970 kPropertyExpression, |
| 954 kCallExpression, | 971 kCallExpression, |
| 955 kNoTemplateTagExpression | 972 kNoTemplateTagExpression |
| 956 }; | 973 }; |
| 957 | 974 |
| 958 explicit PreParserExpression(uint32_t expression_code) | 975 explicit PreParserExpression(uint32_t expression_code) |
| 959 : code_(expression_code) {} | 976 : code_(expression_code) {} |
| 960 | 977 |
| 961 V8_INLINE bool IsValidArrowParams() const { | 978 V8_INLINE bool IsValidArrowParams() const { |
| 962 return IsBinaryOperation() | 979 PreParserExpression e = IsSpread() ? SpreadExpression() : *this; |
| 963 ? IsValidArrowParamListField::decode(code_) | 980 return e.IsBinaryOperation() |
| 964 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 981 ? IsValidArrowParamListField::decode(e.code_) |
| 982 : (e.IsIdentifier() && e.AsIdentifier().IsValidArrowParam()); | |
| 965 } | 983 } |
| 966 | 984 |
| 967 // The first four bits are for the Type and Parenthesization. | 985 // The first four bits are for the Type and Parenthesization. |
| 968 typedef BitField<Type, 0, 2> TypeField; | 986 typedef BitField<Type, 0, 3> TypeField; |
| 969 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 987 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 970 | 988 |
| 971 // The rest of the bits are interpreted depending on the value | 989 // The rest of the bits are interpreted depending on the value |
| 972 // of the Type field, so they can share the storage. | 990 // of the Type field, so they can share the storage. |
| 973 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 991 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 974 ExpressionTypeField; | 992 ExpressionTypeField; |
| 975 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 993 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 976 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 994 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 977 typedef BitField<bool, ParenthesizationField::kNext, 1> | 995 typedef BitField<bool, ParenthesizationField::kNext, 1> |
| 978 IsValidArrowParamListField; | 996 IsValidArrowParamListField; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1143 Yield::Kind yield_kind, | 1161 Yield::Kind yield_kind, |
| 1144 int pos) { | 1162 int pos) { |
| 1145 return PreParserExpression::Default(); | 1163 return PreParserExpression::Default(); |
| 1146 } | 1164 } |
| 1147 PreParserExpression NewConditional(PreParserExpression condition, | 1165 PreParserExpression NewConditional(PreParserExpression condition, |
| 1148 PreParserExpression then_expression, | 1166 PreParserExpression then_expression, |
| 1149 PreParserExpression else_expression, | 1167 PreParserExpression else_expression, |
| 1150 int pos) { | 1168 int pos) { |
| 1151 return PreParserExpression::Default(); | 1169 return PreParserExpression::Default(); |
| 1152 } | 1170 } |
| 1171 PreParserExpression NewSpread(PreParserExpression expression, int pos) { | |
| 1172 return PreParserExpression::Spread(expression); | |
| 1173 } | |
| 1153 PreParserExpression NewCountOperation(Token::Value op, | 1174 PreParserExpression NewCountOperation(Token::Value op, |
| 1154 bool is_prefix, | 1175 bool is_prefix, |
| 1155 PreParserExpression expression, | 1176 PreParserExpression expression, |
| 1156 int pos) { | 1177 int pos) { |
| 1157 return PreParserExpression::Default(); | 1178 return PreParserExpression::Default(); |
| 1158 } | 1179 } |
| 1159 PreParserExpression NewCall(PreParserExpression expression, | 1180 PreParserExpression NewCall(PreParserExpression expression, |
| 1160 PreParserExpressionList arguments, | 1181 PreParserExpressionList arguments, |
| 1161 int pos) { | 1182 int pos) { |
| 1162 return PreParserExpression::Call(); | 1183 return PreParserExpression::Call(); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1487 PreParserIdentifier name, Scanner::Location function_name_location, | 1508 PreParserIdentifier name, Scanner::Location function_name_location, |
| 1488 bool name_is_strict_reserved, FunctionKind kind, | 1509 bool name_is_strict_reserved, FunctionKind kind, |
| 1489 int function_token_position, FunctionLiteral::FunctionType type, | 1510 int function_token_position, FunctionLiteral::FunctionType type, |
| 1490 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1511 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
| 1491 | 1512 |
| 1492 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1513 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
| 1493 Scanner::Location class_name_location, | 1514 Scanner::Location class_name_location, |
| 1494 bool name_is_strict_reserved, int pos, | 1515 bool name_is_strict_reserved, int pos, |
| 1495 bool* ok); | 1516 bool* ok); |
| 1496 | 1517 |
| 1518 PreParserExpression SpreadExpression(PreParserExpression spread) const { | |
| 1519 return spread.SpreadExpression(); | |
| 1520 } | |
| 1521 | |
| 1497 private: | 1522 private: |
| 1498 PreParser* pre_parser_; | 1523 PreParser* pre_parser_; |
| 1499 }; | 1524 }; |
| 1500 | 1525 |
| 1501 | 1526 |
| 1502 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1527 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1503 // a later parsing to be faster. | 1528 // a later parsing to be faster. |
| 1504 // See preparse-data-format.h for the data format. | 1529 // See preparse-data-format.h for the data format. |
| 1505 | 1530 |
| 1506 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1531 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1594 Statement ParseBreakStatement(bool* ok); | 1619 Statement ParseBreakStatement(bool* ok); |
| 1595 Statement ParseReturnStatement(bool* ok); | 1620 Statement ParseReturnStatement(bool* ok); |
| 1596 Statement ParseWithStatement(bool* ok); | 1621 Statement ParseWithStatement(bool* ok); |
| 1597 Statement ParseSwitchStatement(bool* ok); | 1622 Statement ParseSwitchStatement(bool* ok); |
| 1598 Statement ParseDoWhileStatement(bool* ok); | 1623 Statement ParseDoWhileStatement(bool* ok); |
| 1599 Statement ParseWhileStatement(bool* ok); | 1624 Statement ParseWhileStatement(bool* ok); |
| 1600 Statement ParseForStatement(bool* ok); | 1625 Statement ParseForStatement(bool* ok); |
| 1601 Statement ParseThrowStatement(bool* ok); | 1626 Statement ParseThrowStatement(bool* ok); |
| 1602 Statement ParseTryStatement(bool* ok); | 1627 Statement ParseTryStatement(bool* ok); |
| 1603 Statement ParseDebuggerStatement(bool* ok); | 1628 Statement ParseDebuggerStatement(bool* ok); |
| 1604 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1629 Expression ParseConditionalExpression(bool accept_IN, bool maybeArrow, |
| 1630 bool* ok); | |
| 1605 Expression ParseObjectLiteral(bool* ok); | 1631 Expression ParseObjectLiteral(bool* ok); |
| 1606 Expression ParseV8Intrinsic(bool* ok); | 1632 Expression ParseV8Intrinsic(bool* ok); |
| 1607 | 1633 |
| 1608 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1634 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1609 int* materialized_literal_count, | 1635 int* materialized_literal_count, |
| 1610 int* expected_property_count, bool* ok); | 1636 int* expected_property_count, bool* ok); |
| 1611 V8_INLINE PreParserStatementList | 1637 V8_INLINE PreParserStatementList |
| 1612 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1638 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1613 Variable* fvar, Token::Value fvar_init_op, | 1639 Variable* fvar, Token::Value fvar_init_op, |
| 1614 FunctionKind kind, bool* ok); | 1640 FunctionKind kind, bool* ok); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1843 | 1869 |
| 1844 // Used in functions where the return type is not ExpressionT. | 1870 // Used in functions where the return type is not ExpressionT. |
| 1845 #define CHECK_OK_CUSTOM(x) ok); \ | 1871 #define CHECK_OK_CUSTOM(x) ok); \ |
| 1846 if (!*ok) return this->x(); \ | 1872 if (!*ok) return this->x(); \ |
| 1847 ((void)0 | 1873 ((void)0 |
| 1848 #define DUMMY ) // to make indentation work | 1874 #define DUMMY ) // to make indentation work |
| 1849 #undef DUMMY | 1875 #undef DUMMY |
| 1850 | 1876 |
| 1851 template <class Traits> | 1877 template <class Traits> |
| 1852 typename ParserBase<Traits>::ExpressionT | 1878 typename ParserBase<Traits>::ExpressionT |
| 1853 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { | 1879 ParserBase<Traits>::ParsePrimaryExpression(bool maybeArrow, bool* ok) { |
| 1854 // PrimaryExpression :: | 1880 // PrimaryExpression :: |
| 1855 // 'this' | 1881 // 'this' |
| 1856 // 'null' | 1882 // 'null' |
| 1857 // 'true' | 1883 // 'true' |
| 1858 // 'false' | 1884 // 'false' |
| 1859 // Identifier | 1885 // Identifier |
| 1860 // Number | 1886 // Number |
| 1861 // String | 1887 // String |
| 1862 // ArrayLiteral | 1888 // ArrayLiteral |
| 1863 // ObjectLiteral | 1889 // ObjectLiteral |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1969 break; | 1995 break; |
| 1970 | 1996 |
| 1971 case Token::MOD: | 1997 case Token::MOD: |
| 1972 if (allow_natives() || extension_ != NULL) { | 1998 if (allow_natives() || extension_ != NULL) { |
| 1973 result = this->ParseV8Intrinsic(CHECK_OK); | 1999 result = this->ParseV8Intrinsic(CHECK_OK); |
| 1974 break; | 2000 break; |
| 1975 } | 2001 } |
| 1976 // If we're not allowing special syntax we fall-through to the | 2002 // If we're not allowing special syntax we fall-through to the |
| 1977 // default case. | 2003 // default case. |
| 1978 | 2004 |
| 2005 case Token::ELLIPSIS: | |
|
arv (Not doing code reviews)
2015/03/11 18:59:13
Beware of fall through here.
| |
| 2006 if (maybeArrow && allow_harmony_arrow_functions() && | |
| 2007 allow_harmony_rest_params()) { | |
| 2008 Consume(Token::ELLIPSIS); | |
| 2009 if (!peek_any_identifier()) { | |
| 2010 ReportUnexpectedToken(token); | |
| 2011 *ok = false; | |
| 2012 break; | |
| 2013 } | |
| 2014 bool is_strict_reserved_name = false; | |
| 2015 IdentifierT name = ParseIdentifierOrStrictReservedWord( | |
| 2016 &is_strict_reserved_name, CHECK_OK); | |
| 2017 if (peek() != Token::RPAREN) { | |
| 2018 ReportUnexpectedTokenAt(Scanner::Location(beg_pos, beg_pos + 3), | |
| 2019 Token::ELLIPSIS); | |
| 2020 *ok = false; | |
| 2021 break; | |
| 2022 } | |
| 2023 result = this->ExpressionFromIdentifier(name, position(), | |
| 2024 peek_position(), scope_, | |
| 2025 factory()); | |
| 2026 return factory()->NewSpread(result, beg_pos); | |
| 2027 } | |
| 2028 | |
| 1979 default: { | 2029 default: { |
| 1980 Next(); | 2030 Next(); |
| 1981 ReportUnexpectedToken(token); | 2031 ReportUnexpectedToken(token); |
| 1982 *ok = false; | 2032 *ok = false; |
| 1983 } | 2033 } |
| 1984 } | 2034 } |
| 1985 | 2035 |
| 1986 return result; | 2036 return result; |
| 1987 } | 2037 } |
| 1988 | 2038 |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2338 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2388 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2339 | 2389 |
| 2340 Scanner::Location lhs_location = scanner()->peek_location(); | 2390 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2341 | 2391 |
| 2342 if (peek() == Token::YIELD && is_generator()) { | 2392 if (peek() == Token::YIELD && is_generator()) { |
| 2343 return this->ParseYieldExpression(ok); | 2393 return this->ParseYieldExpression(ok); |
| 2344 } | 2394 } |
| 2345 | 2395 |
| 2346 if (fni_ != NULL) fni_->Enter(); | 2396 if (fni_ != NULL) fni_->Enter(); |
| 2347 ParserBase<Traits>::Checkpoint checkpoint(this); | 2397 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2398 const bool maybeArrow = | |
| 2399 allow_harmony_arrow_functions() && allow_harmony_rest_params(); | |
| 2348 ExpressionT expression = | 2400 ExpressionT expression = |
| 2349 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2401 this->ParseConditionalExpression(accept_IN, maybeArrow, CHECK_OK); |
| 2350 | 2402 |
| 2351 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2403 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2352 checkpoint.Restore(); | 2404 checkpoint.Restore(); |
| 2405 if (expression->IsSpread() && !expression->is_parenthesized()) { | |
| 2406 // TODO(caitp): the error is an unexpected `...`, it would be nice if we | |
|
arv (Not doing code reviews)
2015/03/11 18:59:12
Can you store the position before calling ParseCon
| |
| 2407 // knew where the `...` occurred. | |
| 2408 ReportUnexpectedToken(peek()); | |
| 2409 *ok = false; | |
| 2410 return this->EmptyExpression(); | |
| 2411 } | |
| 2353 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2412 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
| 2354 expression, CHECK_OK); | 2413 expression, CHECK_OK); |
| 2355 return expression; | 2414 return expression; |
| 2415 } else if (maybeArrow) { | |
| 2416 // TODO(caitp): report an error if an unexpected `...` occurred. | |
|
arv (Not doing code reviews)
2015/03/11 18:59:13
Here it would be good to have an ast ;-)
I'm not
| |
| 2356 } | 2417 } |
| 2357 | 2418 |
| 2358 if (!Token::IsAssignmentOp(peek())) { | 2419 if (!Token::IsAssignmentOp(peek())) { |
| 2359 if (fni_ != NULL) fni_->Leave(); | 2420 if (fni_ != NULL) fni_->Leave(); |
| 2360 // Parsed conditional expression only (no assignment). | 2421 // Parsed conditional expression only (no assignment). |
| 2361 return expression; | 2422 return expression; |
| 2362 } | 2423 } |
| 2363 | 2424 |
| 2364 expression = this->CheckAndRewriteReferenceExpression( | 2425 expression = this->CheckAndRewriteReferenceExpression( |
| 2365 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2426 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2441 if (kind == Yield::kDelegating) { | 2502 if (kind == Yield::kDelegating) { |
| 2442 yield->set_index(function_state_->NextHandlerIndex()); | 2503 yield->set_index(function_state_->NextHandlerIndex()); |
| 2443 } | 2504 } |
| 2444 return yield; | 2505 return yield; |
| 2445 } | 2506 } |
| 2446 | 2507 |
| 2447 | 2508 |
| 2448 // Precedence = 3 | 2509 // Precedence = 3 |
| 2449 template <class Traits> | 2510 template <class Traits> |
| 2450 typename ParserBase<Traits>::ExpressionT | 2511 typename ParserBase<Traits>::ExpressionT |
| 2451 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2512 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool maybeArrow, |
| 2513 bool* ok) { | |
| 2452 // ConditionalExpression :: | 2514 // ConditionalExpression :: |
| 2453 // LogicalOrExpression | 2515 // LogicalOrExpression |
| 2454 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2516 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2455 | 2517 |
| 2456 int pos = peek_position(); | 2518 int pos = peek_position(); |
| 2457 // We start using the binary expression parser for prec >= 4 only! | 2519 // We start using the binary expression parser for prec >= 4 only! |
| 2458 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2520 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, maybeArrow, |
| 2521 CHECK_OK); | |
| 2459 if (peek() != Token::CONDITIONAL) return expression; | 2522 if (peek() != Token::CONDITIONAL) return expression; |
| 2460 Consume(Token::CONDITIONAL); | 2523 Consume(Token::CONDITIONAL); |
| 2461 // In parsing the first assignment expression in conditional | 2524 // In parsing the first assignment expression in conditional |
| 2462 // expressions we always accept the 'in' keyword; see ECMA-262, | 2525 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2463 // section 11.12, page 58. | 2526 // section 11.12, page 58. |
| 2464 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); | 2527 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); |
| 2465 Expect(Token::COLON, CHECK_OK); | 2528 Expect(Token::COLON, CHECK_OK); |
| 2466 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2529 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2467 return factory()->NewConditional(expression, left, right, pos); | 2530 return factory()->NewConditional(expression, left, right, pos); |
| 2468 } | 2531 } |
| 2469 | 2532 |
| 2470 | 2533 |
| 2471 // Precedence >= 4 | 2534 // Precedence >= 4 |
| 2472 template <class Traits> | 2535 template <class Traits> |
| 2473 typename ParserBase<Traits>::ExpressionT | 2536 typename ParserBase<Traits>::ExpressionT |
| 2474 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2537 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 2538 bool maybeArrow, bool* ok) { | |
| 2475 DCHECK(prec >= 4); | 2539 DCHECK(prec >= 4); |
| 2476 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); | 2540 ExpressionT x = this->ParseUnaryExpression(maybeArrow, CHECK_OK); |
| 2477 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2541 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2478 // prec1 >= 4 | 2542 // prec1 >= 4 |
| 2479 while (Precedence(peek(), accept_IN) == prec1) { | 2543 while (Precedence(peek(), accept_IN) == prec1) { |
| 2480 Token::Value op = Next(); | 2544 Token::Value op = Next(); |
| 2481 Scanner::Location op_location = scanner()->location(); | 2545 Scanner::Location op_location = scanner()->location(); |
| 2482 int pos = position(); | 2546 int pos = position(); |
| 2483 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2547 // Only allow arrow extensions in binary expressions if op is comma |
| 2548 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, | |
| 2549 maybeArrow && op == Token::COMMA, | |
| 2550 CHECK_OK); | |
| 2484 | 2551 |
| 2485 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2552 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 2486 factory())) { | 2553 factory())) { |
| 2487 continue; | 2554 continue; |
| 2488 } | 2555 } |
| 2489 | 2556 |
| 2490 // For now we distinguish between comparisons and other binary | 2557 // For now we distinguish between comparisons and other binary |
| 2491 // operations. (We could combine the two and get rid of this | 2558 // operations. (We could combine the two and get rid of this |
| 2492 // code and AST node eventually.) | 2559 // code and AST node eventually.) |
| 2493 if (Token::IsCompareOp(op)) { | 2560 if (Token::IsCompareOp(op)) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2514 x = factory()->NewBinaryOperation(op, x, y, pos); | 2581 x = factory()->NewBinaryOperation(op, x, y, pos); |
| 2515 } | 2582 } |
| 2516 } | 2583 } |
| 2517 } | 2584 } |
| 2518 return x; | 2585 return x; |
| 2519 } | 2586 } |
| 2520 | 2587 |
| 2521 | 2588 |
| 2522 template <class Traits> | 2589 template <class Traits> |
| 2523 typename ParserBase<Traits>::ExpressionT | 2590 typename ParserBase<Traits>::ExpressionT |
| 2524 ParserBase<Traits>::ParseUnaryExpression(bool* ok) { | 2591 ParserBase<Traits>::ParseUnaryExpression(bool maybeArrow, bool* ok) { |
| 2525 // UnaryExpression :: | 2592 // UnaryExpression :: |
| 2526 // PostfixExpression | 2593 // PostfixExpression |
| 2527 // 'delete' UnaryExpression | 2594 // 'delete' UnaryExpression |
| 2528 // 'void' UnaryExpression | 2595 // 'void' UnaryExpression |
| 2529 // 'typeof' UnaryExpression | 2596 // 'typeof' UnaryExpression |
| 2530 // '++' UnaryExpression | 2597 // '++' UnaryExpression |
| 2531 // '--' UnaryExpression | 2598 // '--' UnaryExpression |
| 2532 // '+' UnaryExpression | 2599 // '+' UnaryExpression |
| 2533 // '-' UnaryExpression | 2600 // '-' UnaryExpression |
| 2534 // '~' UnaryExpression | 2601 // '~' UnaryExpression |
| 2535 // '!' UnaryExpression | 2602 // '!' UnaryExpression |
| 2536 | 2603 |
| 2537 Token::Value op = peek(); | 2604 Token::Value op = peek(); |
| 2538 if (Token::IsUnaryOp(op)) { | 2605 if (Token::IsUnaryOp(op)) { |
| 2539 op = Next(); | 2606 op = Next(); |
| 2540 int pos = position(); | 2607 int pos = position(); |
| 2541 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 2608 ExpressionT expression = ParseUnaryExpression(false, CHECK_OK); |
| 2542 | 2609 |
| 2543 if (op == Token::DELETE && is_strict(language_mode())) { | 2610 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2544 if (is_strong(language_mode())) { | 2611 if (is_strong(language_mode())) { |
| 2545 ReportMessage("strong_delete"); | 2612 ReportMessage("strong_delete"); |
| 2546 *ok = false; | 2613 *ok = false; |
| 2547 return this->EmptyExpression(); | 2614 return this->EmptyExpression(); |
| 2548 } else if (this->IsIdentifier(expression)) { | 2615 } else if (this->IsIdentifier(expression)) { |
| 2549 // "delete identifier" is a syntax error in strict mode. | 2616 // "delete identifier" is a syntax error in strict mode. |
| 2550 ReportMessage("strict_delete"); | 2617 ReportMessage("strict_delete"); |
| 2551 *ok = false; | 2618 *ok = false; |
| 2552 return this->EmptyExpression(); | 2619 return this->EmptyExpression(); |
| 2553 } | 2620 } |
| 2554 } | 2621 } |
| 2555 | 2622 |
| 2556 // Allow Traits do rewrite the expression. | 2623 // Allow Traits do rewrite the expression. |
| 2557 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2624 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 2558 } else if (Token::IsCountOp(op)) { | 2625 } else if (Token::IsCountOp(op)) { |
| 2559 op = Next(); | 2626 op = Next(); |
| 2560 Scanner::Location lhs_location = scanner()->peek_location(); | 2627 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2561 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); | 2628 ExpressionT expression = this->ParseUnaryExpression(false, CHECK_OK); |
| 2562 expression = this->CheckAndRewriteReferenceExpression( | 2629 expression = this->CheckAndRewriteReferenceExpression( |
| 2563 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2630 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
| 2564 this->MarkExpressionAsAssigned(expression); | 2631 this->MarkExpressionAsAssigned(expression); |
| 2565 | 2632 |
| 2566 return factory()->NewCountOperation(op, | 2633 return factory()->NewCountOperation(op, |
| 2567 true /* prefix */, | 2634 true /* prefix */, |
| 2568 expression, | 2635 expression, |
| 2569 position()); | 2636 position()); |
| 2570 | 2637 |
| 2571 } else { | 2638 } else { |
| 2572 return this->ParsePostfixExpression(ok); | 2639 return this->ParsePostfixExpression(maybeArrow, ok); |
| 2573 } | 2640 } |
| 2574 } | 2641 } |
| 2575 | 2642 |
| 2576 | 2643 |
| 2577 template <class Traits> | 2644 template <class Traits> |
| 2578 typename ParserBase<Traits>::ExpressionT | 2645 typename ParserBase<Traits>::ExpressionT |
| 2579 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { | 2646 ParserBase<Traits>::ParsePostfixExpression(bool maybeArrow, bool* ok) { |
| 2580 // PostfixExpression :: | 2647 // PostfixExpression :: |
| 2581 // LeftHandSideExpression ('++' | '--')? | 2648 // LeftHandSideExpression ('++' | '--')? |
| 2582 | 2649 |
| 2583 Scanner::Location lhs_location = scanner()->peek_location(); | 2650 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2584 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); | 2651 ExpressionT expression = this->ParseLeftHandSideExpression(maybeArrow, |
| 2652 CHECK_OK); | |
| 2585 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2653 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2586 Token::IsCountOp(peek())) { | 2654 Token::IsCountOp(peek())) { |
| 2587 expression = this->CheckAndRewriteReferenceExpression( | 2655 expression = this->CheckAndRewriteReferenceExpression( |
| 2588 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 2656 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
| 2589 expression = this->MarkExpressionAsAssigned(expression); | 2657 expression = this->MarkExpressionAsAssigned(expression); |
| 2590 | 2658 |
| 2591 Token::Value next = Next(); | 2659 Token::Value next = Next(); |
| 2592 expression = | 2660 expression = |
| 2593 factory()->NewCountOperation(next, | 2661 factory()->NewCountOperation(next, |
| 2594 false /* postfix */, | 2662 false /* postfix */, |
| 2595 expression, | 2663 expression, |
| 2596 position()); | 2664 position()); |
| 2597 } | 2665 } |
| 2598 return expression; | 2666 return expression; |
| 2599 } | 2667 } |
| 2600 | 2668 |
| 2601 | 2669 |
| 2602 template <class Traits> | 2670 template <class Traits> |
| 2603 typename ParserBase<Traits>::ExpressionT | 2671 typename ParserBase<Traits>::ExpressionT |
| 2604 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { | 2672 ParserBase<Traits>::ParseLeftHandSideExpression(bool maybeArrow, bool* ok) { |
| 2605 // LeftHandSideExpression :: | 2673 // LeftHandSideExpression :: |
| 2606 // (NewExpression | MemberExpression) ... | 2674 // (NewExpression | MemberExpression) ... |
| 2607 | 2675 |
| 2608 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2676 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
| 2677 maybeArrow, CHECK_OK); | |
| 2609 | 2678 |
| 2610 while (true) { | 2679 while (true) { |
| 2611 switch (peek()) { | 2680 switch (peek()) { |
| 2612 case Token::LBRACK: { | 2681 case Token::LBRACK: { |
| 2613 Consume(Token::LBRACK); | 2682 Consume(Token::LBRACK); |
| 2614 int pos = position(); | 2683 int pos = position(); |
| 2615 ExpressionT index = ParseExpression(true, CHECK_OK); | 2684 ExpressionT index = ParseExpression(true, CHECK_OK); |
| 2616 result = factory()->NewProperty(result, index, pos); | 2685 result = factory()->NewProperty(result, index, pos); |
| 2617 Expect(Token::RBRACK, CHECK_OK); | 2686 Expect(Token::RBRACK, CHECK_OK); |
| 2618 break; | 2687 break; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2682 | 2751 |
| 2683 default: | 2752 default: |
| 2684 return result; | 2753 return result; |
| 2685 } | 2754 } |
| 2686 } | 2755 } |
| 2687 } | 2756 } |
| 2688 | 2757 |
| 2689 | 2758 |
| 2690 template <class Traits> | 2759 template <class Traits> |
| 2691 typename ParserBase<Traits>::ExpressionT | 2760 typename ParserBase<Traits>::ExpressionT |
| 2692 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 2761 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| 2762 bool maybeArrow, bool* ok) { | |
| 2693 // NewExpression :: | 2763 // NewExpression :: |
| 2694 // ('new')+ MemberExpression | 2764 // ('new')+ MemberExpression |
| 2695 | 2765 |
| 2696 // The grammar for new expressions is pretty warped. We can have several 'new' | 2766 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2697 // keywords following each other, and then a MemberExpression. When we see '(' | 2767 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2698 // after the MemberExpression, it's associated with the rightmost unassociated | 2768 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2699 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2769 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 2700 // can also occur without arguments. | 2770 // can also occur without arguments. |
| 2701 | 2771 |
| 2702 // Examples of new expression: | 2772 // Examples of new expression: |
| 2703 // new foo.bar().baz means (new (foo.bar)()).baz | 2773 // new foo.bar().baz means (new (foo.bar)()).baz |
| 2704 // new foo()() means (new foo())() | 2774 // new foo()() means (new foo())() |
| 2705 // new new foo()() means (new (new foo())()) | 2775 // new new foo()() means (new (new foo())()) |
| 2706 // new new foo means new (new foo) | 2776 // new new foo means new (new foo) |
| 2707 // new new foo() means new (new foo()) | 2777 // new new foo() means new (new foo()) |
| 2708 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2778 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 2709 | 2779 |
| 2710 if (peek() == Token::NEW) { | 2780 if (peek() == Token::NEW) { |
| 2711 Consume(Token::NEW); | 2781 Consume(Token::NEW); |
| 2712 int new_pos = position(); | 2782 int new_pos = position(); |
| 2713 ExpressionT result = this->EmptyExpression(); | 2783 ExpressionT result = this->EmptyExpression(); |
| 2714 if (peek() == Token::SUPER) { | 2784 if (peek() == Token::SUPER) { |
| 2715 const bool is_new = true; | 2785 const bool is_new = true; |
| 2716 result = ParseSuperExpression(is_new, CHECK_OK); | 2786 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2717 } else { | 2787 } else { |
| 2718 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2788 result = this->ParseMemberWithNewPrefixesExpression(maybeArrow, CHECK_OK); |
| 2719 } | 2789 } |
| 2720 if (peek() == Token::LPAREN) { | 2790 if (peek() == Token::LPAREN) { |
| 2721 // NewExpression with arguments. | 2791 // NewExpression with arguments. |
| 2722 typename Traits::Type::ExpressionList args = | 2792 typename Traits::Type::ExpressionList args = |
| 2723 this->ParseArguments(CHECK_OK); | 2793 this->ParseArguments(CHECK_OK); |
| 2724 result = factory()->NewCallNew(result, args, new_pos); | 2794 result = factory()->NewCallNew(result, args, new_pos); |
| 2725 // The expression can still continue with . or [ after the arguments. | 2795 // The expression can still continue with . or [ after the arguments. |
| 2726 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2796 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2727 return result; | 2797 return result; |
| 2728 } | 2798 } |
| 2729 // NewExpression without arguments. | 2799 // NewExpression without arguments. |
| 2730 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2800 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2731 new_pos); | 2801 new_pos); |
| 2732 } | 2802 } |
| 2733 // No 'new' or 'super' keyword. | 2803 // No 'new' or 'super' keyword. |
| 2734 return this->ParseMemberExpression(ok); | 2804 return this->ParseMemberExpression(maybeArrow, ok); |
| 2735 } | 2805 } |
| 2736 | 2806 |
| 2737 | 2807 |
| 2738 template <class Traits> | 2808 template <class Traits> |
| 2739 typename ParserBase<Traits>::ExpressionT | 2809 typename ParserBase<Traits>::ExpressionT |
| 2740 ParserBase<Traits>::ParseMemberExpression(bool* ok) { | 2810 ParserBase<Traits>::ParseMemberExpression(bool maybeArrow, bool* ok) { |
| 2741 // MemberExpression :: | 2811 // MemberExpression :: |
| 2742 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2812 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 2743 // ('[' Expression ']' | '.' Identifier | Arguments)* | 2813 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 2744 | 2814 |
| 2745 // The '[' Expression ']' and '.' Identifier parts are parsed by | 2815 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 2746 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 2816 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 2747 // caller. | 2817 // caller. |
| 2748 | 2818 |
| 2749 // Parse the initial primary or function expression. | 2819 // Parse the initial primary or function expression. |
| 2750 ExpressionT result = this->EmptyExpression(); | 2820 ExpressionT result = this->EmptyExpression(); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2766 result = this->ParseFunctionLiteral( | 2836 result = this->ParseFunctionLiteral( |
| 2767 name, function_name_location, is_strict_reserved_name, | 2837 name, function_name_location, is_strict_reserved_name, |
| 2768 is_generator ? FunctionKind::kGeneratorFunction | 2838 is_generator ? FunctionKind::kGeneratorFunction |
| 2769 : FunctionKind::kNormalFunction, | 2839 : FunctionKind::kNormalFunction, |
| 2770 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 2840 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
| 2771 CHECK_OK); | 2841 CHECK_OK); |
| 2772 } else if (peek() == Token::SUPER) { | 2842 } else if (peek() == Token::SUPER) { |
| 2773 const bool is_new = false; | 2843 const bool is_new = false; |
| 2774 result = ParseSuperExpression(is_new, CHECK_OK); | 2844 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2775 } else { | 2845 } else { |
| 2776 result = ParsePrimaryExpression(CHECK_OK); | 2846 result = ParsePrimaryExpression(maybeArrow, CHECK_OK); |
| 2777 } | 2847 } |
| 2778 | 2848 |
| 2779 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2849 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2780 return result; | 2850 return result; |
| 2781 } | 2851 } |
| 2782 | 2852 |
| 2783 | 2853 |
| 2784 template <class Traits> | 2854 template <class Traits> |
| 2785 typename ParserBase<Traits>::ExpressionT | 2855 typename ParserBase<Traits>::ExpressionT |
| 2786 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 2856 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3135 *ok = false; | 3205 *ok = false; |
| 3136 return; | 3206 return; |
| 3137 } | 3207 } |
| 3138 has_seen_constructor_ = true; | 3208 has_seen_constructor_ = true; |
| 3139 return; | 3209 return; |
| 3140 } | 3210 } |
| 3141 } | 3211 } |
| 3142 } } // v8::internal | 3212 } } // v8::internal |
| 3143 | 3213 |
| 3144 #endif // V8_PREPARSER_H | 3214 #endif // V8_PREPARSER_H |
| OLD | NEW |