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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2197 bool* ok) { | 2143 bool* ok) { |
2198 DCHECK(prec >= 4); | 2144 DCHECK(prec >= 4); |
2199 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2145 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2200 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2146 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2201 // prec1 >= 4 | 2147 // prec1 >= 4 |
2202 while (Precedence(peek(), accept_IN) == prec1) { | 2148 while (Precedence(peek(), accept_IN) == prec1) { |
2203 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2149 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2204 BindingPatternUnexpectedToken(classifier); | 2150 BindingPatternUnexpectedToken(classifier); |
2205 ArrowFormalParametersUnexpectedToken(classifier); | 2151 ArrowFormalParametersUnexpectedToken(classifier); |
2206 Token::Value op = Next(); | 2152 Token::Value op = Next(); |
2207 Scanner::Location op_location = scanner()->location(); | |
2208 int pos = position(); | 2153 int pos = position(); |
2209 ExpressionT y = | 2154 ExpressionT y = |
2210 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); | 2155 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
2211 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2156 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2212 | 2157 |
2213 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2158 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2214 factory())) { | 2159 factory())) { |
2215 continue; | 2160 continue; |
2216 } | 2161 } |
2217 | 2162 |
2218 // For now we distinguish between comparisons and other binary | 2163 // For now we distinguish between comparisons and other binary |
2219 // operations. (We could combine the two and get rid of this | 2164 // operations. (We could combine the two and get rid of this |
2220 // code and AST node eventually.) | 2165 // code and AST node eventually.) |
2221 if (Token::IsCompareOp(op)) { | 2166 if (Token::IsCompareOp(op)) { |
2222 // We have a comparison. | 2167 // We have a comparison. |
2223 Token::Value cmp = op; | 2168 Token::Value cmp = op; |
2224 switch (op) { | 2169 switch (op) { |
2225 case Token::NE: cmp = Token::EQ; break; | 2170 case Token::NE: cmp = Token::EQ; break; |
2226 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 2171 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
2227 default: break; | 2172 default: break; |
2228 } | 2173 } |
2229 if (cmp == Token::EQ && is_strong(language_mode())) { | 2174 if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) { |
2230 ReportMessageAt(op_location, MessageTemplate::kStrongEqual); | |
2231 *ok = false; | |
2232 return this->EmptyExpression(); | |
2233 } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) { | |
2234 x = Traits::RewriteInstanceof(x, y, pos); | 2175 x = Traits::RewriteInstanceof(x, y, pos); |
2235 } else { | 2176 } else { |
2236 x = factory()->NewCompareOperation(cmp, x, y, pos); | 2177 x = factory()->NewCompareOperation(cmp, x, y, pos); |
2237 if (cmp != op) { | 2178 if (cmp != op) { |
2238 // The comparison was negated - add a NOT. | 2179 // The comparison was negated - add a NOT. |
2239 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | 2180 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
2240 } | 2181 } |
2241 } | 2182 } |
2242 } else { | 2183 } else { |
2243 // We have a "normal" binary operation. | 2184 // We have a "normal" binary operation. |
(...skipping 25 matching lines...) Expand all Loading... |
2269 if (Token::IsUnaryOp(op)) { | 2210 if (Token::IsUnaryOp(op)) { |
2270 BindingPatternUnexpectedToken(classifier); | 2211 BindingPatternUnexpectedToken(classifier); |
2271 ArrowFormalParametersUnexpectedToken(classifier); | 2212 ArrowFormalParametersUnexpectedToken(classifier); |
2272 | 2213 |
2273 op = Next(); | 2214 op = Next(); |
2274 int pos = position(); | 2215 int pos = position(); |
2275 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2216 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2276 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2217 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2277 | 2218 |
2278 if (op == Token::DELETE && is_strict(language_mode())) { | 2219 if (op == Token::DELETE && is_strict(language_mode())) { |
2279 if (is_strong(language_mode())) { | 2220 if (this->IsIdentifier(expression)) { |
2280 ReportMessage(MessageTemplate::kStrongDelete); | |
2281 *ok = false; | |
2282 return this->EmptyExpression(); | |
2283 } else if (this->IsIdentifier(expression)) { | |
2284 // "delete identifier" is a syntax error in strict mode. | 2221 // "delete identifier" is a syntax error in strict mode. |
2285 ReportMessage(MessageTemplate::kStrictDelete); | 2222 ReportMessage(MessageTemplate::kStrictDelete); |
2286 *ok = false; | 2223 *ok = false; |
2287 return this->EmptyExpression(); | 2224 return this->EmptyExpression(); |
2288 } | 2225 } |
2289 } | 2226 } |
2290 | 2227 |
2291 // Allow Traits do rewrite the expression. | 2228 // Allow Traits do rewrite the expression. |
2292 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2229 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2293 } else if (Token::IsCountOp(op)) { | 2230 } else if (Token::IsCountOp(op)) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2368 result = factory()->NewProperty(result, index, pos); | 2305 result = factory()->NewProperty(result, index, pos); |
2369 Expect(Token::RBRACK, CHECK_OK); | 2306 Expect(Token::RBRACK, CHECK_OK); |
2370 break; | 2307 break; |
2371 } | 2308 } |
2372 | 2309 |
2373 case Token::LPAREN: { | 2310 case Token::LPAREN: { |
2374 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2311 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2375 BindingPatternUnexpectedToken(classifier); | 2312 BindingPatternUnexpectedToken(classifier); |
2376 ArrowFormalParametersUnexpectedToken(classifier); | 2313 ArrowFormalParametersUnexpectedToken(classifier); |
2377 | 2314 |
2378 if (is_strong(language_mode()) && this->IsIdentifier(result) && | |
2379 this->IsEval(this->AsIdentifier(result))) { | |
2380 ReportMessage(MessageTemplate::kStrongDirectEval); | |
2381 *ok = false; | |
2382 return this->EmptyExpression(); | |
2383 } | |
2384 int pos; | 2315 int pos; |
2385 if (scanner()->current_token() == Token::IDENTIFIER || | 2316 if (scanner()->current_token() == Token::IDENTIFIER || |
2386 scanner()->current_token() == Token::SUPER) { | 2317 scanner()->current_token() == Token::SUPER) { |
2387 // For call of an identifier we want to report position of | 2318 // For call of an identifier we want to report position of |
2388 // the identifier as position of the call in the stack trace. | 2319 // the identifier as position of the call in the stack trace. |
2389 pos = position(); | 2320 pos = position(); |
2390 } else { | 2321 } else { |
2391 // For other kinds of calls we record position of the parenthesis as | 2322 // For other kinds of calls we record position of the parenthesis as |
2392 // position of the call. Note that this is extremely important for | 2323 // position of the call. Note that this is extremely important for |
2393 // expressions of the form function(){...}() for which call position | 2324 // expressions of the form function(){...}() for which call position |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2591 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2522 result = ParsePrimaryExpression(classifier, CHECK_OK); |
2592 } | 2523 } |
2593 | 2524 |
2594 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2525 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
2595 return result; | 2526 return result; |
2596 } | 2527 } |
2597 | 2528 |
2598 | 2529 |
2599 template <class Traits> | 2530 template <class Traits> |
2600 typename ParserBase<Traits>::ExpressionT | 2531 typename ParserBase<Traits>::ExpressionT |
2601 ParserBase<Traits>::ParseStrongInitializationExpression( | |
2602 ExpressionClassifier* classifier, bool* ok) { | |
2603 // InitializationExpression :: (strong mode) | |
2604 // 'this' '.' IdentifierName '=' AssignmentExpression | |
2605 // 'this' '[' Expression ']' '=' AssignmentExpression | |
2606 | |
2607 FuncNameInferrer::State fni_state(fni_); | |
2608 | |
2609 Consume(Token::THIS); | |
2610 int pos = position(); | |
2611 function_state_->set_this_location(scanner()->location()); | |
2612 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
2613 | |
2614 ExpressionT left = this->EmptyExpression(); | |
2615 switch (peek()) { | |
2616 case Token::LBRACK: { | |
2617 Consume(Token::LBRACK); | |
2618 int pos = position(); | |
2619 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | |
2620 Traits::RewriteNonPattern(classifier, CHECK_OK); | |
2621 left = factory()->NewProperty(this_expr, index, pos); | |
2622 if (fni_ != NULL) { | |
2623 this->PushPropertyName(fni_, index); | |
2624 } | |
2625 Expect(Token::RBRACK, CHECK_OK); | |
2626 break; | |
2627 } | |
2628 case Token::PERIOD: { | |
2629 Consume(Token::PERIOD); | |
2630 int pos = position(); | |
2631 IdentifierT name = ParseIdentifierName(CHECK_OK); | |
2632 left = factory()->NewProperty( | |
2633 this_expr, factory()->NewStringLiteral(name, pos), pos); | |
2634 if (fni_ != NULL) { | |
2635 this->PushLiteralName(fni_, name); | |
2636 } | |
2637 break; | |
2638 } | |
2639 default: | |
2640 ReportMessage(MessageTemplate::kStrongConstructorThis); | |
2641 *ok = false; | |
2642 return this->EmptyExpression(); | |
2643 } | |
2644 | |
2645 if (peek() != Token::ASSIGN) { | |
2646 ReportMessageAt(function_state_->this_location(), | |
2647 MessageTemplate::kStrongConstructorThis); | |
2648 *ok = false; | |
2649 return this->EmptyExpression(); | |
2650 } | |
2651 Consume(Token::ASSIGN); | |
2652 left = this->MarkExpressionAsAssigned(left); | |
2653 | |
2654 ExpressionT right = | |
2655 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | |
2656 Traits::RewriteNonPattern(classifier, CHECK_OK); | |
2657 this->CheckAssigningFunctionLiteralToProperty(left, right); | |
2658 function_state_->AddProperty(); | |
2659 if (fni_ != NULL) { | |
2660 // Check if the right hand side is a call to avoid inferring a | |
2661 // name if we're dealing with "this.a = function(){...}();"-like | |
2662 // expression. | |
2663 if (!right->IsCall() && !right->IsCallNew()) { | |
2664 fni_->Infer(); | |
2665 } else { | |
2666 fni_->RemoveLastFunction(); | |
2667 } | |
2668 } | |
2669 | |
2670 if (function_state_->return_location().IsValid()) { | |
2671 ReportMessageAt(function_state_->return_location(), | |
2672 MessageTemplate::kStrongConstructorReturnMisplaced); | |
2673 *ok = false; | |
2674 return this->EmptyExpression(); | |
2675 } | |
2676 | |
2677 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | |
2678 } | |
2679 | |
2680 | |
2681 template <class Traits> | |
2682 typename ParserBase<Traits>::ExpressionT | |
2683 ParserBase<Traits>::ParseStrongSuperCallExpression( | |
2684 ExpressionClassifier* classifier, bool* ok) { | |
2685 // SuperCallExpression :: (strong mode) | |
2686 // 'super' '(' ExpressionList ')' | |
2687 BindingPatternUnexpectedToken(classifier); | |
2688 | |
2689 Consume(Token::SUPER); | |
2690 int pos = position(); | |
2691 Scanner::Location super_loc = scanner()->location(); | |
2692 ExpressionT expr = this->SuperCallReference(scope_, factory(), pos); | |
2693 | |
2694 if (peek() != Token::LPAREN) { | |
2695 ReportMessage(MessageTemplate::kStrongConstructorSuper); | |
2696 *ok = false; | |
2697 return this->EmptyExpression(); | |
2698 } | |
2699 | |
2700 Scanner::Location spread_pos; | |
2701 typename Traits::Type::ExpressionList args = | |
2702 ParseArguments(&spread_pos, classifier, CHECK_OK); | |
2703 | |
2704 // TODO(rossberg): This doesn't work with arrow functions yet. | |
2705 if (!IsSubclassConstructor(function_state_->kind())) { | |
2706 ReportMessage(MessageTemplate::kUnexpectedSuper); | |
2707 *ok = false; | |
2708 return this->EmptyExpression(); | |
2709 } else if (function_state_->super_location().IsValid()) { | |
2710 ReportMessageAt(scanner()->location(), | |
2711 MessageTemplate::kStrongSuperCallDuplicate); | |
2712 *ok = false; | |
2713 return this->EmptyExpression(); | |
2714 } else if (function_state_->this_location().IsValid()) { | |
2715 ReportMessageAt(scanner()->location(), | |
2716 MessageTemplate::kStrongSuperCallMisplaced); | |
2717 *ok = false; | |
2718 return this->EmptyExpression(); | |
2719 } else if (function_state_->return_location().IsValid()) { | |
2720 ReportMessageAt(function_state_->return_location(), | |
2721 MessageTemplate::kStrongConstructorReturnMisplaced); | |
2722 *ok = false; | |
2723 return this->EmptyExpression(); | |
2724 } | |
2725 | |
2726 function_state_->set_super_location(super_loc); | |
2727 if (spread_pos.IsValid()) { | |
2728 args = Traits::PrepareSpreadArguments(args); | |
2729 expr = Traits::SpreadCall(expr, args, pos); | |
2730 } else { | |
2731 expr = factory()->NewCall(expr, args, pos); | |
2732 } | |
2733 | |
2734 // Explicit calls to the super constructor using super() perform an implicit | |
2735 // binding assignment to the 'this' variable. | |
2736 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
2737 return factory()->NewAssignment(Token::INIT, this_expr, expr, pos); | |
2738 } | |
2739 | |
2740 | |
2741 template <class Traits> | |
2742 typename ParserBase<Traits>::ExpressionT | |
2743 ParserBase<Traits>::ParseSuperExpression(bool is_new, | 2532 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
2744 ExpressionClassifier* classifier, | 2533 ExpressionClassifier* classifier, |
2745 bool* ok) { | 2534 bool* ok) { |
2746 Expect(Token::SUPER, CHECK_OK); | 2535 Expect(Token::SUPER, CHECK_OK); |
2747 int pos = position(); | 2536 int pos = position(); |
2748 | 2537 |
2749 Scope* scope = scope_->ReceiverScope(); | 2538 Scope* scope = scope_->ReceiverScope(); |
2750 FunctionKind kind = scope->function_kind(); | 2539 FunctionKind kind = scope->function_kind(); |
2751 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 2540 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
2752 IsClassConstructor(kind)) { | 2541 IsClassConstructor(kind)) { |
2753 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 2542 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
2754 scope->RecordSuperPropertyUsage(); | 2543 scope->RecordSuperPropertyUsage(); |
2755 return this->SuperPropertyReference(scope_, factory(), pos); | 2544 return this->SuperPropertyReference(scope_, factory(), pos); |
2756 } | 2545 } |
2757 // new super() is never allowed. | 2546 // new super() is never allowed. |
2758 // super() is only allowed in derived constructor | 2547 // super() is only allowed in derived constructor |
2759 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 2548 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
2760 if (is_strong(language_mode())) { | |
2761 // Super calls in strong mode are parsed separately. | |
2762 ReportMessageAt(scanner()->location(), | |
2763 MessageTemplate::kStrongConstructorSuper); | |
2764 *ok = false; | |
2765 return this->EmptyExpression(); | |
2766 } | |
2767 // TODO(rossberg): This might not be the correct FunctionState for the | 2549 // TODO(rossberg): This might not be the correct FunctionState for the |
2768 // method here. | 2550 // method here. |
2769 function_state_->set_super_location(scanner()->location()); | 2551 function_state_->set_super_location(scanner()->location()); |
2770 return this->SuperCallReference(scope_, factory(), pos); | 2552 return this->SuperCallReference(scope_, factory(), pos); |
2771 } | 2553 } |
2772 } | 2554 } |
2773 | 2555 |
2774 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); | 2556 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); |
2775 *ok = false; | 2557 *ok = false; |
2776 return this->EmptyExpression(); | 2558 return this->EmptyExpression(); |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, | 3039 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, |
3258 int end_pos, MessageTemplate::Template message, ParseErrorType type) { | 3040 int end_pos, MessageTemplate::Template message, ParseErrorType type) { |
3259 Scanner::Location location(beg_pos, end_pos); | 3041 Scanner::Location location(beg_pos, end_pos); |
3260 if (this->IsIdentifier(expression)) { | 3042 if (this->IsIdentifier(expression)) { |
3261 if (is_strict(language_mode()) && | 3043 if (is_strict(language_mode()) && |
3262 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3044 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3263 classifier->RecordExpressionError( | 3045 classifier->RecordExpressionError( |
3264 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); | 3046 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); |
3265 return expression; | 3047 return expression; |
3266 } | 3048 } |
3267 if (is_strong(language_mode()) && | |
3268 this->IsUndefined(this->AsIdentifier(expression))) { | |
3269 classifier->RecordExpressionError( | |
3270 location, MessageTemplate::kStrongUndefined, kSyntaxError); | |
3271 return expression; | |
3272 } | |
3273 } | 3049 } |
3274 if (expression->IsValidReferenceExpression()) { | 3050 if (expression->IsValidReferenceExpression()) { |
3275 return expression; | 3051 return expression; |
3276 } else if (expression->IsCall()) { | 3052 } else if (expression->IsCall()) { |
3277 // If it is a call, make it a runtime error for legacy web compatibility. | 3053 // If it is a call, make it a runtime error for legacy web compatibility. |
3278 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3054 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3279 int pos = location.beg_pos; | 3055 int pos = location.beg_pos; |
3280 ExpressionT error = this->NewThrowReferenceError(message, pos); | 3056 ExpressionT error = this->NewThrowReferenceError(message, pos); |
3281 return factory()->NewProperty(expression, error, pos); | 3057 return factory()->NewProperty(expression, error, pos); |
3282 } else { | 3058 } else { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3361 has_seen_constructor_ = true; | 3137 has_seen_constructor_ = true; |
3362 return; | 3138 return; |
3363 } | 3139 } |
3364 } | 3140 } |
3365 | 3141 |
3366 | 3142 |
3367 } // namespace internal | 3143 } // namespace internal |
3368 } // namespace v8 | 3144 } // namespace v8 |
3369 | 3145 |
3370 #endif // V8_PARSING_PARSER_BASE_H | 3146 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |