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

Side by Side Diff: src/preparser.h

Issue 997823003: [es6] support rest parameters in arrow functions (alternative) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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') | src/preparser.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 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698