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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 stack_overflow_(false), | 108 stack_overflow_(false), |
109 allow_lazy_(false), | 109 allow_lazy_(false), |
110 allow_natives_(false), | 110 allow_natives_(false), |
111 allow_harmony_sloppy_(false), | 111 allow_harmony_sloppy_(false), |
112 allow_harmony_sloppy_function_(false), | 112 allow_harmony_sloppy_function_(false), |
113 allow_harmony_sloppy_let_(false), | 113 allow_harmony_sloppy_let_(false), |
114 allow_harmony_default_parameters_(false), | 114 allow_harmony_default_parameters_(false), |
115 allow_harmony_destructuring_bind_(false), | 115 allow_harmony_destructuring_bind_(false), |
116 allow_harmony_destructuring_assignment_(false), | 116 allow_harmony_destructuring_assignment_(false), |
117 allow_harmony_restrictive_declarations_(false), | 117 allow_harmony_restrictive_declarations_(false), |
118 allow_strong_mode_(false), | |
119 allow_legacy_const_(true), | 118 allow_legacy_const_(true), |
120 allow_harmony_do_expressions_(false), | 119 allow_harmony_do_expressions_(false), |
121 allow_harmony_function_name_(false), | 120 allow_harmony_function_name_(false), |
122 allow_harmony_function_sent_(false) {} | 121 allow_harmony_function_sent_(false) {} |
123 | 122 |
124 #define ALLOW_ACCESSORS(name) \ | 123 #define ALLOW_ACCESSORS(name) \ |
125 bool allow_##name() const { return allow_##name##_; } \ | 124 bool allow_##name() const { return allow_##name##_; } \ |
126 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 125 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
127 | 126 |
128 ALLOW_ACCESSORS(lazy); | 127 ALLOW_ACCESSORS(lazy); |
129 ALLOW_ACCESSORS(natives); | 128 ALLOW_ACCESSORS(natives); |
130 ALLOW_ACCESSORS(harmony_sloppy); | 129 ALLOW_ACCESSORS(harmony_sloppy); |
131 ALLOW_ACCESSORS(harmony_sloppy_function); | 130 ALLOW_ACCESSORS(harmony_sloppy_function); |
132 ALLOW_ACCESSORS(harmony_sloppy_let); | 131 ALLOW_ACCESSORS(harmony_sloppy_let); |
133 ALLOW_ACCESSORS(harmony_default_parameters); | 132 ALLOW_ACCESSORS(harmony_default_parameters); |
134 ALLOW_ACCESSORS(harmony_destructuring_bind); | 133 ALLOW_ACCESSORS(harmony_destructuring_bind); |
135 ALLOW_ACCESSORS(harmony_destructuring_assignment); | 134 ALLOW_ACCESSORS(harmony_destructuring_assignment); |
136 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 135 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
137 ALLOW_ACCESSORS(strong_mode); | |
138 ALLOW_ACCESSORS(legacy_const); | 136 ALLOW_ACCESSORS(legacy_const); |
139 ALLOW_ACCESSORS(harmony_do_expressions); | 137 ALLOW_ACCESSORS(harmony_do_expressions); |
140 ALLOW_ACCESSORS(harmony_function_name); | 138 ALLOW_ACCESSORS(harmony_function_name); |
141 ALLOW_ACCESSORS(harmony_function_sent); | 139 ALLOW_ACCESSORS(harmony_function_sent); |
142 #undef ALLOW_ACCESSORS | 140 #undef ALLOW_ACCESSORS |
143 | 141 |
144 uintptr_t stack_limit() const { return stack_limit_; } | 142 uintptr_t stack_limit() const { return stack_limit_; } |
145 | 143 |
146 protected: | 144 protected: |
147 enum AllowRestrictedIdentifiers { | 145 enum AllowRestrictedIdentifiers { |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 Expect(Token::IDENTIFIER, ok); | 474 Expect(Token::IDENTIFIER, ok); |
477 if (!*ok) return; | 475 if (!*ok) return; |
478 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 476 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
479 ReportUnexpectedToken(scanner()->current_token()); | 477 ReportUnexpectedToken(scanner()->current_token()); |
480 *ok = false; | 478 *ok = false; |
481 } | 479 } |
482 } | 480 } |
483 | 481 |
484 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { | 482 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { |
485 if (Check(Token::IN)) { | 483 if (Check(Token::IN)) { |
486 if (is_strong(language_mode())) { | 484 *visit_mode = ForEachStatement::ENUMERATE; |
487 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn); | |
488 *ok = false; | |
489 } else { | |
490 *visit_mode = ForEachStatement::ENUMERATE; | |
491 } | |
492 return true; | 485 return true; |
493 } else if (CheckContextualKeyword(CStrVector("of"))) { | 486 } else if (CheckContextualKeyword(CStrVector("of"))) { |
494 *visit_mode = ForEachStatement::ITERATE; | 487 *visit_mode = ForEachStatement::ITERATE; |
495 return true; | 488 return true; |
496 } | 489 } |
497 return false; | 490 return false; |
498 } | 491 } |
499 | 492 |
500 bool PeekInOrOf() { | 493 bool PeekInOrOf() { |
501 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); | 494 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 MessageTemplate::kStrictEvalArguments); | 535 MessageTemplate::kStrictEvalArguments); |
543 *ok = false; | 536 *ok = false; |
544 return; | 537 return; |
545 } | 538 } |
546 if (function_name_validity == kFunctionNameIsStrictReserved) { | 539 if (function_name_validity == kFunctionNameIsStrictReserved) { |
547 Traits::ReportMessageAt(function_name_loc, | 540 Traits::ReportMessageAt(function_name_loc, |
548 MessageTemplate::kUnexpectedStrictReserved); | 541 MessageTemplate::kUnexpectedStrictReserved); |
549 *ok = false; | 542 *ok = false; |
550 return; | 543 return; |
551 } | 544 } |
552 if (is_strong(language_mode) && this->IsUndefined(function_name)) { | |
553 Traits::ReportMessageAt(function_name_loc, | |
554 MessageTemplate::kStrongUndefined); | |
555 *ok = false; | |
556 return; | |
557 } | |
558 } | 545 } |
559 | 546 |
560 // Determine precedence of given token. | 547 // Determine precedence of given token. |
561 static int Precedence(Token::Value token, bool accept_IN) { | 548 static int Precedence(Token::Value token, bool accept_IN) { |
562 if (token == Token::IN && !accept_IN) | 549 if (token == Token::IN && !accept_IN) |
563 return 0; // 0 precedence will terminate binary expression parsing | 550 return 0; // 0 precedence will terminate binary expression parsing |
564 return Token::Precedence(token); | 551 return Token::Precedence(token); |
565 } | 552 } |
566 | 553 |
567 typename Traits::Type::Factory* factory() { | 554 typename Traits::Type::Factory* factory() { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 LanguageMode language_mode, | 639 LanguageMode language_mode, |
653 bool allow_duplicates, bool* ok) { | 640 bool allow_duplicates, bool* ok) { |
654 if (!allow_duplicates && | 641 if (!allow_duplicates && |
655 !classifier->is_valid_formal_parameter_list_without_duplicates()) { | 642 !classifier->is_valid_formal_parameter_list_without_duplicates()) { |
656 ReportClassifierError(classifier->duplicate_formal_parameter_error()); | 643 ReportClassifierError(classifier->duplicate_formal_parameter_error()); |
657 *ok = false; | 644 *ok = false; |
658 } else if (is_strict(language_mode) && | 645 } else if (is_strict(language_mode) && |
659 !classifier->is_valid_strict_mode_formal_parameters()) { | 646 !classifier->is_valid_strict_mode_formal_parameters()) { |
660 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); | 647 ReportClassifierError(classifier->strict_mode_formal_parameter_error()); |
661 *ok = false; | 648 *ok = false; |
662 } else if (is_strong(language_mode) && | |
663 !classifier->is_valid_strong_mode_formal_parameters()) { | |
664 ReportClassifierError(classifier->strong_mode_formal_parameter_error()); | |
665 *ok = false; | |
666 } | 649 } |
667 } | 650 } |
668 | 651 |
669 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 652 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
670 ExpressionT expr, | 653 ExpressionT expr, |
671 bool parenthesized_formals, bool* ok) { | 654 bool parenthesized_formals, bool* ok) { |
672 if (classifier->is_valid_binding_pattern()) { | 655 if (classifier->is_valid_binding_pattern()) { |
673 // A simple arrow formal parameter: IDENTIFIER => BODY. | 656 // A simple arrow formal parameter: IDENTIFIER => BODY. |
674 if (!this->IsIdentifier(expr)) { | 657 if (!this->IsIdentifier(expr)) { |
675 Traits::ReportMessageAt(scanner()->location(), | 658 Traits::ReportMessageAt(scanner()->location(), |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 782 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
800 const FormalParametersT& parameters, | 783 const FormalParametersT& parameters, |
801 const ExpressionClassifier& classifier, | 784 const ExpressionClassifier& classifier, |
802 bool* ok); | 785 bool* ok); |
803 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 786 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
804 ExpressionClassifier* classifier, bool* ok); | 787 ExpressionClassifier* classifier, bool* ok); |
805 void AddTemplateExpression(ExpressionT); | 788 void AddTemplateExpression(ExpressionT); |
806 ExpressionT ParseSuperExpression(bool is_new, | 789 ExpressionT ParseSuperExpression(bool is_new, |
807 ExpressionClassifier* classifier, bool* ok); | 790 ExpressionClassifier* classifier, bool* ok); |
808 ExpressionT ParseNewTargetExpression(bool* ok); | 791 ExpressionT ParseNewTargetExpression(bool* ok); |
809 ExpressionT ParseStrongInitializationExpression( | |
810 ExpressionClassifier* classifier, bool* ok); | |
811 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, | |
812 bool* ok); | |
813 | 792 |
814 void ParseFormalParameter(FormalParametersT* parameters, | 793 void ParseFormalParameter(FormalParametersT* parameters, |
815 ExpressionClassifier* classifier, bool* ok); | 794 ExpressionClassifier* classifier, bool* ok); |
816 void ParseFormalParameterList(FormalParametersT* parameters, | 795 void ParseFormalParameterList(FormalParametersT* parameters, |
817 ExpressionClassifier* classifier, bool* ok); | 796 ExpressionClassifier* classifier, bool* ok); |
818 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 797 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
819 bool has_rest, int formals_start_pos, | 798 bool has_rest, int formals_start_pos, |
820 int formals_end_pos, bool* ok); | 799 int formals_end_pos, bool* ok); |
821 | 800 |
822 bool IsNextLetKeyword(); | 801 bool IsNextLetKeyword(); |
(...skipping 13 matching lines...) Expand all Loading... |
836 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 815 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
837 | 816 |
838 bool IsValidReferenceExpression(ExpressionT expression); | 817 bool IsValidReferenceExpression(ExpressionT expression); |
839 | 818 |
840 bool IsAssignableIdentifier(ExpressionT expression) { | 819 bool IsAssignableIdentifier(ExpressionT expression) { |
841 if (!Traits::IsIdentifier(expression)) return false; | 820 if (!Traits::IsIdentifier(expression)) return false; |
842 if (is_strict(language_mode()) && | 821 if (is_strict(language_mode()) && |
843 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { | 822 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { |
844 return false; | 823 return false; |
845 } | 824 } |
846 if (is_strong(language_mode()) && | |
847 Traits::IsUndefined(Traits::AsIdentifier(expression))) { | |
848 return false; | |
849 } | |
850 return true; | 825 return true; |
851 } | 826 } |
852 | 827 |
853 bool IsValidPattern(ExpressionT expression) { | 828 bool IsValidPattern(ExpressionT expression) { |
854 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); | 829 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
855 } | 830 } |
856 | 831 |
857 // Keep track of eval() calls since they disable all local variable | 832 // Keep track of eval() calls since they disable all local variable |
858 // optimizations. This checks if expression is an eval call, and if yes, | 833 // optimizations. This checks if expression is an eval call, and if yes, |
859 // forwards the information to scope. | 834 // forwards the information to scope. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 | 922 |
948 bool allow_lazy_; | 923 bool allow_lazy_; |
949 bool allow_natives_; | 924 bool allow_natives_; |
950 bool allow_harmony_sloppy_; | 925 bool allow_harmony_sloppy_; |
951 bool allow_harmony_sloppy_function_; | 926 bool allow_harmony_sloppy_function_; |
952 bool allow_harmony_sloppy_let_; | 927 bool allow_harmony_sloppy_let_; |
953 bool allow_harmony_default_parameters_; | 928 bool allow_harmony_default_parameters_; |
954 bool allow_harmony_destructuring_bind_; | 929 bool allow_harmony_destructuring_bind_; |
955 bool allow_harmony_destructuring_assignment_; | 930 bool allow_harmony_destructuring_assignment_; |
956 bool allow_harmony_restrictive_declarations_; | 931 bool allow_harmony_restrictive_declarations_; |
957 bool allow_strong_mode_; | |
958 bool allow_legacy_const_; | 932 bool allow_legacy_const_; |
959 bool allow_harmony_do_expressions_; | 933 bool allow_harmony_do_expressions_; |
960 bool allow_harmony_function_name_; | 934 bool allow_harmony_function_name_; |
961 bool allow_harmony_function_sent_; | 935 bool allow_harmony_function_sent_; |
962 }; | 936 }; |
963 | 937 |
964 template <class Traits> | 938 template <class Traits> |
965 ParserBase<Traits>::FunctionState::FunctionState( | 939 ParserBase<Traits>::FunctionState::FunctionState( |
966 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 940 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
967 FunctionKind kind, typename Traits::Type::Factory* factory) | 941 FunctionKind kind, typename Traits::Type::Factory* factory) |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 } | 1071 } |
1098 } | 1072 } |
1099 if (this->IsArguments(name)) { | 1073 if (this->IsArguments(name)) { |
1100 scope_->RecordArgumentsUsage(); | 1074 scope_->RecordArgumentsUsage(); |
1101 classifier->RecordStrictModeFormalParameterError( | 1075 classifier->RecordStrictModeFormalParameterError( |
1102 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1076 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1103 if (is_strict(language_mode())) { | 1077 if (is_strict(language_mode())) { |
1104 classifier->RecordBindingPatternError( | 1078 classifier->RecordBindingPatternError( |
1105 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1079 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
1106 } | 1080 } |
1107 if (is_strong(language_mode())) { | |
1108 classifier->RecordExpressionError(scanner()->location(), | |
1109 MessageTemplate::kStrongArguments); | |
1110 } | |
1111 } | |
1112 if (this->IsUndefined(name)) { | |
1113 classifier->RecordStrongModeFormalParameterError( | |
1114 scanner()->location(), MessageTemplate::kStrongUndefined); | |
1115 if (is_strong(language_mode())) { | |
1116 // TODO(dslomov): allow 'undefined' in nested patterns. | |
1117 classifier->RecordPatternError(scanner()->location(), | |
1118 MessageTemplate::kStrongUndefined); | |
1119 } | |
1120 } | 1081 } |
1121 | 1082 |
1122 if (classifier->duplicate_finder() != nullptr && | 1083 if (classifier->duplicate_finder() != nullptr && |
1123 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1084 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
1124 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1085 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
1125 } | 1086 } |
1126 return name; | 1087 return name; |
1127 } else if (is_sloppy(language_mode()) && | 1088 } else if (is_sloppy(language_mode()) && |
1128 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1089 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
1129 next == Token::ESCAPED_STRICT_RESERVED_WORD || | 1090 next == Token::ESCAPED_STRICT_RESERVED_WORD || |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 // ClassLiteral | 1214 // ClassLiteral |
1254 // '(' Expression ')' | 1215 // '(' Expression ')' |
1255 // TemplateLiteral | 1216 // TemplateLiteral |
1256 // do Block | 1217 // do Block |
1257 | 1218 |
1258 int beg_pos = peek_position(); | 1219 int beg_pos = peek_position(); |
1259 switch (peek()) { | 1220 switch (peek()) { |
1260 case Token::THIS: { | 1221 case Token::THIS: { |
1261 BindingPatternUnexpectedToken(classifier); | 1222 BindingPatternUnexpectedToken(classifier); |
1262 Consume(Token::THIS); | 1223 Consume(Token::THIS); |
1263 if (FLAG_strong_this && is_strong(language_mode())) { | |
1264 // Constructors' usages of 'this' in strong mode are parsed separately. | |
1265 // TODO(rossberg): this does not work with arrow functions yet. | |
1266 if (IsClassConstructor(function_state_->kind())) { | |
1267 ReportMessage(MessageTemplate::kStrongConstructorThis); | |
1268 *ok = false; | |
1269 return this->EmptyExpression(); | |
1270 } | |
1271 } | |
1272 return this->ThisExpression(scope_, factory(), beg_pos); | 1224 return this->ThisExpression(scope_, factory(), beg_pos); |
1273 } | 1225 } |
1274 | 1226 |
1275 case Token::NULL_LITERAL: | 1227 case Token::NULL_LITERAL: |
1276 case Token::TRUE_LITERAL: | 1228 case Token::TRUE_LITERAL: |
1277 case Token::FALSE_LITERAL: | 1229 case Token::FALSE_LITERAL: |
1278 BindingPatternUnexpectedToken(classifier); | 1230 BindingPatternUnexpectedToken(classifier); |
1279 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1231 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1280 case Token::SMI: | 1232 case Token::SMI: |
1281 case Token::NUMBER: | 1233 case Token::NUMBER: |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 // '[' Expression? (',' Expression?)* ']' | 1453 // '[' Expression? (',' Expression?)* ']' |
1502 | 1454 |
1503 int pos = peek_position(); | 1455 int pos = peek_position(); |
1504 typename Traits::Type::ExpressionList values = | 1456 typename Traits::Type::ExpressionList values = |
1505 this->NewExpressionList(4, zone_); | 1457 this->NewExpressionList(4, zone_); |
1506 int first_spread_index = -1; | 1458 int first_spread_index = -1; |
1507 Expect(Token::LBRACK, CHECK_OK); | 1459 Expect(Token::LBRACK, CHECK_OK); |
1508 while (peek() != Token::RBRACK) { | 1460 while (peek() != Token::RBRACK) { |
1509 ExpressionT elem = this->EmptyExpression(); | 1461 ExpressionT elem = this->EmptyExpression(); |
1510 if (peek() == Token::COMMA) { | 1462 if (peek() == Token::COMMA) { |
1511 if (is_strong(language_mode())) { | |
1512 ReportMessageAt(scanner()->peek_location(), | |
1513 MessageTemplate::kStrongEllision); | |
1514 *ok = false; | |
1515 return this->EmptyExpression(); | |
1516 } | |
1517 elem = this->GetLiteralTheHole(peek_position(), factory()); | 1463 elem = this->GetLiteralTheHole(peek_position(), factory()); |
1518 } else if (peek() == Token::ELLIPSIS) { | 1464 } else if (peek() == Token::ELLIPSIS) { |
1519 int start_pos = peek_position(); | 1465 int start_pos = peek_position(); |
1520 Consume(Token::ELLIPSIS); | 1466 Consume(Token::ELLIPSIS); |
1521 int expr_pos = peek_position(); | 1467 int expr_pos = peek_position(); |
1522 ExpressionT argument = | 1468 ExpressionT argument = |
1523 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1469 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
1524 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1470 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
1525 | 1471 |
1526 if (first_spread_index < 0) { | 1472 if (first_spread_index < 0) { |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2205 bool* ok) { | 2151 bool* ok) { |
2206 DCHECK(prec >= 4); | 2152 DCHECK(prec >= 4); |
2207 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2153 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2208 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2154 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2209 // prec1 >= 4 | 2155 // prec1 >= 4 |
2210 while (Precedence(peek(), accept_IN) == prec1) { | 2156 while (Precedence(peek(), accept_IN) == prec1) { |
2211 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2157 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2212 BindingPatternUnexpectedToken(classifier); | 2158 BindingPatternUnexpectedToken(classifier); |
2213 ArrowFormalParametersUnexpectedToken(classifier); | 2159 ArrowFormalParametersUnexpectedToken(classifier); |
2214 Token::Value op = Next(); | 2160 Token::Value op = Next(); |
2215 Scanner::Location op_location = scanner()->location(); | |
2216 int pos = position(); | 2161 int pos = position(); |
2217 ExpressionT y = | 2162 ExpressionT y = |
2218 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); | 2163 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
2219 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2164 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2220 | 2165 |
2221 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2166 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2222 factory())) { | 2167 factory())) { |
2223 continue; | 2168 continue; |
2224 } | 2169 } |
2225 | 2170 |
2226 // For now we distinguish between comparisons and other binary | 2171 // For now we distinguish between comparisons and other binary |
2227 // operations. (We could combine the two and get rid of this | 2172 // operations. (We could combine the two and get rid of this |
2228 // code and AST node eventually.) | 2173 // code and AST node eventually.) |
2229 if (Token::IsCompareOp(op)) { | 2174 if (Token::IsCompareOp(op)) { |
2230 // We have a comparison. | 2175 // We have a comparison. |
2231 Token::Value cmp = op; | 2176 Token::Value cmp = op; |
2232 switch (op) { | 2177 switch (op) { |
2233 case Token::NE: cmp = Token::EQ; break; | 2178 case Token::NE: cmp = Token::EQ; break; |
2234 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 2179 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
2235 default: break; | 2180 default: break; |
2236 } | 2181 } |
2237 if (cmp == Token::EQ && is_strong(language_mode())) { | 2182 if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) { |
2238 ReportMessageAt(op_location, MessageTemplate::kStrongEqual); | |
2239 *ok = false; | |
2240 return this->EmptyExpression(); | |
2241 } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) { | |
2242 x = Traits::RewriteInstanceof(x, y, pos); | 2183 x = Traits::RewriteInstanceof(x, y, pos); |
2243 } else { | 2184 } else { |
2244 x = factory()->NewCompareOperation(cmp, x, y, pos); | 2185 x = factory()->NewCompareOperation(cmp, x, y, pos); |
2245 if (cmp != op) { | 2186 if (cmp != op) { |
2246 // The comparison was negated - add a NOT. | 2187 // The comparison was negated - add a NOT. |
2247 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | 2188 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
2248 } | 2189 } |
2249 } | 2190 } |
2250 } else { | 2191 } else { |
2251 // We have a "normal" binary operation. | 2192 // We have a "normal" binary operation. |
(...skipping 25 matching lines...) Expand all Loading... |
2277 if (Token::IsUnaryOp(op)) { | 2218 if (Token::IsUnaryOp(op)) { |
2278 BindingPatternUnexpectedToken(classifier); | 2219 BindingPatternUnexpectedToken(classifier); |
2279 ArrowFormalParametersUnexpectedToken(classifier); | 2220 ArrowFormalParametersUnexpectedToken(classifier); |
2280 | 2221 |
2281 op = Next(); | 2222 op = Next(); |
2282 int pos = position(); | 2223 int pos = position(); |
2283 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2224 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2284 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2225 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2285 | 2226 |
2286 if (op == Token::DELETE && is_strict(language_mode())) { | 2227 if (op == Token::DELETE && is_strict(language_mode())) { |
2287 if (is_strong(language_mode())) { | 2228 if (this->IsIdentifier(expression)) { |
2288 ReportMessage(MessageTemplate::kStrongDelete); | |
2289 *ok = false; | |
2290 return this->EmptyExpression(); | |
2291 } else if (this->IsIdentifier(expression)) { | |
2292 // "delete identifier" is a syntax error in strict mode. | 2229 // "delete identifier" is a syntax error in strict mode. |
2293 ReportMessage(MessageTemplate::kStrictDelete); | 2230 ReportMessage(MessageTemplate::kStrictDelete); |
2294 *ok = false; | 2231 *ok = false; |
2295 return this->EmptyExpression(); | 2232 return this->EmptyExpression(); |
2296 } | 2233 } |
2297 } | 2234 } |
2298 | 2235 |
2299 // Allow Traits do rewrite the expression. | 2236 // Allow Traits do rewrite the expression. |
2300 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2237 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2301 } else if (Token::IsCountOp(op)) { | 2238 } else if (Token::IsCountOp(op)) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2376 result = factory()->NewProperty(result, index, pos); | 2313 result = factory()->NewProperty(result, index, pos); |
2377 Expect(Token::RBRACK, CHECK_OK); | 2314 Expect(Token::RBRACK, CHECK_OK); |
2378 break; | 2315 break; |
2379 } | 2316 } |
2380 | 2317 |
2381 case Token::LPAREN: { | 2318 case Token::LPAREN: { |
2382 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2319 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2383 BindingPatternUnexpectedToken(classifier); | 2320 BindingPatternUnexpectedToken(classifier); |
2384 ArrowFormalParametersUnexpectedToken(classifier); | 2321 ArrowFormalParametersUnexpectedToken(classifier); |
2385 | 2322 |
2386 if (is_strong(language_mode()) && this->IsIdentifier(result) && | |
2387 this->IsEval(this->AsIdentifier(result))) { | |
2388 ReportMessage(MessageTemplate::kStrongDirectEval); | |
2389 *ok = false; | |
2390 return this->EmptyExpression(); | |
2391 } | |
2392 int pos; | 2323 int pos; |
2393 if (scanner()->current_token() == Token::IDENTIFIER || | 2324 if (scanner()->current_token() == Token::IDENTIFIER || |
2394 scanner()->current_token() == Token::SUPER) { | 2325 scanner()->current_token() == Token::SUPER) { |
2395 // For call of an identifier we want to report position of | 2326 // For call of an identifier we want to report position of |
2396 // the identifier as position of the call in the stack trace. | 2327 // the identifier as position of the call in the stack trace. |
2397 pos = position(); | 2328 pos = position(); |
2398 } else { | 2329 } else { |
2399 // For other kinds of calls we record position of the parenthesis as | 2330 // For other kinds of calls we record position of the parenthesis as |
2400 // position of the call. Note that this is extremely important for | 2331 // position of the call. Note that this is extremely important for |
2401 // expressions of the form function(){...}() for which call position | 2332 // expressions of the form function(){...}() for which call position |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2530 result = ParsePrimaryExpression(classifier, CHECK_OK); |
2600 } | 2531 } |
2601 | 2532 |
2602 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2533 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
2603 return result; | 2534 return result; |
2604 } | 2535 } |
2605 | 2536 |
2606 | 2537 |
2607 template <class Traits> | 2538 template <class Traits> |
2608 typename ParserBase<Traits>::ExpressionT | 2539 typename ParserBase<Traits>::ExpressionT |
2609 ParserBase<Traits>::ParseStrongInitializationExpression( | |
2610 ExpressionClassifier* classifier, bool* ok) { | |
2611 // InitializationExpression :: (strong mode) | |
2612 // 'this' '.' IdentifierName '=' AssignmentExpression | |
2613 // 'this' '[' Expression ']' '=' AssignmentExpression | |
2614 | |
2615 FuncNameInferrer::State fni_state(fni_); | |
2616 | |
2617 Consume(Token::THIS); | |
2618 int pos = position(); | |
2619 function_state_->set_this_location(scanner()->location()); | |
2620 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
2621 | |
2622 ExpressionT left = this->EmptyExpression(); | |
2623 switch (peek()) { | |
2624 case Token::LBRACK: { | |
2625 Consume(Token::LBRACK); | |
2626 int pos = position(); | |
2627 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | |
2628 Traits::RewriteNonPattern(classifier, CHECK_OK); | |
2629 left = factory()->NewProperty(this_expr, index, pos); | |
2630 if (fni_ != NULL) { | |
2631 this->PushPropertyName(fni_, index); | |
2632 } | |
2633 Expect(Token::RBRACK, CHECK_OK); | |
2634 break; | |
2635 } | |
2636 case Token::PERIOD: { | |
2637 Consume(Token::PERIOD); | |
2638 int pos = position(); | |
2639 IdentifierT name = ParseIdentifierName(CHECK_OK); | |
2640 left = factory()->NewProperty( | |
2641 this_expr, factory()->NewStringLiteral(name, pos), pos); | |
2642 if (fni_ != NULL) { | |
2643 this->PushLiteralName(fni_, name); | |
2644 } | |
2645 break; | |
2646 } | |
2647 default: | |
2648 ReportMessage(MessageTemplate::kStrongConstructorThis); | |
2649 *ok = false; | |
2650 return this->EmptyExpression(); | |
2651 } | |
2652 | |
2653 if (peek() != Token::ASSIGN) { | |
2654 ReportMessageAt(function_state_->this_location(), | |
2655 MessageTemplate::kStrongConstructorThis); | |
2656 *ok = false; | |
2657 return this->EmptyExpression(); | |
2658 } | |
2659 Consume(Token::ASSIGN); | |
2660 left = this->MarkExpressionAsAssigned(left); | |
2661 | |
2662 ExpressionT right = | |
2663 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | |
2664 Traits::RewriteNonPattern(classifier, CHECK_OK); | |
2665 this->CheckAssigningFunctionLiteralToProperty(left, right); | |
2666 function_state_->AddProperty(); | |
2667 if (fni_ != NULL) { | |
2668 // Check if the right hand side is a call to avoid inferring a | |
2669 // name if we're dealing with "this.a = function(){...}();"-like | |
2670 // expression. | |
2671 if (!right->IsCall() && !right->IsCallNew()) { | |
2672 fni_->Infer(); | |
2673 } else { | |
2674 fni_->RemoveLastFunction(); | |
2675 } | |
2676 } | |
2677 | |
2678 if (function_state_->return_location().IsValid()) { | |
2679 ReportMessageAt(function_state_->return_location(), | |
2680 MessageTemplate::kStrongConstructorReturnMisplaced); | |
2681 *ok = false; | |
2682 return this->EmptyExpression(); | |
2683 } | |
2684 | |
2685 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | |
2686 } | |
2687 | |
2688 | |
2689 template <class Traits> | |
2690 typename ParserBase<Traits>::ExpressionT | |
2691 ParserBase<Traits>::ParseStrongSuperCallExpression( | |
2692 ExpressionClassifier* classifier, bool* ok) { | |
2693 // SuperCallExpression :: (strong mode) | |
2694 // 'super' '(' ExpressionList ')' | |
2695 BindingPatternUnexpectedToken(classifier); | |
2696 | |
2697 Consume(Token::SUPER); | |
2698 int pos = position(); | |
2699 Scanner::Location super_loc = scanner()->location(); | |
2700 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos); | |
2701 | |
2702 if (peek() != Token::LPAREN) { | |
2703 ReportMessage(MessageTemplate::kStrongConstructorSuper); | |
2704 *ok = false; | |
2705 return this->EmptyExpression(); | |
2706 } | |
2707 | |
2708 Scanner::Location spread_pos; | |
2709 typename Traits::Type::ExpressionList args = | |
2710 ParseArguments(&spread_pos, classifier, CHECK_OK); | |
2711 | |
2712 // TODO(rossberg): This doesn't work with arrow functions yet. | |
2713 if (!IsSubclassConstructor(function_state_->kind())) { | |
2714 ReportMessage(MessageTemplate::kUnexpectedSuper); | |
2715 *ok = false; | |
2716 return this->EmptyExpression(); | |
2717 } else if (function_state_->super_location().IsValid()) { | |
2718 ReportMessageAt(scanner()->location(), | |
2719 MessageTemplate::kStrongSuperCallDuplicate); | |
2720 *ok = false; | |
2721 return this->EmptyExpression(); | |
2722 } else if (function_state_->this_location().IsValid()) { | |
2723 ReportMessageAt(scanner()->location(), | |
2724 MessageTemplate::kStrongSuperCallMisplaced); | |
2725 *ok = false; | |
2726 return this->EmptyExpression(); | |
2727 } else if (function_state_->return_location().IsValid()) { | |
2728 ReportMessageAt(function_state_->return_location(), | |
2729 MessageTemplate::kStrongConstructorReturnMisplaced); | |
2730 *ok = false; | |
2731 return this->EmptyExpression(); | |
2732 } | |
2733 | |
2734 function_state_->set_super_location(super_loc); | |
2735 if (spread_pos.IsValid()) { | |
2736 args = Traits::PrepareSpreadArguments(args); | |
2737 expr = Traits::SpreadCall(expr, args, pos); | |
2738 } else { | |
2739 expr = factory()->NewCall(expr, args, pos); | |
2740 } | |
2741 | |
2742 // Explicit calls to the super constructor using super() perform an implicit | |
2743 // binding assignment to the 'this' variable. | |
2744 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
2745 return factory()->NewAssignment(Token::INIT, this_expr, expr, pos); | |
2746 } | |
2747 | |
2748 | |
2749 template <class Traits> | |
2750 typename ParserBase<Traits>::ExpressionT | |
2751 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 2540 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
2752 ExpressionClassifier* classifier, | 2541 ExpressionClassifier* classifier, |
2753 bool* ok) { | 2542 bool* ok) { |
2754 Expect(Token::SUPER, CHECK_OK); | 2543 Expect(Token::SUPER, CHECK_OK); |
2755 int pos = position(); | 2544 int pos = position(); |
2756 | 2545 |
2757 Scope* scope = scope_->ReceiverScope(); | 2546 Scope* scope = scope_->ReceiverScope(); |
2758 FunctionKind kind = scope->function_kind(); | 2547 FunctionKind kind = scope->function_kind(); |
2759 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 2548 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
2760 IsClassConstructor(kind)) { | 2549 IsClassConstructor(kind)) { |
2761 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 2550 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
2762 scope->RecordSuperPropertyUsage(); | 2551 scope->RecordSuperPropertyUsage(); |
2763 return this->SuperPropertyReference(scope_, factory(), pos); | 2552 return this->SuperPropertyReference(scope_, factory(), pos); |
2764 } | 2553 } |
2765 // new super() is never allowed. | 2554 // new super() is never allowed. |
2766 // super() is only allowed in derived constructor | 2555 // super() is only allowed in derived constructor |
2767 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 2556 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
2768 if (is_strong(language_mode())) { | |
2769 // Super calls in strong mode are parsed separately. | |
2770 ReportMessageAt(scanner()->location(), | |
2771 MessageTemplate::kStrongConstructorSuper); | |
2772 *ok = false; | |
2773 return this->EmptyExpression(); | |
2774 } | |
2775 // TODO(rossberg): This might not be the correct FunctionState for the | 2557 // TODO(rossberg): This might not be the correct FunctionState for the |
2776 // method here. | 2558 // method here. |
2777 function_state_->set_super_location(scanner()->location()); | 2559 function_state_->set_super_location(scanner()->location()); |
2778 return this->SuperCallReference(scope_, factory(), pos); | 2560 return this->SuperCallReference(scope_, factory(), pos); |
2779 } | 2561 } |
2780 } | 2562 } |
2781 | 2563 |
2782 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); | 2564 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); |
2783 *ok = false; | 2565 *ok = false; |
2784 return this->EmptyExpression(); | 2566 return this->EmptyExpression(); |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, | 3047 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, |
3266 int end_pos, MessageTemplate::Template message, ParseErrorType type) { | 3048 int end_pos, MessageTemplate::Template message, ParseErrorType type) { |
3267 Scanner::Location location(beg_pos, end_pos); | 3049 Scanner::Location location(beg_pos, end_pos); |
3268 if (this->IsIdentifier(expression)) { | 3050 if (this->IsIdentifier(expression)) { |
3269 if (is_strict(language_mode()) && | 3051 if (is_strict(language_mode()) && |
3270 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3052 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3271 classifier->RecordExpressionError( | 3053 classifier->RecordExpressionError( |
3272 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); | 3054 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); |
3273 return expression; | 3055 return expression; |
3274 } | 3056 } |
3275 if (is_strong(language_mode()) && | |
3276 this->IsUndefined(this->AsIdentifier(expression))) { | |
3277 classifier->RecordExpressionError( | |
3278 location, MessageTemplate::kStrongUndefined, kSyntaxError); | |
3279 return expression; | |
3280 } | |
3281 } | 3057 } |
3282 if (expression->IsValidReferenceExpression()) { | 3058 if (expression->IsValidReferenceExpression()) { |
3283 return expression; | 3059 return expression; |
3284 } else if (expression->IsCall()) { | 3060 } else if (expression->IsCall()) { |
3285 // If it is a call, make it a runtime error for legacy web compatibility. | 3061 // If it is a call, make it a runtime error for legacy web compatibility. |
3286 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3062 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3287 int pos = location.beg_pos; | 3063 int pos = location.beg_pos; |
3288 ExpressionT error = this->NewThrowReferenceError(message, pos); | 3064 ExpressionT error = this->NewThrowReferenceError(message, pos); |
3289 return factory()->NewProperty(expression, error, pos); | 3065 return factory()->NewProperty(expression, error, pos); |
3290 } else { | 3066 } else { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3369 has_seen_constructor_ = true; | 3145 has_seen_constructor_ = true; |
3370 return; | 3146 return; |
3371 } | 3147 } |
3372 } | 3148 } |
3373 | 3149 |
3374 | 3150 |
3375 } // namespace internal | 3151 } // namespace internal |
3376 } // namespace v8 | 3152 } // namespace v8 |
3377 | 3153 |
3378 #endif // V8_PARSING_PARSER_BASE_H | 3154 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |