| 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_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
| 6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| 11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
| 12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
| 13 #include "src/messages.h" |
| 13 #include "src/scanner.h" | 14 #include "src/scanner.h" |
| 14 #include "src/scopes.h" | 15 #include "src/scopes.h" |
| 15 #include "src/token.h" | 16 #include "src/token.h" |
| 16 | 17 |
| 17 namespace v8 { | 18 namespace v8 { |
| 18 namespace internal { | 19 namespace internal { |
| 19 | 20 |
| 20 | 21 |
| 21 // Common base class shared between parser and pre-parser. Traits encapsulate | 22 // Common base class shared between parser and pre-parser. Traits encapsulate |
| 22 // the differences between Parser and PreParser: | 23 // the differences between Parser and PreParser: |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 439 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 439 ReportUnexpectedToken(scanner()->current_token()); | 440 ReportUnexpectedToken(scanner()->current_token()); |
| 440 *ok = false; | 441 *ok = false; |
| 441 } | 442 } |
| 442 } | 443 } |
| 443 | 444 |
| 444 bool CheckInOrOf( | 445 bool CheckInOrOf( |
| 445 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { | 446 bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { |
| 446 if (Check(Token::IN)) { | 447 if (Check(Token::IN)) { |
| 447 if (is_strong(language_mode())) { | 448 if (is_strong(language_mode())) { |
| 448 ReportMessageAt(scanner()->location(), "strong_for_in"); | 449 ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn); |
| 449 *ok = false; | 450 *ok = false; |
| 450 } else { | 451 } else { |
| 451 *visit_mode = ForEachStatement::ENUMERATE; | 452 *visit_mode = ForEachStatement::ENUMERATE; |
| 452 } | 453 } |
| 453 return true; | 454 return true; |
| 454 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { | 455 } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { |
| 455 *visit_mode = ForEachStatement::ITERATE; | 456 *visit_mode = ForEachStatement::ITERATE; |
| 456 return true; | 457 return true; |
| 457 } | 458 } |
| 458 return false; | 459 return false; |
| 459 } | 460 } |
| 460 | 461 |
| 461 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 462 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 462 // If so, reports an error. Only called for strict mode and template strings. | 463 // If so, reports an error. Only called for strict mode and template strings. |
| 463 void CheckOctalLiteral(int beg_pos, int end_pos, const char* error, | 464 void CheckOctalLiteral(int beg_pos, int end_pos, |
| 464 bool* ok) { | 465 MessageTemplate::Template message, bool* ok) { |
| 465 Scanner::Location octal = scanner()->octal_position(); | 466 Scanner::Location octal = scanner()->octal_position(); |
| 466 if (octal.IsValid() && beg_pos <= octal.beg_pos && | 467 if (octal.IsValid() && beg_pos <= octal.beg_pos && |
| 467 octal.end_pos <= end_pos) { | 468 octal.end_pos <= end_pos) { |
| 468 ReportMessageAt(octal, error); | 469 ReportMessageAt(octal, message); |
| 469 scanner()->clear_octal_position(); | 470 scanner()->clear_octal_position(); |
| 470 *ok = false; | 471 *ok = false; |
| 471 } | 472 } |
| 472 } | 473 } |
| 473 | 474 |
| 474 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 475 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 475 CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok); | 476 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral, |
| 477 ok); |
| 476 } | 478 } |
| 477 | 479 |
| 478 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 480 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 479 CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", ok); | 481 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral, |
| 482 ok); |
| 480 } | 483 } |
| 481 | 484 |
| 482 // Checking the name of a function literal. This has to be done after parsing | 485 // Checking the name of a function literal. This has to be done after parsing |
| 483 // the function, since the function can declare itself strict. | 486 // the function, since the function can declare itself strict. |
| 484 void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, | 487 void CheckFunctionName(LanguageMode language_mode, FunctionKind kind, |
| 485 IdentifierT function_name, | 488 IdentifierT function_name, |
| 486 bool function_name_is_strict_reserved, | 489 bool function_name_is_strict_reserved, |
| 487 const Scanner::Location& function_name_loc, | 490 const Scanner::Location& function_name_loc, |
| 488 bool* ok) { | 491 bool* ok) { |
| 489 // Property names are never checked. | 492 // Property names are never checked. |
| 490 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return; | 493 if (IsConciseMethod(kind) || IsAccessorFunction(kind)) return; |
| 491 // The function name needs to be checked in strict mode. | 494 // The function name needs to be checked in strict mode. |
| 492 if (is_sloppy(language_mode)) return; | 495 if (is_sloppy(language_mode)) return; |
| 493 | 496 |
| 494 if (this->IsEvalOrArguments(function_name)) { | 497 if (this->IsEvalOrArguments(function_name)) { |
| 495 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments"); | 498 Traits::ReportMessageAt(function_name_loc, |
| 499 MessageTemplate::kStrictEvalArguments); |
| 496 *ok = false; | 500 *ok = false; |
| 497 return; | 501 return; |
| 498 } | 502 } |
| 499 if (function_name_is_strict_reserved) { | 503 if (function_name_is_strict_reserved) { |
| 500 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved"); | 504 Traits::ReportMessageAt(function_name_loc, |
| 505 MessageTemplate::kUnexpectedStrictReserved); |
| 501 *ok = false; | 506 *ok = false; |
| 502 return; | 507 return; |
| 503 } | 508 } |
| 504 if (is_strong(language_mode) && this->IsUndefined(function_name)) { | 509 if (is_strong(language_mode) && this->IsUndefined(function_name)) { |
| 505 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 510 Traits::ReportMessageAt(function_name_loc, |
| 511 MessageTemplate::kStrongUndefined); |
| 506 *ok = false; | 512 *ok = false; |
| 507 return; | 513 return; |
| 508 } | 514 } |
| 509 } | 515 } |
| 510 | 516 |
| 511 // Determine precedence of given token. | 517 // Determine precedence of given token. |
| 512 static int Precedence(Token::Value token, bool accept_IN) { | 518 static int Precedence(Token::Value token, bool accept_IN) { |
| 513 if (token == Token::IN && !accept_IN) | 519 if (token == Token::IN && !accept_IN) |
| 514 return 0; // 0 precedence will terminate binary expression parsing | 520 return 0; // 0 precedence will terminate binary expression parsing |
| 515 return Token::Precedence(token); | 521 return Token::Precedence(token); |
| 516 } | 522 } |
| 517 | 523 |
| 518 typename Traits::Type::Factory* factory() { | 524 typename Traits::Type::Factory* factory() { |
| 519 return function_state_->factory(); | 525 return function_state_->factory(); |
| 520 } | 526 } |
| 521 | 527 |
| 522 LanguageMode language_mode() { return scope_->language_mode(); } | 528 LanguageMode language_mode() { return scope_->language_mode(); } |
| 523 bool is_generator() const { return function_state_->is_generator(); } | 529 bool is_generator() const { return function_state_->is_generator(); } |
| 524 | 530 |
| 525 // Report syntax errors. | 531 // Report syntax errors. |
| 526 void ReportMessage(const char* message, const char* arg = NULL, | 532 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
| 527 ParseErrorType error_type = kSyntaxError) { | 533 ParseErrorType error_type = kSyntaxError) { |
| 528 Scanner::Location source_location = scanner()->location(); | 534 Scanner::Location source_location = scanner()->location(); |
| 529 Traits::ReportMessageAt(source_location, message, arg, error_type); | 535 Traits::ReportMessageAt(source_location, message, arg, error_type); |
| 530 } | 536 } |
| 531 | 537 |
| 532 void ReportMessageAt(Scanner::Location location, const char* message, | 538 void ReportMessageAt(Scanner::Location location, |
| 539 MessageTemplate::Template message, |
| 533 ParseErrorType error_type = kSyntaxError) { | 540 ParseErrorType error_type = kSyntaxError) { |
| 534 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 541 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
| 535 error_type); | 542 error_type); |
| 536 } | 543 } |
| 537 | 544 |
| 538 void ReportUnexpectedToken(Token::Value token); | 545 void ReportUnexpectedToken(Token::Value token); |
| 539 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); | 546 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); |
| 540 | 547 |
| 541 class ExpressionClassifier { | 548 class ExpressionClassifier { |
| 542 public: | 549 public: |
| 543 struct Error { | 550 struct Error { |
| 544 Error() | 551 Error() |
| 545 : location(Scanner::Location::invalid()), | 552 : location(Scanner::Location::invalid()), |
| 546 message(nullptr), | 553 message(MessageTemplate::kNone), |
| 547 arg(nullptr) {} | 554 arg(nullptr) {} |
| 548 | 555 |
| 549 Scanner::Location location; | 556 Scanner::Location location; |
| 550 const char* message; | 557 MessageTemplate::Template message; |
| 551 const char* arg; | 558 const char* arg; |
| 552 | 559 |
| 553 bool HasError() const { return location.IsValid(); } | 560 bool HasError() const { return location.IsValid(); } |
| 554 }; | 561 }; |
| 555 | 562 |
| 556 ExpressionClassifier() {} | 563 ExpressionClassifier() {} |
| 557 | 564 |
| 558 bool is_valid_expression() const { return !expression_error_.HasError(); } | 565 bool is_valid_expression() const { return !expression_error_.HasError(); } |
| 559 | 566 |
| 560 bool is_valid_binding_pattern() const { | 567 bool is_valid_binding_pattern() const { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 | 612 |
| 606 const Error& strict_mode_formal_parameter_error() const { | 613 const Error& strict_mode_formal_parameter_error() const { |
| 607 return strict_mode_formal_parameter_error_; | 614 return strict_mode_formal_parameter_error_; |
| 608 } | 615 } |
| 609 | 616 |
| 610 const Error& strong_mode_formal_parameter_error() const { | 617 const Error& strong_mode_formal_parameter_error() const { |
| 611 return strong_mode_formal_parameter_error_; | 618 return strong_mode_formal_parameter_error_; |
| 612 } | 619 } |
| 613 | 620 |
| 614 void RecordExpressionError(const Scanner::Location& loc, | 621 void RecordExpressionError(const Scanner::Location& loc, |
| 615 const char* message, const char* arg = nullptr) { | 622 MessageTemplate::Template message, |
| 623 const char* arg = nullptr) { |
| 616 if (!is_valid_expression()) return; | 624 if (!is_valid_expression()) return; |
| 617 expression_error_.location = loc; | 625 expression_error_.location = loc; |
| 618 expression_error_.message = message; | 626 expression_error_.message = message; |
| 619 expression_error_.arg = arg; | 627 expression_error_.arg = arg; |
| 620 } | 628 } |
| 621 | 629 |
| 622 void RecordBindingPatternError(const Scanner::Location& loc, | 630 void RecordBindingPatternError(const Scanner::Location& loc, |
| 623 const char* message, | 631 MessageTemplate::Template message, |
| 624 const char* arg = nullptr) { | 632 const char* arg = nullptr) { |
| 625 if (!is_valid_binding_pattern()) return; | 633 if (!is_valid_binding_pattern()) return; |
| 626 binding_pattern_error_.location = loc; | 634 binding_pattern_error_.location = loc; |
| 627 binding_pattern_error_.message = message; | 635 binding_pattern_error_.message = message; |
| 628 binding_pattern_error_.arg = arg; | 636 binding_pattern_error_.arg = arg; |
| 629 } | 637 } |
| 630 | 638 |
| 631 void RecordAssignmentPatternError(const Scanner::Location& loc, | 639 void RecordAssignmentPatternError(const Scanner::Location& loc, |
| 632 const char* message, | 640 MessageTemplate::Template message, |
| 633 const char* arg = nullptr) { | 641 const char* arg = nullptr) { |
| 634 if (!is_valid_assignment_pattern()) return; | 642 if (!is_valid_assignment_pattern()) return; |
| 635 assignment_pattern_error_.location = loc; | 643 assignment_pattern_error_.location = loc; |
| 636 assignment_pattern_error_.message = message; | 644 assignment_pattern_error_.message = message; |
| 637 assignment_pattern_error_.arg = arg; | 645 assignment_pattern_error_.arg = arg; |
| 638 } | 646 } |
| 639 | 647 |
| 640 void RecordArrowFormalParametersError(const Scanner::Location& loc, | 648 void RecordArrowFormalParametersError(const Scanner::Location& loc, |
| 641 const char* message, | 649 MessageTemplate::Template message, |
| 642 const char* arg = nullptr) { | 650 const char* arg = nullptr) { |
| 643 if (!is_valid_arrow_formal_parameters()) return; | 651 if (!is_valid_arrow_formal_parameters()) return; |
| 644 arrow_formal_parameters_error_.location = loc; | 652 arrow_formal_parameters_error_.location = loc; |
| 645 arrow_formal_parameters_error_.message = message; | 653 arrow_formal_parameters_error_.message = message; |
| 646 arrow_formal_parameters_error_.arg = arg; | 654 arrow_formal_parameters_error_.arg = arg; |
| 647 } | 655 } |
| 648 | 656 |
| 649 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | 657 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
| 650 if (!is_valid_formal_parameter_list_without_duplicates()) return; | 658 if (!is_valid_formal_parameter_list_without_duplicates()) return; |
| 651 duplicate_formal_parameter_error_.location = loc; | 659 duplicate_formal_parameter_error_.location = loc; |
| 652 duplicate_formal_parameter_error_.message = "strict_param_dupe"; | 660 duplicate_formal_parameter_error_.message = |
| 661 MessageTemplate::kStrictParamDupe; |
| 653 duplicate_formal_parameter_error_.arg = nullptr; | 662 duplicate_formal_parameter_error_.arg = nullptr; |
| 654 } | 663 } |
| 655 | 664 |
| 656 // Record a binding that would be invalid in strict mode. Confusingly this | 665 // Record a binding that would be invalid in strict mode. Confusingly this |
| 657 // is not the same as StrictFormalParameterList, which simply forbids | 666 // is not the same as StrictFormalParameterList, which simply forbids |
| 658 // duplicate bindings. | 667 // duplicate bindings. |
| 659 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, | 668 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
| 660 const char* message, | 669 MessageTemplate::Template message, |
| 661 const char* arg = nullptr) { | 670 const char* arg = nullptr) { |
| 662 if (!is_valid_strict_mode_formal_parameters()) return; | 671 if (!is_valid_strict_mode_formal_parameters()) return; |
| 663 strict_mode_formal_parameter_error_.location = loc; | 672 strict_mode_formal_parameter_error_.location = loc; |
| 664 strict_mode_formal_parameter_error_.message = message; | 673 strict_mode_formal_parameter_error_.message = message; |
| 665 strict_mode_formal_parameter_error_.arg = arg; | 674 strict_mode_formal_parameter_error_.arg = arg; |
| 666 } | 675 } |
| 667 | 676 |
| 668 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, | 677 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
| 669 const char* message, | 678 MessageTemplate::Template message, |
| 670 const char* arg = nullptr) { | 679 const char* arg = nullptr) { |
| 671 if (!is_valid_strong_mode_formal_parameters()) return; | 680 if (!is_valid_strong_mode_formal_parameters()) return; |
| 672 strong_mode_formal_parameter_error_.location = loc; | 681 strong_mode_formal_parameter_error_.location = loc; |
| 673 strong_mode_formal_parameter_error_.message = message; | 682 strong_mode_formal_parameter_error_.message = message; |
| 674 strong_mode_formal_parameter_error_.arg = arg; | 683 strong_mode_formal_parameter_error_.arg = arg; |
| 675 } | 684 } |
| 676 | 685 |
| 677 enum TargetProduction { | 686 enum TargetProduction { |
| 678 ExpressionProduction = 1 << 0, | 687 ExpressionProduction = 1 << 0, |
| 679 BindingPatternProduction = 1 << 1, | 688 BindingPatternProduction = 1 << 1, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 ReportClassifierError(classifier->strong_mode_formal_parameter_error()); | 785 ReportClassifierError(classifier->strong_mode_formal_parameter_error()); |
| 777 *ok = false; | 786 *ok = false; |
| 778 } | 787 } |
| 779 } | 788 } |
| 780 | 789 |
| 781 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, | 790 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier, |
| 782 ExpressionT expr, bool* ok) { | 791 ExpressionT expr, bool* ok) { |
| 783 if (classifier->is_valid_binding_pattern()) { | 792 if (classifier->is_valid_binding_pattern()) { |
| 784 // A simple arrow formal parameter: IDENTIFIER => BODY. | 793 // A simple arrow formal parameter: IDENTIFIER => BODY. |
| 785 if (!this->IsIdentifier(expr)) { | 794 if (!this->IsIdentifier(expr)) { |
| 786 Traits::ReportMessageAt(scanner()->location(), "unexpected_token", | 795 Traits::ReportMessageAt(scanner()->location(), |
| 796 MessageTemplate::kUnexpectedToken, |
| 787 Token::String(scanner()->current_token())); | 797 Token::String(scanner()->current_token())); |
| 788 *ok = false; | 798 *ok = false; |
| 789 } | 799 } |
| 790 } else if (!classifier->is_valid_arrow_formal_parameters()) { | 800 } else if (!classifier->is_valid_arrow_formal_parameters()) { |
| 791 ReportClassifierError(classifier->arrow_formal_parameters_error()); | 801 ReportClassifierError(classifier->arrow_formal_parameters_error()); |
| 792 *ok = false; | 802 *ok = false; |
| 793 } | 803 } |
| 794 } | 804 } |
| 795 | 805 |
| 796 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 806 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
| 797 classifier->RecordBindingPatternError( | 807 classifier->RecordBindingPatternError(scanner()->peek_location(), |
| 798 scanner()->peek_location(), "unexpected_token", Token::String(peek())); | 808 MessageTemplate::kUnexpectedToken, |
| 809 Token::String(peek())); |
| 799 } | 810 } |
| 800 | 811 |
| 801 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { | 812 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { |
| 802 classifier->RecordArrowFormalParametersError( | 813 classifier->RecordArrowFormalParametersError( |
| 803 scanner()->peek_location(), "unexpected_token", Token::String(peek())); | 814 scanner()->peek_location(), MessageTemplate::kUnexpectedToken, |
| 815 Token::String(peek())); |
| 804 } | 816 } |
| 805 | 817 |
| 806 // Recursive descent functions: | 818 // Recursive descent functions: |
| 807 | 819 |
| 808 // Parses an identifier that is valid for the current scope, in particular it | 820 // Parses an identifier that is valid for the current scope, in particular it |
| 809 // fails on strict mode future reserved keywords in a strict scope. If | 821 // fails on strict mode future reserved keywords in a strict scope. If |
| 810 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 822 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 811 // "arguments" as identifier even in strict mode (this is needed in cases like | 823 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 812 // "var foo = eval;"). | 824 // "var foo = eval;"). |
| 813 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 825 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest, | 892 int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest, |
| 881 ExpressionClassifier* classifier, bool* ok); | 893 ExpressionClassifier* classifier, bool* ok); |
| 882 void CheckArityRestrictions( | 894 void CheckArityRestrictions( |
| 883 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 895 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| 884 int formals_start_pos, int formals_end_pos, bool* ok); | 896 int formals_start_pos, int formals_end_pos, bool* ok); |
| 885 | 897 |
| 886 // Checks if the expression is a valid reference expression (e.g., on the | 898 // Checks if the expression is a valid reference expression (e.g., on the |
| 887 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 899 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 888 // we allow calls for web compatibility and rewrite them to a runtime throw. | 900 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 889 ExpressionT CheckAndRewriteReferenceExpression( | 901 ExpressionT CheckAndRewriteReferenceExpression( |
| 890 ExpressionT expression, | 902 ExpressionT expression, Scanner::Location location, |
| 891 Scanner::Location location, const char* message, bool* ok); | 903 MessageTemplate::Template message, bool* ok); |
| 892 | 904 |
| 893 // Used to validate property names in object literals and class literals | 905 // Used to validate property names in object literals and class literals |
| 894 enum PropertyKind { | 906 enum PropertyKind { |
| 895 kAccessorProperty, | 907 kAccessorProperty, |
| 896 kValueProperty, | 908 kValueProperty, |
| 897 kMethodProperty | 909 kMethodProperty |
| 898 }; | 910 }; |
| 899 | 911 |
| 900 class ObjectLiteralCheckerBase { | 912 class ObjectLiteralCheckerBase { |
| 901 public: | 913 public: |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 PreParserFactory* factory) { | 1608 PreParserFactory* factory) { |
| 1597 return false; | 1609 return false; |
| 1598 } | 1610 } |
| 1599 | 1611 |
| 1600 PreParserExpression BuildUnaryExpression(PreParserExpression expression, | 1612 PreParserExpression BuildUnaryExpression(PreParserExpression expression, |
| 1601 Token::Value op, int pos, | 1613 Token::Value op, int pos, |
| 1602 PreParserFactory* factory) { | 1614 PreParserFactory* factory) { |
| 1603 return PreParserExpression::Default(); | 1615 return PreParserExpression::Default(); |
| 1604 } | 1616 } |
| 1605 | 1617 |
| 1606 PreParserExpression NewThrowReferenceError(const char* type, int pos) { | 1618 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message, |
| 1619 int pos) { |
| 1607 return PreParserExpression::Default(); | 1620 return PreParserExpression::Default(); |
| 1608 } | 1621 } |
| 1609 PreParserExpression NewThrowSyntaxError( | 1622 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message, |
| 1610 const char* type, Handle<Object> arg, int pos) { | 1623 Handle<Object> arg, int pos) { |
| 1611 return PreParserExpression::Default(); | 1624 return PreParserExpression::Default(); |
| 1612 } | 1625 } |
| 1613 PreParserExpression NewThrowTypeError( | 1626 PreParserExpression NewThrowTypeError(MessageTemplate::Template message, |
| 1614 const char* type, Handle<Object> arg, int pos) { | 1627 Handle<Object> arg, int pos) { |
| 1615 return PreParserExpression::Default(); | 1628 return PreParserExpression::Default(); |
| 1616 } | 1629 } |
| 1617 | 1630 |
| 1618 // Reporting errors. | 1631 // Reporting errors. |
| 1619 void ReportMessageAt(Scanner::Location location, const char* message, | 1632 void ReportMessageAt(Scanner::Location location, |
| 1633 MessageTemplate::Template message, |
| 1620 const char* arg = NULL, | 1634 const char* arg = NULL, |
| 1621 ParseErrorType error_type = kSyntaxError); | 1635 ParseErrorType error_type = kSyntaxError); |
| 1622 void ReportMessageAt(int start_pos, int end_pos, const char* message, | 1636 void ReportMessageAt(int start_pos, int end_pos, |
| 1637 MessageTemplate::Template message, |
| 1623 const char* arg = NULL, | 1638 const char* arg = NULL, |
| 1624 ParseErrorType error_type = kSyntaxError); | 1639 ParseErrorType error_type = kSyntaxError); |
| 1625 | 1640 |
| 1626 // "null" return type creators. | 1641 // "null" return type creators. |
| 1627 static PreParserIdentifier EmptyIdentifier() { | 1642 static PreParserIdentifier EmptyIdentifier() { |
| 1628 return PreParserIdentifier::Default(); | 1643 return PreParserIdentifier::Default(); |
| 1629 } | 1644 } |
| 1630 static PreParserIdentifier EmptyIdentifierString() { | 1645 static PreParserIdentifier EmptyIdentifierString() { |
| 1631 return PreParserIdentifier::Default(); | 1646 return PreParserIdentifier::Default(); |
| 1632 } | 1647 } |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2016 } | 2031 } |
| 2017 | 2032 |
| 2018 | 2033 |
| 2019 template<class Traits> | 2034 template<class Traits> |
| 2020 void ParserBase<Traits>::ReportUnexpectedTokenAt( | 2035 void ParserBase<Traits>::ReportUnexpectedTokenAt( |
| 2021 Scanner::Location source_location, Token::Value token) { | 2036 Scanner::Location source_location, Token::Value token) { |
| 2022 | 2037 |
| 2023 // Four of the tokens are treated specially | 2038 // Four of the tokens are treated specially |
| 2024 switch (token) { | 2039 switch (token) { |
| 2025 case Token::EOS: | 2040 case Token::EOS: |
| 2026 return ReportMessageAt(source_location, "unexpected_eos"); | 2041 return ReportMessageAt(source_location, MessageTemplate::kUnexpectedEOS); |
| 2027 case Token::SMI: | 2042 case Token::SMI: |
| 2028 case Token::NUMBER: | 2043 case Token::NUMBER: |
| 2029 return ReportMessageAt(source_location, "unexpected_token_number"); | 2044 return ReportMessageAt(source_location, |
| 2045 MessageTemplate::kUnexpectedTokenNumber); |
| 2030 case Token::STRING: | 2046 case Token::STRING: |
| 2031 return ReportMessageAt(source_location, "unexpected_token_string"); | 2047 return ReportMessageAt(source_location, |
| 2048 MessageTemplate::kUnexpectedTokenString); |
| 2032 case Token::IDENTIFIER: | 2049 case Token::IDENTIFIER: |
| 2033 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 2050 return ReportMessageAt(source_location, |
| 2051 MessageTemplate::kUnexpectedTokenIdentifier); |
| 2034 case Token::FUTURE_RESERVED_WORD: | 2052 case Token::FUTURE_RESERVED_WORD: |
| 2035 return ReportMessageAt(source_location, "unexpected_reserved"); | 2053 return ReportMessageAt(source_location, |
| 2054 MessageTemplate::kUnexpectedReserved); |
| 2036 case Token::LET: | 2055 case Token::LET: |
| 2037 case Token::STATIC: | 2056 case Token::STATIC: |
| 2038 case Token::YIELD: | 2057 case Token::YIELD: |
| 2039 case Token::FUTURE_STRICT_RESERVED_WORD: | 2058 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 2040 return ReportMessageAt(source_location, | 2059 return ReportMessageAt(source_location, |
| 2041 is_strict(language_mode()) | 2060 is_strict(language_mode()) |
| 2042 ? "unexpected_strict_reserved" | 2061 ? MessageTemplate::kUnexpectedStrictReserved |
| 2043 : "unexpected_token_identifier"); | 2062 : MessageTemplate::kUnexpectedTokenIdentifier); |
| 2044 case Token::TEMPLATE_SPAN: | 2063 case Token::TEMPLATE_SPAN: |
| 2045 case Token::TEMPLATE_TAIL: | 2064 case Token::TEMPLATE_TAIL: |
| 2046 return Traits::ReportMessageAt(source_location, | 2065 return Traits::ReportMessageAt( |
| 2047 "unexpected_template_string"); | 2066 source_location, MessageTemplate::kUnexpectedTemplateString); |
| 2048 default: | 2067 default: |
| 2049 const char* name = Token::String(token); | 2068 const char* name = Token::String(token); |
| 2050 DCHECK(name != NULL); | 2069 DCHECK(name != NULL); |
| 2051 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 2070 Traits::ReportMessageAt(source_location, |
| 2071 MessageTemplate::kUnexpectedToken, name); |
| 2052 } | 2072 } |
| 2053 } | 2073 } |
| 2054 | 2074 |
| 2055 | 2075 |
| 2056 template <class Traits> | 2076 template <class Traits> |
| 2057 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 2077 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
| 2058 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 2078 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
| 2059 ExpressionClassifier classifier; | 2079 ExpressionClassifier classifier; |
| 2060 auto result = ParseAndClassifyIdentifier(&classifier, ok); | 2080 auto result = ParseAndClassifyIdentifier(&classifier, ok); |
| 2061 if (!*ok) return Traits::EmptyIdentifier(); | 2081 if (!*ok) return Traits::EmptyIdentifier(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2081 Token::Value next = Next(); | 2101 Token::Value next = Next(); |
| 2082 if (next == Token::IDENTIFIER) { | 2102 if (next == Token::IDENTIFIER) { |
| 2083 IdentifierT name = this->GetSymbol(scanner()); | 2103 IdentifierT name = this->GetSymbol(scanner()); |
| 2084 // When this function is used to read a formal parameter, we don't always | 2104 // When this function is used to read a formal parameter, we don't always |
| 2085 // know whether the function is going to be strict or sloppy. Indeed for | 2105 // know whether the function is going to be strict or sloppy. Indeed for |
| 2086 // arrow functions we don't always know that the identifier we are reading | 2106 // arrow functions we don't always know that the identifier we are reading |
| 2087 // is actually a formal parameter. Therefore besides the errors that we | 2107 // is actually a formal parameter. Therefore besides the errors that we |
| 2088 // must detect because we know we're in strict mode, we also record any | 2108 // must detect because we know we're in strict mode, we also record any |
| 2089 // error that we might make in the future once we know the language mode. | 2109 // error that we might make in the future once we know the language mode. |
| 2090 if (this->IsEval(name)) { | 2110 if (this->IsEval(name)) { |
| 2091 classifier->RecordStrictModeFormalParameterError(scanner()->location(), | 2111 classifier->RecordStrictModeFormalParameterError( |
| 2092 "strict_eval_arguments"); | 2112 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 2093 if (is_strict(language_mode())) { | 2113 if (is_strict(language_mode())) { |
| 2094 classifier->RecordBindingPatternError(scanner()->location(), | 2114 classifier->RecordBindingPatternError( |
| 2095 "strict_eval_arguments"); | 2115 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 2096 } | 2116 } |
| 2097 } | 2117 } |
| 2098 if (this->IsArguments(name)) { | 2118 if (this->IsArguments(name)) { |
| 2099 scope_->RecordArgumentsUsage(); | 2119 scope_->RecordArgumentsUsage(); |
| 2100 classifier->RecordStrictModeFormalParameterError(scanner()->location(), | 2120 classifier->RecordStrictModeFormalParameterError( |
| 2101 "strict_eval_arguments"); | 2121 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 2102 if (is_strict(language_mode())) { | 2122 if (is_strict(language_mode())) { |
| 2103 classifier->RecordBindingPatternError(scanner()->location(), | 2123 classifier->RecordBindingPatternError( |
| 2104 "strict_eval_arguments"); | 2124 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| 2105 } | 2125 } |
| 2106 if (is_strong(language_mode())) { | 2126 if (is_strong(language_mode())) { |
| 2107 classifier->RecordExpressionError(scanner()->location(), | 2127 classifier->RecordExpressionError(scanner()->location(), |
| 2108 "strong_arguments"); | 2128 MessageTemplate::kStrongArguments); |
| 2109 } | 2129 } |
| 2110 } | 2130 } |
| 2111 if (this->IsUndefined(name)) { | 2131 if (this->IsUndefined(name)) { |
| 2112 classifier->RecordStrongModeFormalParameterError(scanner()->location(), | 2132 classifier->RecordStrongModeFormalParameterError( |
| 2113 "strong_undefined"); | 2133 scanner()->location(), MessageTemplate::kStrongUndefined); |
| 2114 if (is_strong(language_mode())) { | 2134 if (is_strong(language_mode())) { |
| 2115 // TODO(dslomov): allow 'undefined' in nested patterns. | 2135 // TODO(dslomov): allow 'undefined' in nested patterns. |
| 2116 classifier->RecordBindingPatternError(scanner()->location(), | 2136 classifier->RecordBindingPatternError( |
| 2117 "strong_undefined"); | 2137 scanner()->location(), MessageTemplate::kStrongUndefined); |
| 2118 classifier->RecordAssignmentPatternError(scanner()->location(), | 2138 classifier->RecordAssignmentPatternError( |
| 2119 "strong_undefined"); | 2139 scanner()->location(), MessageTemplate::kStrongUndefined); |
| 2120 } | 2140 } |
| 2121 } | 2141 } |
| 2122 return name; | 2142 return name; |
| 2123 } else if (is_sloppy(language_mode()) && | 2143 } else if (is_sloppy(language_mode()) && |
| 2124 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 2144 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 2125 next == Token::LET || next == Token::STATIC || | 2145 next == Token::LET || next == Token::STATIC || |
| 2126 (next == Token::YIELD && !is_generator()))) { | 2146 (next == Token::YIELD && !is_generator()))) { |
| 2127 classifier->RecordStrictModeFormalParameterError( | 2147 classifier->RecordStrictModeFormalParameterError( |
| 2128 scanner()->location(), "unexpected_strict_reserved"); | 2148 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
| 2129 return this->GetSymbol(scanner()); | 2149 return this->GetSymbol(scanner()); |
| 2130 } else { | 2150 } else { |
| 2131 this->ReportUnexpectedToken(next); | 2151 this->ReportUnexpectedToken(next); |
| 2132 *ok = false; | 2152 *ok = false; |
| 2133 return Traits::EmptyIdentifier(); | 2153 return Traits::EmptyIdentifier(); |
| 2134 } | 2154 } |
| 2135 } | 2155 } |
| 2136 | 2156 |
| 2137 | 2157 |
| 2138 template <class Traits> | 2158 template <class Traits> |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 return result; | 2207 return result; |
| 2188 } | 2208 } |
| 2189 | 2209 |
| 2190 | 2210 |
| 2191 template <class Traits> | 2211 template <class Traits> |
| 2192 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 2212 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
| 2193 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { | 2213 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
| 2194 int pos = peek_position(); | 2214 int pos = peek_position(); |
| 2195 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 2215 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| 2196 Next(); | 2216 Next(); |
| 2197 ReportMessage("unterminated_regexp"); | 2217 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
| 2198 *ok = false; | 2218 *ok = false; |
| 2199 return Traits::EmptyExpression(); | 2219 return Traits::EmptyExpression(); |
| 2200 } | 2220 } |
| 2201 | 2221 |
| 2202 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2222 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 2203 | 2223 |
| 2204 IdentifierT js_pattern = this->GetNextSymbol(scanner()); | 2224 IdentifierT js_pattern = this->GetNextSymbol(scanner()); |
| 2205 if (!scanner()->ScanRegExpFlags()) { | 2225 if (!scanner()->ScanRegExpFlags()) { |
| 2206 Next(); | 2226 Next(); |
| 2207 ReportMessage("malformed_regexp_flags"); | 2227 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
| 2208 *ok = false; | 2228 *ok = false; |
| 2209 return Traits::EmptyExpression(); | 2229 return Traits::EmptyExpression(); |
| 2210 } | 2230 } |
| 2211 IdentifierT js_flags = this->GetNextSymbol(scanner()); | 2231 IdentifierT js_flags = this->GetNextSymbol(scanner()); |
| 2212 Next(); | 2232 Next(); |
| 2213 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 2233 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 2214 } | 2234 } |
| 2215 | 2235 |
| 2216 | 2236 |
| 2217 #define CHECK_OK ok); \ | 2237 #define CHECK_OK ok); \ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2252 ExpressionT result = this->EmptyExpression(); | 2272 ExpressionT result = this->EmptyExpression(); |
| 2253 Token::Value token = peek(); | 2273 Token::Value token = peek(); |
| 2254 switch (token) { | 2274 switch (token) { |
| 2255 case Token::THIS: { | 2275 case Token::THIS: { |
| 2256 BindingPatternUnexpectedToken(classifier); | 2276 BindingPatternUnexpectedToken(classifier); |
| 2257 Consume(Token::THIS); | 2277 Consume(Token::THIS); |
| 2258 if (is_strong(language_mode())) { | 2278 if (is_strong(language_mode())) { |
| 2259 // Constructors' usages of 'this' in strong mode are parsed separately. | 2279 // Constructors' usages of 'this' in strong mode are parsed separately. |
| 2260 // TODO(rossberg): this does not work with arrow functions yet. | 2280 // TODO(rossberg): this does not work with arrow functions yet. |
| 2261 if (i::IsConstructor(function_state_->kind())) { | 2281 if (i::IsConstructor(function_state_->kind())) { |
| 2262 ReportMessage("strong_constructor_this"); | 2282 ReportMessage(MessageTemplate::kStrongConstructorThis); |
| 2263 *ok = false; | 2283 *ok = false; |
| 2264 break; | 2284 break; |
| 2265 } | 2285 } |
| 2266 } | 2286 } |
| 2267 scope_->RecordThisUsage(); | 2287 scope_->RecordThisUsage(); |
| 2268 result = this->ThisExpression(scope_, factory(), beg_pos); | 2288 result = this->ThisExpression(scope_, factory(), beg_pos); |
| 2269 break; | 2289 break; |
| 2270 } | 2290 } |
| 2271 | 2291 |
| 2272 case Token::NULL_LITERAL: | 2292 case Token::NULL_LITERAL: |
| 2273 case Token::TRUE_LITERAL: | 2293 case Token::TRUE_LITERAL: |
| 2274 case Token::FALSE_LITERAL: | 2294 case Token::FALSE_LITERAL: |
| 2275 BindingPatternUnexpectedToken(classifier); | 2295 BindingPatternUnexpectedToken(classifier); |
| 2276 Next(); | 2296 Next(); |
| 2277 result = | 2297 result = |
| 2278 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2298 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 2279 break; | 2299 break; |
| 2280 case Token::SMI: | 2300 case Token::SMI: |
| 2281 case Token::NUMBER: | 2301 case Token::NUMBER: |
| 2282 classifier->RecordBindingPatternError(scanner()->location(), | 2302 classifier->RecordBindingPatternError( |
| 2283 "unexpected_token_number"); | 2303 scanner()->location(), MessageTemplate::kUnexpectedTokenNumber); |
| 2284 Next(); | 2304 Next(); |
| 2285 result = | 2305 result = |
| 2286 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2306 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 2287 break; | 2307 break; |
| 2288 | 2308 |
| 2289 case Token::IDENTIFIER: | 2309 case Token::IDENTIFIER: |
| 2290 case Token::LET: | 2310 case Token::LET: |
| 2291 case Token::STATIC: | 2311 case Token::STATIC: |
| 2292 case Token::YIELD: | 2312 case Token::YIELD: |
| 2293 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2313 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 2294 // Using eval or arguments in this context is OK even in strict mode. | 2314 // Using eval or arguments in this context is OK even in strict mode. |
| 2295 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2315 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 2296 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2316 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
| 2297 factory()); | 2317 factory()); |
| 2298 break; | 2318 break; |
| 2299 } | 2319 } |
| 2300 | 2320 |
| 2301 case Token::STRING: { | 2321 case Token::STRING: { |
| 2302 classifier->RecordBindingPatternError(scanner()->location(), | 2322 classifier->RecordBindingPatternError( |
| 2303 "unexpected_token_string"); | 2323 scanner()->location(), MessageTemplate::kUnexpectedTokenString); |
| 2304 Consume(Token::STRING); | 2324 Consume(Token::STRING); |
| 2305 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2325 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
| 2306 break; | 2326 break; |
| 2307 } | 2327 } |
| 2308 | 2328 |
| 2309 case Token::ASSIGN_DIV: | 2329 case Token::ASSIGN_DIV: |
| 2310 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); | 2330 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); |
| 2311 break; | 2331 break; |
| 2312 | 2332 |
| 2313 case Token::DIV: | 2333 case Token::DIV: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2335 // is_valid_binding_pattern() check to detect multiple levels of | 2355 // is_valid_binding_pattern() check to detect multiple levels of |
| 2336 // parenthesization. | 2356 // parenthesization. |
| 2337 if (!classifier->is_valid_binding_pattern()) { | 2357 if (!classifier->is_valid_binding_pattern()) { |
| 2338 ArrowFormalParametersUnexpectedToken(classifier); | 2358 ArrowFormalParametersUnexpectedToken(classifier); |
| 2339 } | 2359 } |
| 2340 BindingPatternUnexpectedToken(classifier); | 2360 BindingPatternUnexpectedToken(classifier); |
| 2341 Consume(Token::LPAREN); | 2361 Consume(Token::LPAREN); |
| 2342 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2362 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
| 2343 // As a primary expression, the only thing that can follow "()" is "=>". | 2363 // As a primary expression, the only thing that can follow "()" is "=>". |
| 2344 classifier->RecordBindingPatternError(scanner()->location(), | 2364 classifier->RecordBindingPatternError(scanner()->location(), |
| 2345 "unexpected_token", | 2365 MessageTemplate::kUnexpectedToken, |
| 2346 Token::String(Token::RPAREN)); | 2366 Token::String(Token::RPAREN)); |
| 2347 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2367 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 2348 scope->set_start_position(beg_pos); | 2368 scope->set_start_position(beg_pos); |
| 2349 ExpressionClassifier args_classifier; | 2369 ExpressionClassifier args_classifier; |
| 2350 bool has_rest = false; | 2370 bool has_rest = false; |
| 2351 result = this->ParseArrowFunctionLiteral(scope, has_rest, | 2371 result = this->ParseArrowFunctionLiteral(scope, has_rest, |
| 2352 args_classifier, CHECK_OK); | 2372 args_classifier, CHECK_OK); |
| 2353 } else { | 2373 } else { |
| 2354 // Heuristically try to detect immediately called functions before | 2374 // Heuristically try to detect immediately called functions before |
| 2355 // seeing the call parentheses. | 2375 // seeing the call parentheses. |
| 2356 parenthesized_function_ = (peek() == Token::FUNCTION); | 2376 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2357 result = this->ParseExpression(true, classifier, CHECK_OK); | 2377 result = this->ParseExpression(true, classifier, CHECK_OK); |
| 2358 Expect(Token::RPAREN, CHECK_OK); | 2378 Expect(Token::RPAREN, CHECK_OK); |
| 2359 } | 2379 } |
| 2360 break; | 2380 break; |
| 2361 | 2381 |
| 2362 case Token::CLASS: { | 2382 case Token::CLASS: { |
| 2363 BindingPatternUnexpectedToken(classifier); | 2383 BindingPatternUnexpectedToken(classifier); |
| 2364 Consume(Token::CLASS); | 2384 Consume(Token::CLASS); |
| 2365 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2385 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2366 ReportMessage("sloppy_lexical"); | 2386 ReportMessage(MessageTemplate::kSloppyLexical); |
| 2367 *ok = false; | 2387 *ok = false; |
| 2368 break; | 2388 break; |
| 2369 } | 2389 } |
| 2370 int class_token_position = position(); | 2390 int class_token_position = position(); |
| 2371 IdentifierT name = this->EmptyIdentifier(); | 2391 IdentifierT name = this->EmptyIdentifier(); |
| 2372 bool is_strict_reserved_name = false; | 2392 bool is_strict_reserved_name = false; |
| 2373 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2393 Scanner::Location class_name_location = Scanner::Location::invalid(); |
| 2374 if (peek_any_identifier()) { | 2394 if (peek_any_identifier()) { |
| 2375 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2395 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 2376 CHECK_OK); | 2396 CHECK_OK); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2450 // '[' Expression? (',' Expression?)* ']' | 2470 // '[' Expression? (',' Expression?)* ']' |
| 2451 | 2471 |
| 2452 int pos = peek_position(); | 2472 int pos = peek_position(); |
| 2453 typename Traits::Type::ExpressionList values = | 2473 typename Traits::Type::ExpressionList values = |
| 2454 this->NewExpressionList(4, zone_); | 2474 this->NewExpressionList(4, zone_); |
| 2455 Expect(Token::LBRACK, CHECK_OK); | 2475 Expect(Token::LBRACK, CHECK_OK); |
| 2456 while (peek() != Token::RBRACK) { | 2476 while (peek() != Token::RBRACK) { |
| 2457 ExpressionT elem = this->EmptyExpression(); | 2477 ExpressionT elem = this->EmptyExpression(); |
| 2458 if (peek() == Token::COMMA) { | 2478 if (peek() == Token::COMMA) { |
| 2459 if (is_strong(language_mode())) { | 2479 if (is_strong(language_mode())) { |
| 2460 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); | 2480 ReportMessageAt(scanner()->peek_location(), |
| 2481 MessageTemplate::kStrongEllision); |
| 2461 *ok = false; | 2482 *ok = false; |
| 2462 return this->EmptyExpression(); | 2483 return this->EmptyExpression(); |
| 2463 } | 2484 } |
| 2464 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2485 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2465 } else { | 2486 } else { |
| 2466 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2487 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2467 } | 2488 } |
| 2468 values->Add(elem, zone_); | 2489 values->Add(elem, zone_); |
| 2469 if (peek() != Token::RBRACK) { | 2490 if (peek() != Token::RBRACK) { |
| 2470 Expect(Token::COMMA, CHECK_OK); | 2491 Expect(Token::COMMA, CHECK_OK); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2768 // unspread_sequences_count is the number of sequences of parameters which | 2789 // unspread_sequences_count is the number of sequences of parameters which |
| 2769 // are not prefixed with a spread '...' operator. | 2790 // are not prefixed with a spread '...' operator. |
| 2770 if (is_spread) { | 2791 if (is_spread) { |
| 2771 was_unspread = false; | 2792 was_unspread = false; |
| 2772 } else if (!was_unspread) { | 2793 } else if (!was_unspread) { |
| 2773 was_unspread = true; | 2794 was_unspread = true; |
| 2774 unspread_sequences_count++; | 2795 unspread_sequences_count++; |
| 2775 } | 2796 } |
| 2776 | 2797 |
| 2777 if (result->length() > Code::kMaxArguments) { | 2798 if (result->length() > Code::kMaxArguments) { |
| 2778 ReportMessage("too_many_arguments"); | 2799 ReportMessage(MessageTemplate::kTooManyArguments); |
| 2779 *ok = false; | 2800 *ok = false; |
| 2780 return this->NullExpressionList(); | 2801 return this->NullExpressionList(); |
| 2781 } | 2802 } |
| 2782 done = (peek() != Token::COMMA); | 2803 done = (peek() != Token::COMMA); |
| 2783 if (!done) { | 2804 if (!done) { |
| 2784 Next(); | 2805 Next(); |
| 2785 } | 2806 } |
| 2786 } | 2807 } |
| 2787 Scanner::Location location = scanner_->location(); | 2808 Scanner::Location location = scanner_->location(); |
| 2788 if (Token::RPAREN != Next()) { | 2809 if (Token::RPAREN != Next()) { |
| 2789 ReportMessageAt(location, "unterminated_arg_list"); | 2810 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 2790 *ok = false; | 2811 *ok = false; |
| 2791 return this->NullExpressionList(); | 2812 return this->NullExpressionList(); |
| 2792 } | 2813 } |
| 2793 *first_spread_arg_loc = spread_arg; | 2814 *first_spread_arg_loc = spread_arg; |
| 2794 | 2815 |
| 2795 if (spread_arg.IsValid()) { | 2816 if (spread_arg.IsValid()) { |
| 2796 // Unspread parameter sequences are translated into array literals in the | 2817 // Unspread parameter sequences are translated into array literals in the |
| 2797 // parser. Ensure that the number of materialized literals matches between | 2818 // parser. Ensure that the number of materialized literals matches between |
| 2798 // the parser and preparser | 2819 // the parser and preparser |
| 2799 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2820 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2862 if (fni_ != NULL) fni_->Leave(); | 2883 if (fni_ != NULL) fni_->Leave(); |
| 2863 // Parsed conditional expression only (no assignment). | 2884 // Parsed conditional expression only (no assignment). |
| 2864 return expression; | 2885 return expression; |
| 2865 } | 2886 } |
| 2866 | 2887 |
| 2867 if (!allow_harmony_destructuring()) { | 2888 if (!allow_harmony_destructuring()) { |
| 2868 BindingPatternUnexpectedToken(classifier); | 2889 BindingPatternUnexpectedToken(classifier); |
| 2869 } | 2890 } |
| 2870 | 2891 |
| 2871 expression = this->CheckAndRewriteReferenceExpression( | 2892 expression = this->CheckAndRewriteReferenceExpression( |
| 2872 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2893 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, |
| 2894 CHECK_OK); |
| 2873 expression = this->MarkExpressionAsAssigned(expression); | 2895 expression = this->MarkExpressionAsAssigned(expression); |
| 2874 | 2896 |
| 2875 Token::Value op = Next(); // Get assignment operator. | 2897 Token::Value op = Next(); // Get assignment operator. |
| 2876 int pos = position(); | 2898 int pos = position(); |
| 2877 ExpressionT right = | 2899 ExpressionT right = |
| 2878 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2900 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
| 2879 | 2901 |
| 2880 // TODO(1231235): We try to estimate the set of properties set by | 2902 // TODO(1231235): We try to estimate the set of properties set by |
| 2881 // constructors. We define a new property whenever there is an | 2903 // constructors. We define a new property whenever there is an |
| 2882 // assignment to a property of 'this'. We should probably only add | 2904 // assignment to a property of 'this'. We should probably only add |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3010 // code and AST node eventually.) | 3032 // code and AST node eventually.) |
| 3011 if (Token::IsCompareOp(op)) { | 3033 if (Token::IsCompareOp(op)) { |
| 3012 // We have a comparison. | 3034 // We have a comparison. |
| 3013 Token::Value cmp = op; | 3035 Token::Value cmp = op; |
| 3014 switch (op) { | 3036 switch (op) { |
| 3015 case Token::NE: cmp = Token::EQ; break; | 3037 case Token::NE: cmp = Token::EQ; break; |
| 3016 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 3038 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
| 3017 default: break; | 3039 default: break; |
| 3018 } | 3040 } |
| 3019 if (cmp == Token::EQ && is_strong(language_mode())) { | 3041 if (cmp == Token::EQ && is_strong(language_mode())) { |
| 3020 ReportMessageAt(op_location, "strong_equal"); | 3042 ReportMessageAt(op_location, MessageTemplate::kStrongEqual); |
| 3021 *ok = false; | 3043 *ok = false; |
| 3022 return this->EmptyExpression(); | 3044 return this->EmptyExpression(); |
| 3023 } | 3045 } |
| 3024 x = factory()->NewCompareOperation(cmp, x, y, pos); | 3046 x = factory()->NewCompareOperation(cmp, x, y, pos); |
| 3025 if (cmp != op) { | 3047 if (cmp != op) { |
| 3026 // The comparison was negated - add a NOT. | 3048 // The comparison was negated - add a NOT. |
| 3027 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | 3049 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
| 3028 } | 3050 } |
| 3029 | 3051 |
| 3030 } else { | 3052 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3056 Token::Value op = peek(); | 3078 Token::Value op = peek(); |
| 3057 if (Token::IsUnaryOp(op)) { | 3079 if (Token::IsUnaryOp(op)) { |
| 3058 BindingPatternUnexpectedToken(classifier); | 3080 BindingPatternUnexpectedToken(classifier); |
| 3059 | 3081 |
| 3060 op = Next(); | 3082 op = Next(); |
| 3061 int pos = position(); | 3083 int pos = position(); |
| 3062 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 3084 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 3063 | 3085 |
| 3064 if (op == Token::DELETE && is_strict(language_mode())) { | 3086 if (op == Token::DELETE && is_strict(language_mode())) { |
| 3065 if (is_strong(language_mode())) { | 3087 if (is_strong(language_mode())) { |
| 3066 ReportMessage("strong_delete"); | 3088 ReportMessage(MessageTemplate::kStrongDelete); |
| 3067 *ok = false; | 3089 *ok = false; |
| 3068 return this->EmptyExpression(); | 3090 return this->EmptyExpression(); |
| 3069 } else if (this->IsIdentifier(expression)) { | 3091 } else if (this->IsIdentifier(expression)) { |
| 3070 // "delete identifier" is a syntax error in strict mode. | 3092 // "delete identifier" is a syntax error in strict mode. |
| 3071 ReportMessage("strict_delete"); | 3093 ReportMessage(MessageTemplate::kStrictDelete); |
| 3072 *ok = false; | 3094 *ok = false; |
| 3073 return this->EmptyExpression(); | 3095 return this->EmptyExpression(); |
| 3074 } | 3096 } |
| 3075 } | 3097 } |
| 3076 | 3098 |
| 3077 // Allow Traits do rewrite the expression. | 3099 // Allow Traits do rewrite the expression. |
| 3078 return this->BuildUnaryExpression(expression, op, pos, factory()); | 3100 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 3079 } else if (Token::IsCountOp(op)) { | 3101 } else if (Token::IsCountOp(op)) { |
| 3080 BindingPatternUnexpectedToken(classifier); | 3102 BindingPatternUnexpectedToken(classifier); |
| 3081 op = Next(); | 3103 op = Next(); |
| 3082 Scanner::Location lhs_location = scanner()->peek_location(); | 3104 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3083 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 3105 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 3084 expression = this->CheckAndRewriteReferenceExpression( | 3106 expression = this->CheckAndRewriteReferenceExpression( |
| 3085 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 3107 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, |
| 3108 CHECK_OK); |
| 3086 this->MarkExpressionAsAssigned(expression); | 3109 this->MarkExpressionAsAssigned(expression); |
| 3087 | 3110 |
| 3088 return factory()->NewCountOperation(op, | 3111 return factory()->NewCountOperation(op, |
| 3089 true /* prefix */, | 3112 true /* prefix */, |
| 3090 expression, | 3113 expression, |
| 3091 position()); | 3114 position()); |
| 3092 | 3115 |
| 3093 } else { | 3116 } else { |
| 3094 return this->ParsePostfixExpression(classifier, ok); | 3117 return this->ParsePostfixExpression(classifier, ok); |
| 3095 } | 3118 } |
| 3096 } | 3119 } |
| 3097 | 3120 |
| 3098 | 3121 |
| 3099 template <class Traits> | 3122 template <class Traits> |
| 3100 typename ParserBase<Traits>::ExpressionT | 3123 typename ParserBase<Traits>::ExpressionT |
| 3101 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 3124 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 3102 bool* ok) { | 3125 bool* ok) { |
| 3103 // PostfixExpression :: | 3126 // PostfixExpression :: |
| 3104 // LeftHandSideExpression ('++' | '--')? | 3127 // LeftHandSideExpression ('++' | '--')? |
| 3105 | 3128 |
| 3106 Scanner::Location lhs_location = scanner()->peek_location(); | 3129 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3107 ExpressionT expression = | 3130 ExpressionT expression = |
| 3108 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3131 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 3109 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3132 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 3110 Token::IsCountOp(peek())) { | 3133 Token::IsCountOp(peek())) { |
| 3111 BindingPatternUnexpectedToken(classifier); | 3134 BindingPatternUnexpectedToken(classifier); |
| 3112 | 3135 |
| 3113 expression = this->CheckAndRewriteReferenceExpression( | 3136 expression = this->CheckAndRewriteReferenceExpression( |
| 3114 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 3137 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, |
| 3138 CHECK_OK); |
| 3115 expression = this->MarkExpressionAsAssigned(expression); | 3139 expression = this->MarkExpressionAsAssigned(expression); |
| 3116 | 3140 |
| 3117 Token::Value next = Next(); | 3141 Token::Value next = Next(); |
| 3118 expression = | 3142 expression = |
| 3119 factory()->NewCountOperation(next, | 3143 factory()->NewCountOperation(next, |
| 3120 false /* postfix */, | 3144 false /* postfix */, |
| 3121 expression, | 3145 expression, |
| 3122 position()); | 3146 position()); |
| 3123 } | 3147 } |
| 3124 return expression; | 3148 return expression; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3145 result = factory()->NewProperty(result, index, pos); | 3169 result = factory()->NewProperty(result, index, pos); |
| 3146 Expect(Token::RBRACK, CHECK_OK); | 3170 Expect(Token::RBRACK, CHECK_OK); |
| 3147 break; | 3171 break; |
| 3148 } | 3172 } |
| 3149 | 3173 |
| 3150 case Token::LPAREN: { | 3174 case Token::LPAREN: { |
| 3151 BindingPatternUnexpectedToken(classifier); | 3175 BindingPatternUnexpectedToken(classifier); |
| 3152 | 3176 |
| 3153 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3177 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
| 3154 this->IsEval(this->AsIdentifier(result))) { | 3178 this->IsEval(this->AsIdentifier(result))) { |
| 3155 ReportMessage("strong_direct_eval"); | 3179 ReportMessage(MessageTemplate::kStrongDirectEval); |
| 3156 *ok = false; | 3180 *ok = false; |
| 3157 return this->EmptyExpression(); | 3181 return this->EmptyExpression(); |
| 3158 } | 3182 } |
| 3159 int pos; | 3183 int pos; |
| 3160 if (scanner()->current_token() == Token::IDENTIFIER) { | 3184 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3161 // For call of an identifier we want to report position of | 3185 // For call of an identifier we want to report position of |
| 3162 // the identifier as position of the call in the stack trace. | 3186 // the identifier as position of the call in the stack trace. |
| 3163 pos = position(); | 3187 pos = position(); |
| 3164 } else { | 3188 } else { |
| 3165 // For other kinds of calls we record position of the parenthesis as | 3189 // For other kinds of calls we record position of the parenthesis as |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3357 int pos = position(); | 3381 int pos = position(); |
| 3358 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3382 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3359 left = factory()->NewProperty( | 3383 left = factory()->NewProperty( |
| 3360 this_expr, factory()->NewStringLiteral(name, pos), pos); | 3384 this_expr, factory()->NewStringLiteral(name, pos), pos); |
| 3361 if (fni_ != NULL) { | 3385 if (fni_ != NULL) { |
| 3362 this->PushLiteralName(fni_, name); | 3386 this->PushLiteralName(fni_, name); |
| 3363 } | 3387 } |
| 3364 break; | 3388 break; |
| 3365 } | 3389 } |
| 3366 default: | 3390 default: |
| 3367 ReportMessage("strong_constructor_this"); | 3391 ReportMessage(MessageTemplate::kStrongConstructorThis); |
| 3368 *ok = false; | 3392 *ok = false; |
| 3369 return this->EmptyExpression(); | 3393 return this->EmptyExpression(); |
| 3370 } | 3394 } |
| 3371 | 3395 |
| 3372 if (peek() != Token::ASSIGN) { | 3396 if (peek() != Token::ASSIGN) { |
| 3373 ReportMessageAt(function_state_->this_location(), | 3397 ReportMessageAt(function_state_->this_location(), |
| 3374 "strong_constructor_this"); | 3398 MessageTemplate::kStrongConstructorThis); |
| 3375 *ok = false; | 3399 *ok = false; |
| 3376 return this->EmptyExpression(); | 3400 return this->EmptyExpression(); |
| 3377 } | 3401 } |
| 3378 Consume(Token::ASSIGN); | 3402 Consume(Token::ASSIGN); |
| 3379 left = this->MarkExpressionAsAssigned(left); | 3403 left = this->MarkExpressionAsAssigned(left); |
| 3380 | 3404 |
| 3381 ExpressionT right = | 3405 ExpressionT right = |
| 3382 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 3406 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 3383 this->CheckAssigningFunctionLiteralToProperty(left, right); | 3407 this->CheckAssigningFunctionLiteralToProperty(left, right); |
| 3384 function_state_->AddProperty(); | 3408 function_state_->AddProperty(); |
| 3385 if (fni_ != NULL) { | 3409 if (fni_ != NULL) { |
| 3386 // Check if the right hand side is a call to avoid inferring a | 3410 // Check if the right hand side is a call to avoid inferring a |
| 3387 // name if we're dealing with "this.a = function(){...}();"-like | 3411 // name if we're dealing with "this.a = function(){...}();"-like |
| 3388 // expression. | 3412 // expression. |
| 3389 if (!right->IsCall() && !right->IsCallNew()) { | 3413 if (!right->IsCall() && !right->IsCallNew()) { |
| 3390 fni_->Infer(); | 3414 fni_->Infer(); |
| 3391 } else { | 3415 } else { |
| 3392 fni_->RemoveLastFunction(); | 3416 fni_->RemoveLastFunction(); |
| 3393 } | 3417 } |
| 3394 fni_->Leave(); | 3418 fni_->Leave(); |
| 3395 } | 3419 } |
| 3396 | 3420 |
| 3397 if (function_state_->return_location().IsValid()) { | 3421 if (function_state_->return_location().IsValid()) { |
| 3398 ReportMessageAt(function_state_->return_location(), | 3422 ReportMessageAt(function_state_->return_location(), |
| 3399 "strong_constructor_return_misplaced"); | 3423 MessageTemplate::kStrongConstructorReturnMisplaced); |
| 3400 *ok = false; | 3424 *ok = false; |
| 3401 return this->EmptyExpression(); | 3425 return this->EmptyExpression(); |
| 3402 } | 3426 } |
| 3403 | 3427 |
| 3404 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | 3428 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); |
| 3405 } | 3429 } |
| 3406 | 3430 |
| 3407 | 3431 |
| 3408 template <class Traits> | 3432 template <class Traits> |
| 3409 typename ParserBase<Traits>::ExpressionT | 3433 typename ParserBase<Traits>::ExpressionT |
| 3410 ParserBase<Traits>::ParseStrongSuperCallExpression( | 3434 ParserBase<Traits>::ParseStrongSuperCallExpression( |
| 3411 ExpressionClassifier* classifier, bool* ok) { | 3435 ExpressionClassifier* classifier, bool* ok) { |
| 3412 // SuperCallExpression :: (strong mode) | 3436 // SuperCallExpression :: (strong mode) |
| 3413 // 'super' '(' ExpressionList ')' | 3437 // 'super' '(' ExpressionList ')' |
| 3414 BindingPatternUnexpectedToken(classifier); | 3438 BindingPatternUnexpectedToken(classifier); |
| 3415 | 3439 |
| 3416 Consume(Token::SUPER); | 3440 Consume(Token::SUPER); |
| 3417 int pos = position(); | 3441 int pos = position(); |
| 3418 Scanner::Location super_loc = scanner()->location(); | 3442 Scanner::Location super_loc = scanner()->location(); |
| 3419 ExpressionT expr = this->SuperReference(scope_, factory()); | 3443 ExpressionT expr = this->SuperReference(scope_, factory()); |
| 3420 | 3444 |
| 3421 if (peek() != Token::LPAREN) { | 3445 if (peek() != Token::LPAREN) { |
| 3422 ReportMessage("strong_constructor_super"); | 3446 ReportMessage(MessageTemplate::kStrongConstructorSuper); |
| 3423 *ok = false; | 3447 *ok = false; |
| 3424 return this->EmptyExpression(); | 3448 return this->EmptyExpression(); |
| 3425 } | 3449 } |
| 3426 | 3450 |
| 3427 Scanner::Location spread_pos; | 3451 Scanner::Location spread_pos; |
| 3428 typename Traits::Type::ExpressionList args = | 3452 typename Traits::Type::ExpressionList args = |
| 3429 ParseArguments(&spread_pos, classifier, CHECK_OK); | 3453 ParseArguments(&spread_pos, classifier, CHECK_OK); |
| 3430 | 3454 |
| 3431 // TODO(rossberg): This doesn't work with arrow functions yet. | 3455 // TODO(rossberg): This doesn't work with arrow functions yet. |
| 3432 if (!IsSubclassConstructor(function_state_->kind())) { | 3456 if (!IsSubclassConstructor(function_state_->kind())) { |
| 3433 ReportMessage("unexpected_super"); | 3457 ReportMessage(MessageTemplate::kUnexpectedSuper); |
| 3434 *ok = false; | 3458 *ok = false; |
| 3435 return this->EmptyExpression(); | 3459 return this->EmptyExpression(); |
| 3436 } else if (function_state_->super_location().IsValid()) { | 3460 } else if (function_state_->super_location().IsValid()) { |
| 3437 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | 3461 ReportMessageAt(scanner()->location(), |
| 3462 MessageTemplate::kStrongSuperCallDuplicate); |
| 3438 *ok = false; | 3463 *ok = false; |
| 3439 return this->EmptyExpression(); | 3464 return this->EmptyExpression(); |
| 3440 } else if (function_state_->this_location().IsValid()) { | 3465 } else if (function_state_->this_location().IsValid()) { |
| 3441 ReportMessageAt(scanner()->location(), "strong_super_call_misplaced"); | 3466 ReportMessageAt(scanner()->location(), |
| 3467 MessageTemplate::kStrongSuperCallMisplaced); |
| 3442 *ok = false; | 3468 *ok = false; |
| 3443 return this->EmptyExpression(); | 3469 return this->EmptyExpression(); |
| 3444 } else if (function_state_->return_location().IsValid()) { | 3470 } else if (function_state_->return_location().IsValid()) { |
| 3445 ReportMessageAt(function_state_->return_location(), | 3471 ReportMessageAt(function_state_->return_location(), |
| 3446 "strong_constructor_return_misplaced"); | 3472 MessageTemplate::kStrongConstructorReturnMisplaced); |
| 3447 *ok = false; | 3473 *ok = false; |
| 3448 return this->EmptyExpression(); | 3474 return this->EmptyExpression(); |
| 3449 } | 3475 } |
| 3450 | 3476 |
| 3451 function_state_->set_super_location(super_loc); | 3477 function_state_->set_super_location(super_loc); |
| 3452 if (spread_pos.IsValid()) { | 3478 if (spread_pos.IsValid()) { |
| 3453 args = Traits::PrepareSpreadArguments(args); | 3479 args = Traits::PrepareSpreadArguments(args); |
| 3454 return Traits::SpreadCall(expr, args, pos); | 3480 return Traits::SpreadCall(expr, args, pos); |
| 3455 } else { | 3481 } else { |
| 3456 return factory()->NewCall(expr, args, pos); | 3482 return factory()->NewCall(expr, args, pos); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3477 i::IsConstructor(kind)) { | 3503 i::IsConstructor(kind)) { |
| 3478 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3504 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 3479 scope_->RecordSuperPropertyUsage(); | 3505 scope_->RecordSuperPropertyUsage(); |
| 3480 return this->SuperReference(scope_, factory()); | 3506 return this->SuperReference(scope_, factory()); |
| 3481 } | 3507 } |
| 3482 // new super() is never allowed. | 3508 // new super() is never allowed. |
| 3483 // super() is only allowed in derived constructor | 3509 // super() is only allowed in derived constructor |
| 3484 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3510 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3485 if (is_strong(language_mode())) { | 3511 if (is_strong(language_mode())) { |
| 3486 // Super calls in strong mode are parsed separately. | 3512 // Super calls in strong mode are parsed separately. |
| 3487 ReportMessageAt(scanner()->location(), "strong_constructor_super"); | 3513 ReportMessageAt(scanner()->location(), |
| 3514 MessageTemplate::kStrongConstructorSuper); |
| 3488 *ok = false; | 3515 *ok = false; |
| 3489 return this->EmptyExpression(); | 3516 return this->EmptyExpression(); |
| 3490 } | 3517 } |
| 3491 function_state->set_super_location(scanner()->location()); | 3518 function_state->set_super_location(scanner()->location()); |
| 3492 return this->SuperReference(scope_, factory()); | 3519 return this->SuperReference(scope_, factory()); |
| 3493 } | 3520 } |
| 3494 } | 3521 } |
| 3495 | 3522 |
| 3496 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3523 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); |
| 3497 *ok = false; | 3524 *ok = false; |
| 3498 return this->EmptyExpression(); | 3525 return this->EmptyExpression(); |
| 3499 } | 3526 } |
| 3500 | 3527 |
| 3501 | 3528 |
| 3502 template <class Traits> | 3529 template <class Traits> |
| 3503 typename ParserBase<Traits>::ExpressionT | 3530 typename ParserBase<Traits>::ExpressionT |
| 3504 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3531 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 3505 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3532 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| 3506 // Parses this part of MemberExpression: | 3533 // Parses this part of MemberExpression: |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3593 // FormalsList[Yield,GeneratorParameter] : | 3620 // FormalsList[Yield,GeneratorParameter] : |
| 3594 // FormalParameter[?Yield, ?GeneratorParameter] | 3621 // FormalParameter[?Yield, ?GeneratorParameter] |
| 3595 // FormalsList[?Yield, ?GeneratorParameter] , | 3622 // FormalsList[?Yield, ?GeneratorParameter] , |
| 3596 // FormalParameter[?Yield,?GeneratorParameter] | 3623 // FormalParameter[?Yield,?GeneratorParameter] |
| 3597 | 3624 |
| 3598 int parameter_count = 0; | 3625 int parameter_count = 0; |
| 3599 | 3626 |
| 3600 if (peek() != Token::RPAREN) { | 3627 if (peek() != Token::RPAREN) { |
| 3601 do { | 3628 do { |
| 3602 if (++parameter_count > Code::kMaxArguments) { | 3629 if (++parameter_count > Code::kMaxArguments) { |
| 3603 ReportMessage("too_many_parameters"); | 3630 ReportMessage(MessageTemplate::kTooManyParameters); |
| 3604 *ok = false; | 3631 *ok = false; |
| 3605 return -1; | 3632 return -1; |
| 3606 } | 3633 } |
| 3607 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); | 3634 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); |
| 3608 ParseFormalParameter(scope, *is_rest, classifier, ok); | 3635 ParseFormalParameter(scope, *is_rest, classifier, ok); |
| 3609 if (!*ok) return -1; | 3636 if (!*ok) return -1; |
| 3610 } while (!*is_rest && Check(Token::COMMA)); | 3637 } while (!*is_rest && Check(Token::COMMA)); |
| 3611 | 3638 |
| 3612 if (*is_rest && peek() == Token::COMMA) { | 3639 if (*is_rest && peek() == Token::COMMA) { |
| 3613 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); | 3640 ReportMessageAt(scanner()->peek_location(), |
| 3641 MessageTemplate::kParamAfterRest); |
| 3614 *ok = false; | 3642 *ok = false; |
| 3615 return -1; | 3643 return -1; |
| 3616 } | 3644 } |
| 3617 } | 3645 } |
| 3618 | 3646 |
| 3619 return parameter_count; | 3647 return parameter_count; |
| 3620 } | 3648 } |
| 3621 | 3649 |
| 3622 | 3650 |
| 3623 template <class Traits> | 3651 template <class Traits> |
| 3624 void ParserBase<Traits>::CheckArityRestrictions( | 3652 void ParserBase<Traits>::CheckArityRestrictions( |
| 3625 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 3653 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| 3626 int formals_start_pos, int formals_end_pos, bool* ok) { | 3654 int formals_start_pos, int formals_end_pos, bool* ok) { |
| 3627 switch (arity_restriction) { | 3655 switch (arity_restriction) { |
| 3628 case FunctionLiteral::GETTER_ARITY: | 3656 case FunctionLiteral::GETTER_ARITY: |
| 3629 if (param_count != 0) { | 3657 if (param_count != 0) { |
| 3630 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3658 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
| 3631 "bad_getter_arity"); | 3659 MessageTemplate::kBadGetterArity); |
| 3632 *ok = false; | 3660 *ok = false; |
| 3633 } | 3661 } |
| 3634 break; | 3662 break; |
| 3635 case FunctionLiteral::SETTER_ARITY: | 3663 case FunctionLiteral::SETTER_ARITY: |
| 3636 if (param_count != 1) { | 3664 if (param_count != 1) { |
| 3637 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3665 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
| 3638 "bad_setter_arity"); | 3666 MessageTemplate::kBadSetterArity); |
| 3639 *ok = false; | 3667 *ok = false; |
| 3640 } | 3668 } |
| 3641 break; | 3669 break; |
| 3642 default: | 3670 default: |
| 3643 break; | 3671 break; |
| 3644 } | 3672 } |
| 3645 } | 3673 } |
| 3646 | 3674 |
| 3647 | 3675 |
| 3648 template <class Traits> | 3676 template <class Traits> |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3779 | 3807 |
| 3780 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, | 3808 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, |
| 3781 // and repeat if the following token is a TEMPLATE_SPAN as well (in this | 3809 // and repeat if the following token is a TEMPLATE_SPAN as well (in this |
| 3782 // case, representing a TemplateMiddle). | 3810 // case, representing a TemplateMiddle). |
| 3783 | 3811 |
| 3784 do { | 3812 do { |
| 3785 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3813 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
| 3786 next = peek(); | 3814 next = peek(); |
| 3787 if (next == Token::EOS) { | 3815 if (next == Token::EOS) { |
| 3788 ReportMessageAt(Scanner::Location(start, peek_position()), | 3816 ReportMessageAt(Scanner::Location(start, peek_position()), |
| 3789 "unterminated_template"); | 3817 MessageTemplate::kUnterminatedTemplate); |
| 3790 *ok = false; | 3818 *ok = false; |
| 3791 return Traits::EmptyExpression(); | 3819 return Traits::EmptyExpression(); |
| 3792 } else if (next == Token::ILLEGAL) { | 3820 } else if (next == Token::ILLEGAL) { |
| 3793 Traits::ReportMessageAt( | 3821 Traits::ReportMessageAt( |
| 3794 Scanner::Location(position() + 1, peek_position()), | 3822 Scanner::Location(position() + 1, peek_position()), |
| 3795 "unexpected_token", "ILLEGAL", kSyntaxError); | 3823 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3796 *ok = false; | 3824 *ok = false; |
| 3797 return Traits::EmptyExpression(); | 3825 return Traits::EmptyExpression(); |
| 3798 } | 3826 } |
| 3799 | 3827 |
| 3800 int expr_pos = peek_position(); | 3828 int expr_pos = peek_position(); |
| 3801 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3829 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
| 3802 Traits::AddTemplateExpression(&ts, expression); | 3830 Traits::AddTemplateExpression(&ts, expression); |
| 3803 | 3831 |
| 3804 if (peek() != Token::RBRACE) { | 3832 if (peek() != Token::RBRACE) { |
| 3805 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3833 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
| 3806 "unterminated_template_expr"); | 3834 MessageTemplate::kUnterminatedTemplateExpr); |
| 3807 *ok = false; | 3835 *ok = false; |
| 3808 return Traits::EmptyExpression(); | 3836 return Traits::EmptyExpression(); |
| 3809 } | 3837 } |
| 3810 | 3838 |
| 3811 // If we didn't die parsing that expression, our next token should be a | 3839 // If we didn't die parsing that expression, our next token should be a |
| 3812 // TEMPLATE_SPAN or TEMPLATE_TAIL. | 3840 // TEMPLATE_SPAN or TEMPLATE_TAIL. |
| 3813 next = scanner()->ScanTemplateContinuation(); | 3841 next = scanner()->ScanTemplateContinuation(); |
| 3814 Next(); | 3842 Next(); |
| 3815 pos = position(); | 3843 pos = position(); |
| 3816 | 3844 |
| 3817 if (next == Token::EOS) { | 3845 if (next == Token::EOS) { |
| 3818 ReportMessageAt(Scanner::Location(start, pos), "unterminated_template"); | 3846 ReportMessageAt(Scanner::Location(start, pos), |
| 3847 MessageTemplate::kUnterminatedTemplate); |
| 3819 *ok = false; | 3848 *ok = false; |
| 3820 return Traits::EmptyExpression(); | 3849 return Traits::EmptyExpression(); |
| 3821 } else if (next == Token::ILLEGAL) { | 3850 } else if (next == Token::ILLEGAL) { |
| 3822 Traits::ReportMessageAt( | 3851 Traits::ReportMessageAt( |
| 3823 Scanner::Location(position() + 1, peek_position()), | 3852 Scanner::Location(position() + 1, peek_position()), |
| 3824 "unexpected_token", "ILLEGAL", kSyntaxError); | 3853 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3825 *ok = false; | 3854 *ok = false; |
| 3826 return Traits::EmptyExpression(); | 3855 return Traits::EmptyExpression(); |
| 3827 } | 3856 } |
| 3828 | 3857 |
| 3829 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3858 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
| 3830 } while (next == Token::TEMPLATE_SPAN); | 3859 } while (next == Token::TEMPLATE_SPAN); |
| 3831 | 3860 |
| 3832 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3861 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
| 3833 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3862 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
| 3834 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3863 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
| 3835 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3864 return Traits::CloseTemplateLiteral(&ts, start, tag); |
| 3836 } | 3865 } |
| 3837 | 3866 |
| 3838 | 3867 |
| 3839 template <typename Traits> | 3868 template <typename Traits> |
| 3840 typename ParserBase<Traits>::ExpressionT ParserBase< | 3869 typename ParserBase<Traits>::ExpressionT |
| 3841 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, | 3870 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
| 3842 Scanner::Location location, | 3871 ExpressionT expression, Scanner::Location location, |
| 3843 const char* message, bool* ok) { | 3872 MessageTemplate::Template message, bool* ok) { |
| 3844 if (this->IsIdentifier(expression)) { | 3873 if (this->IsIdentifier(expression)) { |
| 3845 if (is_strict(language_mode()) && | 3874 if (is_strict(language_mode()) && |
| 3846 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3875 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 3847 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); | 3876 this->ReportMessageAt(location, MessageTemplate::kStrictEvalArguments, |
| 3877 kSyntaxError); |
| 3848 *ok = false; | 3878 *ok = false; |
| 3849 return this->EmptyExpression(); | 3879 return this->EmptyExpression(); |
| 3850 } | 3880 } |
| 3851 if (is_strong(language_mode()) && | 3881 if (is_strong(language_mode()) && |
| 3852 this->IsUndefined(this->AsIdentifier(expression))) { | 3882 this->IsUndefined(this->AsIdentifier(expression))) { |
| 3853 this->ReportMessageAt(location, "strong_undefined", kSyntaxError); | 3883 this->ReportMessageAt(location, MessageTemplate::kStrongUndefined, |
| 3884 kSyntaxError); |
| 3854 *ok = false; | 3885 *ok = false; |
| 3855 return this->EmptyExpression(); | 3886 return this->EmptyExpression(); |
| 3856 } | 3887 } |
| 3857 } | 3888 } |
| 3858 if (expression->IsValidReferenceExpression()) { | 3889 if (expression->IsValidReferenceExpression()) { |
| 3859 return expression; | 3890 return expression; |
| 3860 } else if (expression->IsCall()) { | 3891 } else if (expression->IsCall()) { |
| 3861 // If it is a call, make it a runtime error for legacy web compatibility. | 3892 // If it is a call, make it a runtime error for legacy web compatibility. |
| 3862 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3893 // Rewrite `expr' to `expr[throw ReferenceError]'. |
| 3863 int pos = location.beg_pos; | 3894 int pos = location.beg_pos; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3879 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3910 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 3880 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3911 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
| 3881 bool* ok) { | 3912 bool* ok) { |
| 3882 DCHECK(!is_static); | 3913 DCHECK(!is_static); |
| 3883 DCHECK(!is_generator || type == kMethodProperty); | 3914 DCHECK(!is_generator || type == kMethodProperty); |
| 3884 | 3915 |
| 3885 if (property == Token::SMI || property == Token::NUMBER) return; | 3916 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3886 | 3917 |
| 3887 if (type == kValueProperty && IsProto()) { | 3918 if (type == kValueProperty && IsProto()) { |
| 3888 if (has_seen_proto_) { | 3919 if (has_seen_proto_) { |
| 3889 this->parser()->ReportMessage("duplicate_proto"); | 3920 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto); |
| 3890 *ok = false; | 3921 *ok = false; |
| 3891 return; | 3922 return; |
| 3892 } | 3923 } |
| 3893 has_seen_proto_ = true; | 3924 has_seen_proto_ = true; |
| 3894 return; | 3925 return; |
| 3895 } | 3926 } |
| 3896 } | 3927 } |
| 3897 | 3928 |
| 3898 | 3929 |
| 3899 template <typename Traits> | 3930 template <typename Traits> |
| 3900 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( | 3931 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( |
| 3901 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3932 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
| 3902 bool* ok) { | 3933 bool* ok) { |
| 3903 DCHECK(type == kMethodProperty || type == kAccessorProperty); | 3934 DCHECK(type == kMethodProperty || type == kAccessorProperty); |
| 3904 | 3935 |
| 3905 if (property == Token::SMI || property == Token::NUMBER) return; | 3936 if (property == Token::SMI || property == Token::NUMBER) return; |
| 3906 | 3937 |
| 3907 if (is_static) { | 3938 if (is_static) { |
| 3908 if (IsPrototype()) { | 3939 if (IsPrototype()) { |
| 3909 this->parser()->ReportMessage("static_prototype"); | 3940 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
| 3910 *ok = false; | 3941 *ok = false; |
| 3911 return; | 3942 return; |
| 3912 } | 3943 } |
| 3913 } else if (IsConstructor()) { | 3944 } else if (IsConstructor()) { |
| 3914 if (is_generator || type == kAccessorProperty) { | 3945 if (is_generator || type == kAccessorProperty) { |
| 3915 const char* msg = | 3946 MessageTemplate::Template msg = |
| 3916 is_generator ? "constructor_is_generator" : "constructor_is_accessor"; | 3947 is_generator ? MessageTemplate::kConstructorIsGenerator |
| 3948 : MessageTemplate::kConstructorIsAccessor; |
| 3917 this->parser()->ReportMessage(msg); | 3949 this->parser()->ReportMessage(msg); |
| 3918 *ok = false; | 3950 *ok = false; |
| 3919 return; | 3951 return; |
| 3920 } | 3952 } |
| 3921 if (has_seen_constructor_) { | 3953 if (has_seen_constructor_) { |
| 3922 this->parser()->ReportMessage("duplicate_constructor"); | 3954 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); |
| 3923 *ok = false; | 3955 *ok = false; |
| 3924 return; | 3956 return; |
| 3925 } | 3957 } |
| 3926 has_seen_constructor_ = true; | 3958 has_seen_constructor_ = true; |
| 3927 return; | 3959 return; |
| 3928 } | 3960 } |
| 3929 } | 3961 } |
| 3930 } } // v8::internal | 3962 } } // v8::internal |
| 3931 | 3963 |
| 3932 #endif // V8_PREPARSER_H | 3964 #endif // V8_PREPARSER_H |
| OLD | NEW |