| 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 |