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

Side by Side Diff: src/preparser.h

Issue 987083003: [es6] support rest parameters in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix preparser bug 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
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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 bool stack_overflow() const { return stack_overflow_; } 331 bool stack_overflow() const { return stack_overflow_; }
332 void set_stack_overflow() { stack_overflow_ = true; } 332 void set_stack_overflow() { stack_overflow_ = true; }
333 Mode mode() const { return mode_; } 333 Mode mode() const { return mode_; }
334 Zone* zone() const { return zone_; } 334 Zone* zone() const { return zone_; }
335 335
336 INLINE(Token::Value peek()) { 336 INLINE(Token::Value peek()) {
337 if (stack_overflow_) return Token::ILLEGAL; 337 if (stack_overflow_) return Token::ILLEGAL;
338 return scanner()->peek(); 338 return scanner()->peek();
339 } 339 }
340 340
341 INLINE(Token::Value peek(int n)) {
342 if (stack_overflow_) return Token::ILLEGAL;
343 return scanner()->peek(n);
344 }
345
341 INLINE(Token::Value Next()) { 346 INLINE(Token::Value Next()) {
342 if (stack_overflow_) return Token::ILLEGAL; 347 if (stack_overflow_) return Token::ILLEGAL;
343 { 348 {
344 if (GetCurrentStackPosition() < stack_limit_) { 349 if (GetCurrentStackPosition() < stack_limit_) {
345 // Any further calls to Next or peek will return the illegal token. 350 // Any further calls to Next or peek will return the illegal token.
346 // The current call must return the next token, which might already 351 // The current call must return the next token, which might already
347 // have been peek'ed. 352 // have been peek'ed.
348 stack_overflow_ = true; 353 stack_overflow_ = true;
349 } 354 }
350 } 355 }
351 return scanner()->Next(); 356 return scanner()->Next();
352 } 357 }
353 358
359 void PeekScan(int until);
360
354 void Consume(Token::Value token) { 361 void Consume(Token::Value token) {
355 Token::Value next = Next(); 362 Token::Value next = Next();
356 USE(next); 363 USE(next);
357 USE(token); 364 USE(token);
358 DCHECK(next == token); 365 DCHECK(next == token);
359 } 366 }
360 367
361 bool Check(Token::Value token) { 368 bool Check(Token::Value token) {
362 Token::Value next = peek(); 369 Token::Value next = peek();
363 if (next == token) { 370 if (next == token) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 Traits::ReportMessageAt(source_location, message, arg, error_type); 539 Traits::ReportMessageAt(source_location, message, arg, error_type);
533 } 540 }
534 541
535 void ReportMessageAt(Scanner::Location location, const char* message, 542 void ReportMessageAt(Scanner::Location location, const char* message,
536 ParseErrorType error_type = kSyntaxError) { 543 ParseErrorType error_type = kSyntaxError) {
537 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), 544 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
538 error_type); 545 error_type);
539 } 546 }
540 547
541 void ReportUnexpectedToken(Token::Value token); 548 void ReportUnexpectedToken(Token::Value token);
549 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
542 550
543 // Recursive descent functions: 551 // Recursive descent functions:
544 552
545 // Parses an identifier that is valid for the current scope, in particular it 553 // Parses an identifier that is valid for the current scope, in particular it
546 // fails on strict mode future reserved keywords in a strict scope. If 554 // fails on strict mode future reserved keywords in a strict scope. If
547 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 555 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
548 // "arguments" as identifier even in strict mode (this is needed in cases like 556 // "arguments" as identifier even in strict mode (this is needed in cases like
549 // "var foo = eval;"). 557 // "var foo = eval;").
550 IdentifierT ParseIdentifier( 558 IdentifierT ParseIdentifier(
551 AllowEvalOrArgumentsAsIdentifier, 559 AllowEvalOrArgumentsAsIdentifier,
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 public: 784 public:
777 static PreParserExpression Default() { 785 static PreParserExpression Default() {
778 return PreParserExpression(TypeField::encode(kExpression)); 786 return PreParserExpression(TypeField::encode(kExpression));
779 } 787 }
780 788
781 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 789 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
782 return PreParserExpression(TypeField::encode(kIdentifierExpression) | 790 return PreParserExpression(TypeField::encode(kIdentifierExpression) |
783 IdentifierTypeField::encode(id.type_)); 791 IdentifierTypeField::encode(id.type_));
784 } 792 }
785 793
794 static PreParserExpression SpreadOperation(PreParserExpression expr) {
795 return PreParserExpression(TypeField::encode(
796 kSpreadExpression) | expr.code_);
797 }
798
786 static PreParserExpression BinaryOperation(PreParserExpression left, 799 static PreParserExpression BinaryOperation(PreParserExpression left,
787 Token::Value op, 800 Token::Value op,
788 PreParserExpression right) { 801 PreParserExpression right) {
789 bool valid_arrow_param_list = 802 bool valid_arrow_param_list =
790 op == Token::COMMA && !left.is_parenthesized() && 803 op == Token::COMMA && !left.is_parenthesized() &&
791 !right.is_parenthesized() && left.IsValidArrowParams() && 804 !right.is_parenthesized() && left.IsValidArrowParams() &&
792 right.IsValidArrowParams(); 805 right.IsValidArrowParams();
793 return PreParserExpression( 806 return PreParserExpression(
794 TypeField::encode(kBinaryOperationExpression) | 807 TypeField::encode(kBinaryOperationExpression) |
795 IsValidArrowParamListField::encode(valid_arrow_param_list)); 808 IsValidArrowParamListField::encode(valid_arrow_param_list));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 bool IsValidReferenceExpression() const { 903 bool IsValidReferenceExpression() const {
891 return IsIdentifier() || IsProperty(); 904 return IsIdentifier() || IsProperty();
892 } 905 }
893 906
894 bool IsValidArrowParamList() const { 907 bool IsValidArrowParamList() const {
895 return IsValidArrowParams() && 908 return IsValidArrowParams() &&
896 ParenthesizationField::decode(code_) != 909 ParenthesizationField::decode(code_) !=
897 kMultiParenthesizedExpression; 910 kMultiParenthesizedExpression;
898 } 911 }
899 912
913 bool IsSpreadOperation() const {
914 return TypeField::decode(code_) & kSpreadExpression;
marja 2015/03/10 09:11:19 Hmm... so this works because kSpreadExpression hap
915 }
916
917 PreParserExpression SpreadExpression() const {
918 DCHECK(IsSpreadOperation());
919 return PreParserExpression(TypeField::decode(code_) & ~kSpreadExpression);
920 }
921
900 // At the moment PreParser doesn't track these expression types. 922 // At the moment PreParser doesn't track these expression types.
901 bool IsFunctionLiteral() const { return false; } 923 bool IsFunctionLiteral() const { return false; }
902 bool IsCallNew() const { return false; } 924 bool IsCallNew() const { return false; }
903 925
904 bool IsNoTemplateTag() const { 926 bool IsNoTemplateTag() const {
905 return TypeField::decode(code_) == kExpression && 927 return TypeField::decode(code_) == kExpression &&
906 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; 928 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
907 } 929 }
908 930
909 PreParserExpression AsFunctionLiteral() { return *this; } 931 PreParserExpression AsFunctionLiteral() { return *this; }
(...skipping 21 matching lines...) Expand all
931 void set_parenthesized() {} 953 void set_parenthesized() {}
932 954
933 int position() const { return RelocInfo::kNoPosition; } 955 int position() const { return RelocInfo::kNoPosition; }
934 void set_function_token_position(int position) {} 956 void set_function_token_position(int position) {}
935 957
936 private: 958 private:
937 enum Type { 959 enum Type {
938 kExpression, 960 kExpression,
939 kIdentifierExpression, 961 kIdentifierExpression,
940 kStringLiteralExpression, 962 kStringLiteralExpression,
941 kBinaryOperationExpression 963 kBinaryOperationExpression,
964 kSpreadExpression
marja 2015/03/10 09:11:19 So maybe add "= 1 << 3 " here to hint that kSpread
942 }; 965 };
943 966
944 enum Parenthesization { 967 enum Parenthesization {
945 kNotParenthesized, 968 kNotParenthesized,
946 kParanthesizedExpression, 969 kParanthesizedExpression,
947 kMultiParenthesizedExpression 970 kMultiParenthesizedExpression
948 }; 971 };
949 972
950 enum ExpressionType { 973 enum ExpressionType {
marja 2015/03/10 09:11:19 (Huh, why do we have Type and ExpressionType? Urgh
951 kThisExpression, 974 kThisExpression,
952 kThisPropertyExpression, 975 kThisPropertyExpression,
953 kPropertyExpression, 976 kPropertyExpression,
954 kCallExpression, 977 kCallExpression,
955 kNoTemplateTagExpression 978 kNoTemplateTagExpression
956 }; 979 };
957 980
958 explicit PreParserExpression(uint32_t expression_code) 981 explicit PreParserExpression(uint32_t expression_code)
959 : code_(expression_code) {} 982 : code_(expression_code) {}
960 983
961 V8_INLINE bool IsValidArrowParams() const { 984 V8_INLINE bool IsValidArrowParams() const {
985 if (IsSpreadOperation()) {
986 return SpreadExpression().IsValidArrowParams();
987 }
962 return IsBinaryOperation() 988 return IsBinaryOperation()
963 ? IsValidArrowParamListField::decode(code_) 989 ? IsValidArrowParamListField::decode(code_)
964 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); 990 : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
965 } 991 }
966 992
967 // The first four bits are for the Type and Parenthesization. 993 // The first four bits are for the Type and Parenthesization.
968 typedef BitField<Type, 0, 2> TypeField; 994 typedef BitField<Type, 0, 3> TypeField;
969 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; 995 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField;
970 996
971 // The rest of the bits are interpreted depending on the value 997 // The rest of the bits are interpreted depending on the value
972 // of the Type field, so they can share the storage. 998 // of the Type field, so they can share the storage.
973 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> 999 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3>
974 ExpressionTypeField; 1000 ExpressionTypeField;
975 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; 1001 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
976 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; 1002 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
977 typedef BitField<bool, ParenthesizationField::kNext, 1> 1003 typedef BitField<bool, ParenthesizationField::kNext, 1>
978 IsValidArrowParamListField; 1004 IsValidArrowParamListField;
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 PreParserIdentifier name, AstValueFactory* ast_value_factory, 1200 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1175 Scope* scope, PreParserStatementList body, int materialized_literal_count, 1201 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1176 int expected_property_count, int handler_count, int parameter_count, 1202 int expected_property_count, int handler_count, int parameter_count,
1177 FunctionLiteral::ParameterFlag has_duplicate_parameters, 1203 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1178 FunctionLiteral::FunctionType function_type, 1204 FunctionLiteral::FunctionType function_type,
1179 FunctionLiteral::IsFunctionFlag is_function, 1205 FunctionLiteral::IsFunctionFlag is_function,
1180 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, 1206 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
1181 int position) { 1207 int position) {
1182 return PreParserExpression::Default(); 1208 return PreParserExpression::Default();
1183 } 1209 }
1210 PreParserExpression NewSpreadOperation(PreParserExpression expr, int pos) {
1211 return PreParserExpression::SpreadOperation(expr);
1212 }
1184 1213
1185 // Return the object itself as AstVisitor and implement the needed 1214 // Return the object itself as AstVisitor and implement the needed
1186 // dummy method right in this class. 1215 // dummy method right in this class.
1187 PreParserFactory* visitor() { return this; } 1216 PreParserFactory* visitor() { return this; }
1188 int* ast_properties() { 1217 int* ast_properties() {
1189 static int dummy = 42; 1218 static int dummy = 42;
1190 return &dummy; 1219 return &dummy;
1191 } 1220 }
1192 }; 1221 };
1193 1222
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 1704
1676 template <class Traits> 1705 template <class Traits>
1677 ParserBase<Traits>::FunctionState::~FunctionState() { 1706 ParserBase<Traits>::FunctionState::~FunctionState() {
1678 *scope_stack_ = outer_scope_; 1707 *scope_stack_ = outer_scope_;
1679 *function_state_stack_ = outer_function_state_; 1708 *function_state_stack_ = outer_function_state_;
1680 } 1709 }
1681 1710
1682 1711
1683 template<class Traits> 1712 template<class Traits>
1684 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1713 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1685 Scanner::Location source_location = scanner()->location(); 1714 return ReportUnexpectedTokenAt(scanner()->location(), token);
1715 }
1686 1716
1717
1718 template <class Traits>
1719 void ParserBase<Traits>::ReportUnexpectedTokenAt(Scanner::Location location,
1720 Token::Value token) {
1687 // Four of the tokens are treated specially 1721 // Four of the tokens are treated specially
1688 switch (token) { 1722 switch (token) {
1689 case Token::EOS: 1723 case Token::EOS:
1690 return ReportMessageAt(source_location, "unexpected_eos"); 1724 return ReportMessageAt(location, "unexpected_eos");
1691 case Token::SMI: 1725 case Token::SMI:
1692 case Token::NUMBER: 1726 case Token::NUMBER:
1693 return ReportMessageAt(source_location, "unexpected_token_number"); 1727 return ReportMessageAt(location, "unexpected_token_number");
1694 case Token::STRING: 1728 case Token::STRING:
1695 return ReportMessageAt(source_location, "unexpected_token_string"); 1729 return ReportMessageAt(location, "unexpected_token_string");
1696 case Token::IDENTIFIER: 1730 case Token::IDENTIFIER:
1697 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1731 return ReportMessageAt(location, "unexpected_token_identifier");
1698 case Token::FUTURE_RESERVED_WORD: 1732 case Token::FUTURE_RESERVED_WORD:
1699 return ReportMessageAt(source_location, "unexpected_reserved"); 1733 return ReportMessageAt(location, "unexpected_reserved");
1700 case Token::LET: 1734 case Token::LET:
1701 case Token::STATIC: 1735 case Token::STATIC:
1702 case Token::YIELD: 1736 case Token::YIELD:
1703 case Token::FUTURE_STRICT_RESERVED_WORD: 1737 case Token::FUTURE_STRICT_RESERVED_WORD:
1704 return ReportMessageAt(source_location, 1738 return ReportMessageAt(location, is_strict(language_mode())
1705 is_strict(language_mode()) 1739 ? "unexpected_strict_reserved"
1706 ? "unexpected_strict_reserved" 1740 : "unexpected_token_identifier");
1707 : "unexpected_token_identifier");
1708 case Token::TEMPLATE_SPAN: 1741 case Token::TEMPLATE_SPAN:
1709 case Token::TEMPLATE_TAIL: 1742 case Token::TEMPLATE_TAIL:
1710 return Traits::ReportMessageAt(source_location, 1743 return Traits::ReportMessageAt(location, "unexpected_template_string");
1711 "unexpected_template_string");
1712 default: 1744 default:
1713 const char* name = Token::String(token); 1745 const char* name = Token::String(token);
1714 DCHECK(name != NULL); 1746 DCHECK(name != NULL);
1715 Traits::ReportMessageAt(source_location, "unexpected_token", name); 1747 Traits::ReportMessageAt(location, "unexpected_token", name);
1716 } 1748 }
1717 } 1749 }
1718 1750
1719 1751
1720 template<class Traits> 1752 template<class Traits>
1721 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1753 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1722 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1754 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1723 bool* ok) { 1755 bool* ok) {
1724 Token::Value next = Next(); 1756 Token::Value next = Next();
1725 if (next == Token::IDENTIFIER) { 1757 if (next == Token::IDENTIFIER) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 // 'false' 1884 // 'false'
1853 // Identifier 1885 // Identifier
1854 // Number 1886 // Number
1855 // String 1887 // String
1856 // ArrayLiteral 1888 // ArrayLiteral
1857 // ObjectLiteral 1889 // ObjectLiteral
1858 // RegExpLiteral 1890 // RegExpLiteral
1859 // ClassLiteral 1891 // ClassLiteral
1860 // '(' Expression ')' 1892 // '(' Expression ')'
1861 // TemplateLiteral 1893 // TemplateLiteral
1894 // ... Identifier ')' '=>'
arv (Not doing code reviews) 2015/03/10 13:44:02 Why ')' '=>'?
caitp (gmail) 2015/03/10 14:47:51 So, you're right that we can just check for the `)
1862 1895
1863 int beg_pos = scanner()->peek_location().beg_pos; 1896 int beg_pos = scanner()->peek_location().beg_pos;
1864 int end_pos = scanner()->peek_location().end_pos; 1897 int end_pos = scanner()->peek_location().end_pos;
1865 ExpressionT result = this->EmptyExpression(); 1898 ExpressionT result = this->EmptyExpression();
1866 Token::Value token = peek(); 1899 Token::Value token = peek();
1867 switch (token) { 1900 switch (token) {
1868 case Token::THIS: { 1901 case Token::THIS: {
1869 Consume(Token::THIS); 1902 Consume(Token::THIS);
1870 scope_->RecordThisUsage(); 1903 scope_->RecordThisUsage();
1871 result = this->ThisExpression(scope_, factory(), beg_pos); 1904 result = this->ThisExpression(scope_, factory(), beg_pos);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 Consume(Token::RPAREN); 1957 Consume(Token::RPAREN);
1925 result = this->ParseArrowFunctionLiteral( 1958 result = this->ParseArrowFunctionLiteral(
1926 beg_pos, this->EmptyArrowParamList(), CHECK_OK); 1959 beg_pos, this->EmptyArrowParamList(), CHECK_OK);
1927 } else { 1960 } else {
1928 // Heuristically try to detect immediately called functions before 1961 // Heuristically try to detect immediately called functions before
1929 // seeing the call parentheses. 1962 // seeing the call parentheses.
1930 parenthesized_function_ = (peek() == Token::FUNCTION); 1963 parenthesized_function_ = (peek() == Token::FUNCTION);
1931 result = this->ParseExpression(true, CHECK_OK); 1964 result = this->ParseExpression(true, CHECK_OK);
1932 result->increase_parenthesization_level(); 1965 result->increase_parenthesization_level();
1933 Expect(Token::RPAREN, CHECK_OK); 1966 Expect(Token::RPAREN, CHECK_OK);
1967 if (peek() == Token::ARROW) {
1968 int x = 5;
marja 2015/03/10 09:11:19 ?
arv (Not doing code reviews) 2015/03/10 13:44:02 Looks like debug code... remove?
caitp (gmail) 2015/03/10 14:47:51 Hah, yeah --- I'll get rid of that =)
1969 USE(x);
1970 }
1934 } 1971 }
1935 break; 1972 break;
1936 1973
1937 case Token::CLASS: { 1974 case Token::CLASS: {
1938 Consume(Token::CLASS); 1975 Consume(Token::CLASS);
1939 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 1976 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
1940 ReportMessage("sloppy_lexical", NULL); 1977 ReportMessage("sloppy_lexical", NULL);
1941 *ok = false; 1978 *ok = false;
1942 break; 1979 break;
1943 } 1980 }
(...skipping 19 matching lines...) Expand all
1963 break; 2000 break;
1964 2001
1965 case Token::MOD: 2002 case Token::MOD:
1966 if (allow_natives() || extension_ != NULL) { 2003 if (allow_natives() || extension_ != NULL) {
1967 result = this->ParseV8Intrinsic(CHECK_OK); 2004 result = this->ParseV8Intrinsic(CHECK_OK);
1968 break; 2005 break;
1969 } 2006 }
1970 // If we're not allowing special syntax we fall-through to the 2007 // If we're not allowing special syntax we fall-through to the
1971 // default case. 2008 // default case.
1972 2009
2010 case Token::ELLIPSIS:
2011 // Not a valid primary expression, but valid in parenthesized arrow
2012 // function.
2013 //
2014 // Fail if name, closing parenthesis and arrow token are not found.
2015 if (allow_harmony_rest_params() && allow_harmony_arrow_functions()) {
2016 Consume(Token::ELLIPSIS);
2017 bool is_strict_reserved_name = false;
2018 IdentifierT name = ParseIdentifierOrStrictReservedWord(
2019 &is_strict_reserved_name, CHECK_OK);
arv (Not doing code reviews) 2015/03/10 13:44:03 I don't see where is_strict_reserved_name is being
caitp (gmail) 2015/03/10 14:47:51 to match the function signature... pretty much jus
2020 if (peek() == Token::COMMA) {
2021 *ok = false;
2022 ReportMessageAt(scanner_->peek_location(), "param_after_rest");
2023 break;
2024 } else if (peek() != Token::RPAREN) {
2025 ReportUnexpectedTokenAt(scanner_->peek_location(), peek());
2026 *ok = false;
2027 break;
2028 }
2029
2030 if (peek(1) != Token::ARROW) {
2031 ReportUnexpectedTokenAt(scanner_->peek_location(1), peek(1));
arv (Not doing code reviews) 2015/03/10 13:44:03 Another option here is to report the invalid `...`
2032 *ok = false;
2033 break;
2034 }
2035
2036 Scanner::Location name_pos = scanner_->location();
2037 result = this->ExpressionFromIdentifier(
2038 name, name_pos.beg_pos, name_pos.end_pos, scope_, factory());
2039
2040 return factory()->NewSpreadOperation(result, beg_pos);
2041 }
2042
1973 default: { 2043 default: {
1974 Next(); 2044 Next();
1975 ReportUnexpectedToken(token); 2045 ReportUnexpectedToken(token);
1976 *ok = false; 2046 *ok = false;
1977 } 2047 }
1978 } 2048 }
1979 2049
1980 return result; 2050 return result;
1981 } 2051 }
1982 2052
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
2758 name, function_name_location, is_strict_reserved_name, 2828 name, function_name_location, is_strict_reserved_name,
2759 is_generator ? FunctionKind::kGeneratorFunction 2829 is_generator ? FunctionKind::kGeneratorFunction
2760 : FunctionKind::kNormalFunction, 2830 : FunctionKind::kNormalFunction,
2761 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, 2831 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
2762 CHECK_OK); 2832 CHECK_OK);
2763 } else if (peek() == Token::SUPER) { 2833 } else if (peek() == Token::SUPER) {
2764 const bool is_new = false; 2834 const bool is_new = false;
2765 result = ParseSuperExpression(is_new, CHECK_OK); 2835 result = ParseSuperExpression(is_new, CHECK_OK);
2766 } else { 2836 } else {
2767 result = ParsePrimaryExpression(CHECK_OK); 2837 result = ParsePrimaryExpression(CHECK_OK);
2838 if (result->IsSpreadOperation()) {
2839 // SpreadOperation is only parsed here as the last parameter of an
2840 // arrow function. It's not a valid MemberExpression, and there is no
2841 // continuation.
2842 return result;
2843 }
2768 } 2844 }
2769 2845
2770 result = ParseMemberExpressionContinuation(result, CHECK_OK); 2846 result = ParseMemberExpressionContinuation(result, CHECK_OK);
2771 return result; 2847 return result;
2772 } 2848 }
2773 2849
2774 2850
2775 template <class Traits> 2851 template <class Traits>
2776 typename ParserBase<Traits>::ExpressionT 2852 typename ParserBase<Traits>::ExpressionT
2777 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { 2853 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 *ok = false; 3193 *ok = false;
3118 return; 3194 return;
3119 } 3195 }
3120 has_seen_constructor_ = true; 3196 has_seen_constructor_ = true;
3121 return; 3197 return;
3122 } 3198 }
3123 } 3199 }
3124 } } // v8::internal 3200 } } // v8::internal
3125 3201
3126 #endif // V8_PREPARSER_H 3202 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698