| 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" |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 message(MessageTemplate::kNone), | 563 message(MessageTemplate::kNone), |
| 564 arg(nullptr) {} | 564 arg(nullptr) {} |
| 565 | 565 |
| 566 Scanner::Location location; | 566 Scanner::Location location; |
| 567 MessageTemplate::Template message; | 567 MessageTemplate::Template message; |
| 568 const char* arg; | 568 const char* arg; |
| 569 | 569 |
| 570 bool HasError() const { return location.IsValid(); } | 570 bool HasError() const { return location.IsValid(); } |
| 571 }; | 571 }; |
| 572 | 572 |
| 573 ExpressionClassifier() {} | 573 ExpressionClassifier() : lhs_type_(TARGET_NONE), assigned_(false) {} |
| 574 |
| 575 enum AssignmentTargetType { |
| 576 TARGET_NONE = 0, |
| 577 |
| 578 // IdentifierReference |
| 579 TARGET_IDENTIFIER, |
| 580 |
| 581 // MemberExpression . <property name> |
| 582 // MemberExpression [<property name>] |
| 583 TARGET_PROPERTY, |
| 584 |
| 585 // MemberExpression ( arguments ) |
| 586 // new MemberExpression ( arguments ) |
| 587 // MemberExpression TemplateLiteral |
| 588 TARGET_CALL, |
| 589 |
| 590 // this |
| 591 // Literal |
| 592 // ArrayLiteral |
| 593 // ObjectLiteral |
| 594 // FunctionExpression |
| 595 // ClassExpression |
| 596 // GeneratorExpression |
| 597 // RegularExpressionLiteral |
| 598 // TemplateLiteral |
| 599 // CoverParenthesizedExpressionAndArrowParameterList |
| 600 TARGET_PRIMARY, |
| 601 |
| 602 // new.target |
| 603 // yield (in generator) |
| 604 TARGET_RESTRICTED, |
| 605 |
| 606 // UnaryExpression |
| 607 // MultiplicativeExpression |
| 608 // AdditiveExpression |
| 609 // ShiftExpression |
| 610 // RelationalExpression |
| 611 // EqualityExpression |
| 612 // BitwiseANDExpression |
| 613 // BitwiseXORExpression |
| 614 // BitwiseORExpression |
| 615 // LogicalANDExpression |
| 616 // LogicalORExpression |
| 617 // ConditionalExpression |
| 618 // AssignmentExpression |
| 619 // ... Pretty much any binary operator |
| 620 UNACCEPTABLE_TARGET, |
| 621 |
| 622 // BindingPattern |
| 623 TARGET_PATTERN |
| 624 }; |
| 625 |
| 626 inline AssignmentTargetType AssignmentTarget() const { return lhs_type_; } |
| 627 |
| 628 inline void AppendAssignmentTarget(AssignmentTargetType type) { |
| 629 if (lhs_type_ == UNACCEPTABLE_TARGET) return; |
| 630 lhs_type_ = type; |
| 631 } |
| 632 |
| 633 inline void ReportInvalidSimpleAssignmentTarget() { |
| 634 lhs_type_ = UNACCEPTABLE_TARGET; |
| 635 } |
| 636 |
| 637 inline bool IsValidSimpleAssignmentTarget() const { |
| 638 // Only identifiers and properties are valid targets. |
| 639 return lhs_type_ >= TARGET_IDENTIFIER && lhs_type_ <= TARGET_PROPERTY; |
| 640 } |
| 641 |
| 642 inline bool IsPatternAssignmentElement() const { |
| 643 // Any AssignmentElement for which IsValidSimpleAssignmentTarget is false. |
| 644 // Used for nested AssignmentPatterns |
| 645 return lhs_type_ == TARGET_PATTERN && is_valid_assignment_pattern(); |
| 646 } |
| 647 |
| 648 void set_assigned() { assigned_ = true; } |
| 649 |
| 650 bool is_destructuring_assignment() const { |
| 651 return lhs_type_ == TARGET_PATTERN && assigned_; |
| 652 } |
| 574 | 653 |
| 575 bool is_valid_expression() const { return !expression_error_.HasError(); } | 654 bool is_valid_expression() const { return !expression_error_.HasError(); } |
| 576 | 655 |
| 577 bool is_valid_binding_pattern() const { | 656 bool is_valid_binding_pattern() const { |
| 578 return !binding_pattern_error_.HasError(); | 657 return !binding_pattern_error_.HasError(); |
| 579 } | 658 } |
| 580 | 659 |
| 581 bool is_valid_assignment_pattern() const { | 660 bool is_valid_assignment_pattern() const { |
| 582 return !assignment_pattern_error_.HasError(); | 661 return !assignment_pattern_error_.HasError(); |
| 583 } | 662 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 FormalParametersProduction = 1 << 3, | 779 FormalParametersProduction = 1 << 3, |
| 701 ArrowFormalParametersProduction = 1 << 4, | 780 ArrowFormalParametersProduction = 1 << 4, |
| 702 StandardProductions = (ExpressionProduction | BindingPatternProduction | | 781 StandardProductions = (ExpressionProduction | BindingPatternProduction | |
| 703 AssignmentPatternProduction), | 782 AssignmentPatternProduction), |
| 704 PatternProductions = | 783 PatternProductions = |
| 705 BindingPatternProduction | AssignmentPatternProduction, | 784 BindingPatternProduction | AssignmentPatternProduction, |
| 706 AllProductions = (StandardProductions | FormalParametersProduction | | 785 AllProductions = (StandardProductions | FormalParametersProduction | |
| 707 ArrowFormalParametersProduction), | 786 ArrowFormalParametersProduction), |
| 708 }; | 787 }; |
| 709 | 788 |
| 789 void AccumulateValidSimpleAssignmentTarget( |
| 790 const ExpressionClassifier& inner) { |
| 791 if (lhs_type_ != UNACCEPTABLE_TARGET) { |
| 792 lhs_type_ = inner.lhs_type_; |
| 793 } |
| 794 } |
| 795 |
| 710 void Accumulate(const ExpressionClassifier& inner, | 796 void Accumulate(const ExpressionClassifier& inner, |
| 711 unsigned productions = StandardProductions) { | 797 unsigned productions = StandardProductions) { |
| 712 if (productions & ExpressionProduction && is_valid_expression()) { | 798 if (productions & ExpressionProduction && is_valid_expression()) { |
| 713 expression_error_ = inner.expression_error_; | 799 expression_error_ = inner.expression_error_; |
| 714 } | 800 } |
| 715 if (productions & BindingPatternProduction && | 801 if (productions & BindingPatternProduction && |
| 716 is_valid_binding_pattern()) { | 802 is_valid_binding_pattern()) { |
| 717 binding_pattern_error_ = inner.binding_pattern_error_; | 803 binding_pattern_error_ = inner.binding_pattern_error_; |
| 718 } | 804 } |
| 719 if (productions & AssignmentPatternProduction && | 805 if (productions & AssignmentPatternProduction && |
| (...skipping 28 matching lines...) Expand all Loading... |
| 748 if (is_valid_binding_pattern()) { | 834 if (is_valid_binding_pattern()) { |
| 749 binding_pattern_error_ = inner.expression_error(); | 835 binding_pattern_error_ = inner.expression_error(); |
| 750 } | 836 } |
| 751 if (is_valid_assignment_pattern()) { | 837 if (is_valid_assignment_pattern()) { |
| 752 assignment_pattern_error_ = inner.expression_error(); | 838 assignment_pattern_error_ = inner.expression_error(); |
| 753 } | 839 } |
| 754 } | 840 } |
| 755 } | 841 } |
| 756 | 842 |
| 757 private: | 843 private: |
| 844 AssignmentTargetType lhs_type_; |
| 845 bool assigned_; |
| 758 Error expression_error_; | 846 Error expression_error_; |
| 759 Error binding_pattern_error_; | 847 Error binding_pattern_error_; |
| 760 Error assignment_pattern_error_; | 848 Error assignment_pattern_error_; |
| 761 Error arrow_formal_parameters_error_; | 849 Error arrow_formal_parameters_error_; |
| 762 Error duplicate_formal_parameter_error_; | 850 Error duplicate_formal_parameter_error_; |
| 763 Error strict_mode_formal_parameter_error_; | 851 Error strict_mode_formal_parameter_error_; |
| 764 Error strong_mode_formal_parameter_error_; | 852 Error strong_mode_formal_parameter_error_; |
| 765 }; | 853 }; |
| 766 | 854 |
| 855 ExpressionT CheckDestructuringAssignment(ExpressionT expr, |
| 856 ExpressionClassifier* classifier, |
| 857 bool* ok) { |
| 858 if (classifier->is_destructuring_assignment()) { |
| 859 if (!classifier->is_valid_assignment_pattern()) { |
| 860 this->ReportClassifierError(classifier->assignment_pattern_error()); |
| 861 *ok = false; |
| 862 return this->EmptyExpression(); |
| 863 } |
| 864 return Traits::RewriteDestructuringAssignment(expr); |
| 865 } |
| 866 return expr; |
| 867 } |
| 868 |
| 767 void ReportClassifierError( | 869 void ReportClassifierError( |
| 768 const typename ExpressionClassifier::Error& error) { | 870 const typename ExpressionClassifier::Error& error) { |
| 769 Traits::ReportMessageAt(error.location, error.message, error.arg, | 871 Traits::ReportMessageAt(error.location, error.message, error.arg, |
| 770 kSyntaxError); | 872 kSyntaxError); |
| 771 } | 873 } |
| 772 | 874 |
| 773 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 875 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
| 774 if (!classifier->is_valid_expression()) { | 876 if (!classifier->is_valid_expression()) { |
| 775 ReportClassifierError(classifier->expression_error()); | 877 ReportClassifierError(classifier->expression_error()); |
| 776 *ok = false; | 878 *ok = false; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 bool* is_static, bool* is_computed_name, | 980 bool* is_static, bool* is_computed_name, |
| 879 ExpressionClassifier* classifier, bool* ok); | 981 ExpressionClassifier* classifier, bool* ok); |
| 880 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 982 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 881 ObjectLiteralPropertyT ParsePropertyDefinition( | 983 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 882 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 984 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 883 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 985 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 884 ExpressionClassifier* classifier, bool* ok); | 986 ExpressionClassifier* classifier, bool* ok); |
| 885 typename Traits::Type::ExpressionList ParseArguments( | 987 typename Traits::Type::ExpressionList ParseArguments( |
| 886 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 988 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 887 bool* ok); | 989 bool* ok); |
| 990 // TODO(caitp): Use enums for accept_IN / pattern_lhs? |
| 991 ExpressionT ParseAssignmentExpression(bool accept_IN, bool pattern_lhs, |
| 992 ExpressionClassifier* classifier, |
| 993 bool* ok); |
| 888 ExpressionT ParseAssignmentExpression(bool accept_IN, | 994 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 889 ExpressionClassifier* classifier, | 995 ExpressionClassifier* classifier, |
| 890 bool* ok); | 996 bool* ok) { |
| 997 return ParseAssignmentExpression(accept_IN, false, classifier, ok); |
| 998 } |
| 891 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 999 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| 892 ExpressionT ParseConditionalExpression(bool accept_IN, | 1000 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 893 ExpressionClassifier* classifier, | 1001 ExpressionClassifier* classifier, |
| 894 bool* ok); | 1002 bool* ok); |
| 895 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1003 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 896 ExpressionClassifier* classifier, bool* ok); | 1004 ExpressionClassifier* classifier, bool* ok); |
| 897 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 1005 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 898 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 1006 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 899 bool* ok); | 1007 bool* ok); |
| 900 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 1008 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 | 1941 |
| 1834 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1942 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1835 | 1943 |
| 1836 inline PreParserExpression SpreadCall(PreParserExpression function, | 1944 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1837 PreParserExpressionList args, int pos); | 1945 PreParserExpressionList args, int pos); |
| 1838 | 1946 |
| 1839 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1947 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1840 PreParserExpressionList args, | 1948 PreParserExpressionList args, |
| 1841 int pos); | 1949 int pos); |
| 1842 | 1950 |
| 1951 inline PreParserExpression RewriteDestructuringAssignment( |
| 1952 PreParserExpression expr) { |
| 1953 return expr; |
| 1954 } |
| 1955 |
| 1843 private: | 1956 private: |
| 1844 PreParser* pre_parser_; | 1957 PreParser* pre_parser_; |
| 1845 }; | 1958 }; |
| 1846 | 1959 |
| 1847 | 1960 |
| 1848 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1961 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1849 // a later parsing to be faster. | 1962 // a later parsing to be faster. |
| 1850 // See preparse-data-format.h for the data format. | 1963 // See preparse-data-format.h for the data format. |
| 1851 | 1964 |
| 1852 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1965 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2310 // ObjectLiteral | 2423 // ObjectLiteral |
| 2311 // RegExpLiteral | 2424 // RegExpLiteral |
| 2312 // ClassLiteral | 2425 // ClassLiteral |
| 2313 // '(' Expression ')' | 2426 // '(' Expression ')' |
| 2314 // TemplateLiteral | 2427 // TemplateLiteral |
| 2315 | 2428 |
| 2316 int beg_pos = scanner()->peek_location().beg_pos; | 2429 int beg_pos = scanner()->peek_location().beg_pos; |
| 2317 int end_pos = scanner()->peek_location().end_pos; | 2430 int end_pos = scanner()->peek_location().end_pos; |
| 2318 ExpressionT result = this->EmptyExpression(); | 2431 ExpressionT result = this->EmptyExpression(); |
| 2319 Token::Value token = peek(); | 2432 Token::Value token = peek(); |
| 2433 typename ExpressionClassifier::AssignmentTargetType lhs_part = |
| 2434 ExpressionClassifier::TARGET_PRIMARY; |
| 2320 switch (token) { | 2435 switch (token) { |
| 2321 case Token::THIS: { | 2436 case Token::THIS: { |
| 2322 BindingPatternUnexpectedToken(classifier); | 2437 BindingPatternUnexpectedToken(classifier); |
| 2323 Consume(Token::THIS); | 2438 Consume(Token::THIS); |
| 2324 if (is_strong(language_mode())) { | 2439 if (is_strong(language_mode())) { |
| 2325 // Constructors' usages of 'this' in strong mode are parsed separately. | 2440 // Constructors' usages of 'this' in strong mode are parsed separately. |
| 2326 // TODO(rossberg): this does not work with arrow functions yet. | 2441 // TODO(rossberg): this does not work with arrow functions yet. |
| 2327 if (i::IsConstructor(function_state_->kind())) { | 2442 if (i::IsConstructor(function_state_->kind())) { |
| 2328 ReportMessage(MessageTemplate::kStrongConstructorThis); | 2443 ReportMessage(MessageTemplate::kStrongConstructorThis); |
| 2329 *ok = false; | 2444 *ok = false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2350 result = | 2465 result = |
| 2351 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2466 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 2352 break; | 2467 break; |
| 2353 | 2468 |
| 2354 case Token::IDENTIFIER: | 2469 case Token::IDENTIFIER: |
| 2355 case Token::LET: | 2470 case Token::LET: |
| 2356 case Token::STATIC: | 2471 case Token::STATIC: |
| 2357 case Token::YIELD: | 2472 case Token::YIELD: |
| 2358 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2473 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 2359 // Using eval or arguments in this context is OK even in strict mode. | 2474 // Using eval or arguments in this context is OK even in strict mode. |
| 2475 lhs_part = ExpressionClassifier::TARGET_IDENTIFIER; |
| 2360 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2476 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 2361 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2477 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
| 2362 factory()); | 2478 factory()); |
| 2363 break; | 2479 break; |
| 2364 } | 2480 } |
| 2365 | 2481 |
| 2366 case Token::STRING: { | 2482 case Token::STRING: { |
| 2367 classifier->RecordBindingPatternError( | 2483 classifier->RecordBindingPatternError( |
| 2368 scanner()->location(), MessageTemplate::kUnexpectedTokenString); | 2484 scanner()->location(), MessageTemplate::kUnexpectedTokenString); |
| 2369 Consume(Token::STRING); | 2485 Consume(Token::STRING); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2413 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2529 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2414 scope->set_start_position(beg_pos); | 2530 scope->set_start_position(beg_pos); |
| 2415 ExpressionClassifier args_classifier; | 2531 ExpressionClassifier args_classifier; |
| 2416 bool has_rest = false; | 2532 bool has_rest = false; |
| 2417 result = this->ParseArrowFunctionLiteral(scope, has_rest, | 2533 result = this->ParseArrowFunctionLiteral(scope, has_rest, |
| 2418 args_classifier, CHECK_OK); | 2534 args_classifier, CHECK_OK); |
| 2419 } else { | 2535 } else { |
| 2420 // Heuristically try to detect immediately called functions before | 2536 // Heuristically try to detect immediately called functions before |
| 2421 // seeing the call parentheses. | 2537 // seeing the call parentheses. |
| 2422 parenthesized_function_ = (peek() == Token::FUNCTION); | 2538 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2423 result = this->ParseExpression(true, classifier, CHECK_OK); | 2539 ExpressionClassifier expr_classifier; |
| 2540 result = this->ParseExpression(true, &expr_classifier, CHECK_OK); |
| 2424 Expect(Token::RPAREN, CHECK_OK); | 2541 Expect(Token::RPAREN, CHECK_OK); |
| 2542 if (peek() == Token::ARROW || parenthesized_function_) { |
| 2543 classifier->Accumulate( |
| 2544 expr_classifier, |
| 2545 ExpressionClassifier::ArrowFormalParametersProduction | |
| 2546 ExpressionClassifier::FormalParametersProduction); |
| 2547 } else { |
| 2548 lhs_part = expr_classifier.AssignmentTarget(); |
| 2549 } |
| 2425 } | 2550 } |
| 2426 break; | 2551 break; |
| 2427 | 2552 |
| 2428 case Token::CLASS: { | 2553 case Token::CLASS: { |
| 2429 BindingPatternUnexpectedToken(classifier); | 2554 BindingPatternUnexpectedToken(classifier); |
| 2430 Consume(Token::CLASS); | 2555 Consume(Token::CLASS); |
| 2431 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2556 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2432 ReportMessage(MessageTemplate::kSloppyLexical); | 2557 ReportMessage(MessageTemplate::kSloppyLexical); |
| 2433 *ok = false; | 2558 *ok = false; |
| 2434 break; | 2559 break; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2450 | 2575 |
| 2451 case Token::TEMPLATE_SPAN: | 2576 case Token::TEMPLATE_SPAN: |
| 2452 case Token::TEMPLATE_TAIL: | 2577 case Token::TEMPLATE_TAIL: |
| 2453 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2578 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
| 2454 classifier, CHECK_OK); | 2579 classifier, CHECK_OK); |
| 2455 break; | 2580 break; |
| 2456 | 2581 |
| 2457 case Token::MOD: | 2582 case Token::MOD: |
| 2458 if (allow_natives() || extension_ != NULL) { | 2583 if (allow_natives() || extension_ != NULL) { |
| 2459 result = this->ParseV8Intrinsic(CHECK_OK); | 2584 result = this->ParseV8Intrinsic(CHECK_OK); |
| 2585 lhs_part = ExpressionClassifier::TARGET_CALL; |
| 2460 break; | 2586 break; |
| 2461 } | 2587 } |
| 2462 // If we're not allowing special syntax we fall-through to the | 2588 // If we're not allowing special syntax we fall-through to the |
| 2463 // default case. | 2589 // default case. |
| 2464 | 2590 |
| 2465 default: { | 2591 default: { |
| 2466 Next(); | 2592 Next(); |
| 2467 ReportUnexpectedToken(token); | 2593 ReportUnexpectedToken(token); |
| 2468 *ok = false; | 2594 *ok = false; |
| 2469 } | 2595 } |
| 2470 } | 2596 } |
| 2471 | 2597 |
| 2598 if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) { |
| 2599 classifier->AppendAssignmentTarget(lhs_part); |
| 2600 } |
| 2601 |
| 2472 return result; | 2602 return result; |
| 2473 } | 2603 } |
| 2474 | 2604 |
| 2475 | 2605 |
| 2476 template <class Traits> | 2606 template <class Traits> |
| 2477 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2607 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2478 bool accept_IN, bool* ok) { | 2608 bool accept_IN, bool* ok) { |
| 2479 ExpressionClassifier classifier; | 2609 ExpressionClassifier classifier; |
| 2480 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2610 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 2481 ValidateExpression(&classifier, CHECK_OK); | 2611 ValidateExpression(&classifier, CHECK_OK); |
| 2482 return result; | 2612 return result; |
| 2483 } | 2613 } |
| 2484 | 2614 |
| 2485 | 2615 |
| 2486 // Precedence = 1 | 2616 // Precedence = 1 |
| 2487 template <class Traits> | 2617 template <class Traits> |
| 2488 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2618 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2489 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2619 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2490 // Expression :: | 2620 // Expression :: |
| 2491 // AssignmentExpression | 2621 // AssignmentExpression |
| 2492 // Expression ',' AssignmentExpression | 2622 // Expression ',' AssignmentExpression |
| 2493 | 2623 |
| 2494 ExpressionClassifier binding_classifier; | 2624 ExpressionClassifier expr_classifier; |
| 2495 ExpressionT result = | 2625 ExpressionT result = |
| 2496 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2626 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK); |
| 2497 classifier->Accumulate(binding_classifier, | 2627 classifier->AccumulateValidSimpleAssignmentTarget(expr_classifier); |
| 2498 ExpressionClassifier::AllProductions); | 2628 classifier->Accumulate(expr_classifier, |
| 2629 expr_classifier.is_destructuring_assignment() |
| 2630 ? ExpressionClassifier::PatternProductions |
| 2631 : ExpressionClassifier::AllProductions); |
| 2499 while (peek() == Token::COMMA) { | 2632 while (peek() == Token::COMMA) { |
| 2500 Expect(Token::COMMA, CHECK_OK); | 2633 Expect(Token::COMMA, CHECK_OK); |
| 2501 int pos = position(); | 2634 int pos = position(); |
| 2502 ExpressionT right = this->ParseAssignmentExpression( | 2635 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 2503 accept_IN, &binding_classifier, CHECK_OK); | 2636 ExpressionClassifier expr_classifier; |
| 2504 classifier->Accumulate(binding_classifier, | 2637 ExpressionT right = |
| 2505 ExpressionClassifier::AllProductions); | 2638 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK); |
| 2639 classifier->Accumulate(expr_classifier, |
| 2640 expr_classifier.is_destructuring_assignment() |
| 2641 ? ExpressionClassifier::PatternProductions |
| 2642 : ExpressionClassifier::AllProductions); |
| 2643 |
| 2644 |
| 2506 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2645 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2507 } | 2646 } |
| 2508 return result; | 2647 return result; |
| 2509 } | 2648 } |
| 2510 | 2649 |
| 2511 | 2650 |
| 2512 template <class Traits> | 2651 template <class Traits> |
| 2513 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2652 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| 2514 ExpressionClassifier* classifier, bool* ok) { | 2653 ExpressionClassifier* classifier, bool* ok) { |
| 2515 // ArrayLiteral :: | 2654 // ArrayLiteral :: |
| 2516 // '[' Expression? (',' Expression?)* ']' | 2655 // '[' Expression? (',' Expression?)* ']' |
| 2517 | 2656 |
| 2518 int pos = peek_position(); | 2657 int pos = peek_position(); |
| 2519 typename Traits::Type::ExpressionList values = | 2658 typename Traits::Type::ExpressionList values = |
| 2520 this->NewExpressionList(4, zone_); | 2659 this->NewExpressionList(4, zone_); |
| 2521 Expect(Token::LBRACK, CHECK_OK); | 2660 Expect(Token::LBRACK, CHECK_OK); |
| 2522 while (peek() != Token::RBRACK) { | 2661 while (peek() != Token::RBRACK) { |
| 2523 bool seen_spread = false; | 2662 bool seen_spread = false; |
| 2524 ExpressionT elem = this->EmptyExpression(); | 2663 ExpressionT elem = this->EmptyExpression(); |
| 2664 ExpressionClassifier element_classifier; |
| 2525 if (peek() == Token::COMMA) { | 2665 if (peek() == Token::COMMA) { |
| 2526 if (is_strong(language_mode())) { | 2666 if (is_strong(language_mode())) { |
| 2527 ReportMessageAt(scanner()->peek_location(), | 2667 ReportMessageAt(scanner()->peek_location(), |
| 2528 MessageTemplate::kStrongEllision); | 2668 MessageTemplate::kStrongEllision); |
| 2529 *ok = false; | 2669 *ok = false; |
| 2530 return this->EmptyExpression(); | 2670 return this->EmptyExpression(); |
| 2531 } | 2671 } |
| 2532 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2672 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2533 } else if (peek() == Token::ELLIPSIS) { | 2673 } else if (peek() == Token::ELLIPSIS) { |
| 2534 if (!allow_harmony_spread_arrays()) { | 2674 if (!allow_harmony_spread_arrays()) { |
| 2535 ExpressionUnexpectedToken(classifier); | 2675 ExpressionUnexpectedToken(classifier); |
| 2536 } | 2676 } |
| 2537 int start_pos = peek_position(); | 2677 int start_pos = peek_position(); |
| 2538 Consume(Token::ELLIPSIS); | 2678 Consume(Token::ELLIPSIS); |
| 2539 ExpressionT argument = | 2679 ExpressionT argument = |
| 2540 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2680 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2541 elem = factory()->NewSpread(argument, start_pos); | 2681 elem = factory()->NewSpread(argument, start_pos); |
| 2542 seen_spread = true; | 2682 seen_spread = true; |
| 2543 } else { | 2683 } else { |
| 2544 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2684 int start_pos = peek_position(); |
| 2685 elem = |
| 2686 this->ParseAssignmentExpression(true, &element_classifier, CHECK_OK); |
| 2687 if (!element_classifier.IsValidSimpleAssignmentTarget() && |
| 2688 !element_classifier.IsPatternAssignmentElement()) { |
| 2689 Scanner::Location location(start_pos, scanner()->location().end_pos); |
| 2690 classifier->RecordAssignmentPatternError( |
| 2691 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); |
| 2692 } |
| 2693 classifier->Accumulate(element_classifier); |
| 2545 } | 2694 } |
| 2546 values->Add(elem, zone_); | 2695 values->Add(elem, zone_); |
| 2547 if (peek() != Token::RBRACK) { | 2696 if (peek() != Token::RBRACK) { |
| 2548 if (seen_spread) { | 2697 if (seen_spread) { |
| 2549 BindingPatternUnexpectedToken(classifier); | 2698 BindingPatternUnexpectedToken(classifier); |
| 2550 } | 2699 } |
| 2551 Expect(Token::COMMA, CHECK_OK); | 2700 Expect(Token::COMMA, CHECK_OK); |
| 2552 } | 2701 } |
| 2553 } | 2702 } |
| 2554 Expect(Token::RBRACK, CHECK_OK); | 2703 Expect(Token::RBRACK, CHECK_OK); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 2777 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 2629 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 2778 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 2630 ExpressionClassifier* classifier, bool* ok) { | 2779 ExpressionClassifier* classifier, bool* ok) { |
| 2631 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 2780 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| 2632 ExpressionT value = this->EmptyExpression(); | 2781 ExpressionT value = this->EmptyExpression(); |
| 2633 IdentifierT name = this->EmptyIdentifier(); | 2782 IdentifierT name = this->EmptyIdentifier(); |
| 2634 bool is_get = false; | 2783 bool is_get = false; |
| 2635 bool is_set = false; | 2784 bool is_set = false; |
| 2636 bool name_is_static = false; | 2785 bool name_is_static = false; |
| 2637 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2786 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
| 2638 | 2787 // Classify destructuring assignment target for ObjectAssignmentPattern |
| 2788 ExpressionClassifier property_classifier; |
| 2639 Token::Value name_token = peek(); | 2789 Token::Value name_token = peek(); |
| 2640 int next_beg_pos = scanner()->peek_location().beg_pos; | 2790 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2641 int next_end_pos = scanner()->peek_location().end_pos; | 2791 int next_end_pos = scanner()->peek_location().end_pos; |
| 2792 int value_start = next_beg_pos; |
| 2793 int value_end = next_end_pos; |
| 2642 ExpressionT name_expression = ParsePropertyName( | 2794 ExpressionT name_expression = ParsePropertyName( |
| 2643 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, | 2795 &name, &is_get, &is_set, &name_is_static, is_computed_name, |
| 2644 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2796 &property_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2645 | 2797 |
| 2646 if (fni_ != nullptr && !*is_computed_name) { | 2798 if (fni_ != nullptr && !*is_computed_name) { |
| 2647 this->PushLiteralName(fni_, name); | 2799 this->PushLiteralName(fni_, name); |
| 2648 } | 2800 } |
| 2649 | 2801 |
| 2650 if (!in_class && !is_generator && peek() == Token::COLON) { | 2802 if (!in_class && !is_generator && peek() == Token::COLON) { |
| 2651 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2803 // PropertyDefinition : PropertyName ':' AssignmentExpression |
| 2652 if (!*is_computed_name) { | 2804 if (!*is_computed_name) { |
| 2653 checker->CheckProperty(name_token, kValueProperty, is_static, | 2805 checker->CheckProperty(name_token, kValueProperty, is_static, |
| 2654 is_generator, | 2806 is_generator, |
| 2655 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2807 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2656 } | 2808 } |
| 2657 Consume(Token::COLON); | 2809 Consume(Token::COLON); |
| 2810 property_classifier = ExpressionClassifier(); |
| 2811 value_start = peek_position(); |
| 2658 value = this->ParseAssignmentExpression( | 2812 value = this->ParseAssignmentExpression( |
| 2659 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2813 true, &property_classifier, |
| 2660 | 2814 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2815 value_end = scanner()->location().end_pos; |
| 2661 } else if (is_generator || | 2816 } else if (is_generator || |
| 2662 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2817 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
| 2663 // Concise Method | 2818 // Concise Method |
| 2819 property_classifier.ReportInvalidSimpleAssignmentTarget(); |
| 2664 if (!*is_computed_name) { | 2820 if (!*is_computed_name) { |
| 2665 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2821 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 2666 is_generator, | 2822 is_generator, |
| 2667 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2823 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2668 } | 2824 } |
| 2669 | 2825 |
| 2670 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 2826 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
| 2671 : FunctionKind::kConciseMethod; | 2827 : FunctionKind::kConciseMethod; |
| 2672 | 2828 |
| 2673 if (in_class && !is_static && this->IsConstructor(name)) { | 2829 if (in_class && !is_static && this->IsConstructor(name)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2684 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2840 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 2685 FunctionLiteral::NORMAL_ARITY, | 2841 FunctionLiteral::NORMAL_ARITY, |
| 2686 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2842 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2687 | 2843 |
| 2688 return factory()->NewObjectLiteralProperty(name_expression, value, | 2844 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 2689 ObjectLiteralProperty::COMPUTED, | 2845 ObjectLiteralProperty::COMPUTED, |
| 2690 is_static, *is_computed_name); | 2846 is_static, *is_computed_name); |
| 2691 | 2847 |
| 2692 } else if (in_class && name_is_static && !is_static) { | 2848 } else if (in_class && name_is_static && !is_static) { |
| 2693 // static MethodDefinition | 2849 // static MethodDefinition |
| 2850 property_classifier.ReportInvalidSimpleAssignmentTarget(); |
| 2694 return ParsePropertyDefinition(checker, true, has_extends, true, | 2851 return ParsePropertyDefinition(checker, true, has_extends, true, |
| 2695 is_computed_name, nullptr, classifier, ok); | 2852 is_computed_name, nullptr, classifier, ok); |
| 2696 } else if (is_get || is_set) { | 2853 } else if (is_get || is_set) { |
| 2697 // Accessor | 2854 // Accessor |
| 2855 property_classifier.ReportInvalidSimpleAssignmentTarget(); |
| 2698 name = this->EmptyIdentifier(); | 2856 name = this->EmptyIdentifier(); |
| 2699 bool dont_care = false; | 2857 bool dont_care = false; |
| 2700 name_token = peek(); | 2858 name_token = peek(); |
| 2701 | 2859 |
| 2702 name_expression = ParsePropertyName( | 2860 name_expression = ParsePropertyName( |
| 2703 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, | 2861 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 2704 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2862 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2705 | 2863 |
| 2706 if (!*is_computed_name) { | 2864 if (!*is_computed_name) { |
| 2707 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2865 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2719 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2877 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2720 | 2878 |
| 2721 // Make sure the name expression is a string since we need a Name for | 2879 // Make sure the name expression is a string since we need a Name for |
| 2722 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 2880 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
| 2723 // statically we can skip the extra runtime check. | 2881 // statically we can skip the extra runtime check. |
| 2724 if (!*is_computed_name) { | 2882 if (!*is_computed_name) { |
| 2725 name_expression = | 2883 name_expression = |
| 2726 factory()->NewStringLiteral(name, name_expression->position()); | 2884 factory()->NewStringLiteral(name, name_expression->position()); |
| 2727 } | 2885 } |
| 2728 | 2886 |
| 2887 value_end = scanner()->location().end_pos; |
| 2888 Scanner::Location location(value_start, value_end); |
| 2889 classifier->RecordAssignmentPatternError( |
| 2890 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); |
| 2891 |
| 2729 return factory()->NewObjectLiteralProperty( | 2892 return factory()->NewObjectLiteralProperty( |
| 2730 name_expression, value, | 2893 name_expression, value, |
| 2731 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 2894 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
| 2732 is_static, *is_computed_name); | 2895 is_static, *is_computed_name); |
| 2733 | 2896 |
| 2734 } else if (!in_class && allow_harmony_object_literals_ && | 2897 } else if (!in_class && allow_harmony_object_literals_ && |
| 2735 Token::IsIdentifier(name_token, language_mode(), | 2898 Token::IsIdentifier(name_token, language_mode(), |
| 2736 this->is_generator())) { | 2899 this->is_generator())) { |
| 2737 DCHECK(!*is_computed_name); | 2900 DCHECK(!*is_computed_name); |
| 2738 DCHECK(!is_static); | 2901 DCHECK(!is_static); |
| 2739 | 2902 |
| 2740 ExpressionT lhs = this->ExpressionFromIdentifier( | 2903 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 2741 name, next_beg_pos, next_end_pos, scope_, factory()); | 2904 name, next_beg_pos, next_end_pos, scope_, factory()); |
| 2742 if (peek() == Token::ASSIGN) { | 2905 if (peek() == Token::ASSIGN) { |
| 2743 this->ExpressionUnexpectedToken(classifier); | 2906 this->ExpressionUnexpectedToken(classifier); |
| 2744 Consume(Token::ASSIGN); | 2907 Consume(Token::ASSIGN); |
| 2745 ExpressionClassifier rhs_classifier; | 2908 ExpressionClassifier rhs_classifier; |
| 2746 ExpressionT rhs = this->ParseAssignmentExpression( | 2909 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2747 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2910 true, true, &rhs_classifier, |
| 2911 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2748 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); | 2912 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); |
| 2749 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2913 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2750 RelocInfo::kNoPosition); | 2914 RelocInfo::kNoPosition); |
| 2751 } else { | 2915 } else { |
| 2752 value = lhs; | 2916 value = lhs; |
| 2753 } | 2917 } |
| 2754 return factory()->NewObjectLiteralProperty( | 2918 return factory()->NewObjectLiteralProperty( |
| 2755 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); | 2919 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); |
| 2756 | 2920 |
| 2757 } else { | 2921 } else { |
| 2758 Token::Value next = Next(); | 2922 Token::Value next = Next(); |
| 2759 ReportUnexpectedToken(next); | 2923 ReportUnexpectedToken(next); |
| 2760 *ok = false; | 2924 *ok = false; |
| 2761 return this->EmptyObjectLiteralProperty(); | 2925 return this->EmptyObjectLiteralProperty(); |
| 2762 } | 2926 } |
| 2763 | 2927 |
| 2928 if (!property_classifier.IsValidSimpleAssignmentTarget() && |
| 2929 !property_classifier.IsPatternAssignmentElement()) { |
| 2930 Scanner::Location location(value_start, value_end); |
| 2931 classifier->RecordAssignmentPatternError( |
| 2932 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); |
| 2933 } |
| 2934 classifier->Accumulate(property_classifier); |
| 2935 |
| 2764 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2936 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
| 2765 *is_computed_name); | 2937 *is_computed_name); |
| 2766 } | 2938 } |
| 2767 | 2939 |
| 2768 | 2940 |
| 2769 template <class Traits> | 2941 template <class Traits> |
| 2770 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2942 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| 2771 ExpressionClassifier* classifier, bool* ok) { | 2943 ExpressionClassifier* classifier, bool* ok) { |
| 2772 // ObjectLiteral :: | 2944 // ObjectLiteral :: |
| 2773 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2945 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2896 // the parser and preparser | 3068 // the parser and preparser |
| 2897 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3069 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2898 } | 3070 } |
| 2899 | 3071 |
| 2900 return result; | 3072 return result; |
| 2901 } | 3073 } |
| 2902 | 3074 |
| 2903 // Precedence = 2 | 3075 // Precedence = 2 |
| 2904 template <class Traits> | 3076 template <class Traits> |
| 2905 typename ParserBase<Traits>::ExpressionT | 3077 typename ParserBase<Traits>::ExpressionT |
| 2906 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3078 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool pattern_lhs, |
| 2907 ExpressionClassifier* classifier, | 3079 ExpressionClassifier* classifier, |
| 2908 bool* ok) { | 3080 bool* ok) { |
| 2909 // AssignmentExpression :: | 3081 // AssignmentExpression :: |
| 2910 // ConditionalExpression | 3082 // ConditionalExpression |
| 2911 // ArrowFunction | 3083 // ArrowFunction |
| 2912 // YieldExpression | 3084 // YieldExpression |
| 2913 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3085 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2914 | 3086 |
| 2915 Scanner::Location lhs_location = scanner()->peek_location(); | 3087 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2916 | 3088 |
| 2917 if (peek() == Token::YIELD && is_generator()) { | 3089 if (peek() == Token::YIELD && is_generator()) { |
| 2918 return this->ParseYieldExpression(classifier, ok); | 3090 return this->ParseYieldExpression(classifier, ok); |
| 2919 } | 3091 } |
| 2920 | 3092 |
| 3093 bool maybe_assignment_pattern = |
| 3094 allow_harmony_destructuring() && |
| 3095 classifier->is_valid_assignment_pattern() && |
| 3096 (peek() == Token::LBRACK || peek() == Token::LBRACE); |
| 3097 |
| 2921 if (fni_ != NULL) fni_->Enter(); | 3098 if (fni_ != NULL) fni_->Enter(); |
| 2922 ParserBase<Traits>::Checkpoint checkpoint(this); | 3099 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2923 ExpressionClassifier arrow_formals_classifier; | 3100 ExpressionClassifier arrow_formals_classifier; |
| 2924 if (peek() != Token::LPAREN) { | 3101 if (peek() != Token::LPAREN) { |
| 2925 // The expression we are going to read is not a parenthesized arrow function | 3102 // The expression we are going to read is not a parenthesized arrow function |
| 2926 // formal parameter list. | 3103 // formal parameter list. |
| 2927 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 3104 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
| 2928 } | 3105 } |
| 3106 |
| 2929 ExpressionT expression = this->ParseConditionalExpression( | 3107 ExpressionT expression = this->ParseConditionalExpression( |
| 2930 accept_IN, &arrow_formals_classifier, CHECK_OK); | 3108 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 3109 |
| 3110 if (!arrow_formals_classifier.is_valid_assignment_pattern()) { |
| 3111 if (maybe_assignment_pattern && peek() == Token::ASSIGN) { |
| 3112 // ObjectAssignmentPattern or ArrayAssignmentPattern contains an error |
| 3113 ReportClassifierError( |
| 3114 arrow_formals_classifier.assignment_pattern_error()); |
| 3115 *ok = false; |
| 3116 return this->EmptyExpression(); |
| 3117 } |
| 3118 } |
| 3119 |
| 2931 classifier->Accumulate(arrow_formals_classifier); | 3120 classifier->Accumulate(arrow_formals_classifier); |
| 2932 | 3121 |
| 2933 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 3122 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2934 checkpoint.Restore(); | 3123 checkpoint.Restore(); |
| 2935 BindingPatternUnexpectedToken(classifier); | 3124 BindingPatternUnexpectedToken(classifier); |
| 3125 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY); |
| 2936 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 3126 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| 2937 CHECK_OK); | 3127 CHECK_OK); |
| 2938 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 3128 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2939 bool has_rest = false; | 3129 bool has_rest = false; |
| 2940 Scope* scope = | 3130 Scope* scope = |
| 2941 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 3131 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2942 scope->set_start_position(lhs_location.beg_pos); | 3132 scope->set_start_position(lhs_location.beg_pos); |
| 2943 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 3133 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2944 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, | 3134 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, |
| 2945 &duplicate_loc, CHECK_OK); | 3135 &duplicate_loc, CHECK_OK); |
| 2946 if (duplicate_loc.IsValid()) { | 3136 if (duplicate_loc.IsValid()) { |
| 2947 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3137 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 2948 duplicate_loc); | 3138 duplicate_loc); |
| 2949 } | 3139 } |
| 2950 expression = this->ParseArrowFunctionLiteral( | 3140 expression = this->ParseArrowFunctionLiteral( |
| 2951 scope, has_rest, arrow_formals_classifier, CHECK_OK); | 3141 scope, has_rest, arrow_formals_classifier, CHECK_OK); |
| 2952 return expression; | 3142 return expression; |
| 2953 } | 3143 } |
| 2954 | 3144 |
| 2955 // "expression" was not itself an arrow function parameter list, but it might | 3145 // "expression" was not itself an arrow function parameter list, but it might |
| 2956 // form part of one. Propagate speculative formal parameter error locations. | 3146 // form part of one. Propagate speculative formal parameter error locations. |
| 2957 classifier->Accumulate(arrow_formals_classifier, | 3147 classifier->Accumulate(arrow_formals_classifier, |
| 2958 ExpressionClassifier::FormalParametersProduction); | 3148 ExpressionClassifier::FormalParametersProduction); |
| 2959 | 3149 |
| 3150 bool valid_destructuring_assignment_target = |
| 3151 arrow_formals_classifier.IsValidSimpleAssignmentTarget(); |
| 3152 if (valid_destructuring_assignment_target) { |
| 3153 classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier); |
| 3154 } else if (!maybe_assignment_pattern || |
| 3155 !arrow_formals_classifier.is_valid_assignment_pattern()) { |
| 3156 // Potentially a bad DestructuringAssignmentTarget |
| 3157 classifier->RecordAssignmentPatternError( |
| 3158 Scanner::Location(lhs_location.beg_pos, scanner()->location().end_pos), |
| 3159 MessageTemplate::kInvalidDestructuringAssignmentTarget); |
| 3160 } |
| 3161 |
| 3162 if (maybe_assignment_pattern) { |
| 3163 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN); |
| 3164 } |
| 3165 |
| 3166 if (pattern_lhs && peek() != Token::ASSIGN) { |
| 3167 // If LHS was an AssignmentPattern and there is no additional assignment, |
| 3168 // ensure that the RHS is a valid expression |
| 3169 ValidateExpression(classifier, CHECK_OK); |
| 3170 return expression; |
| 3171 } |
| 3172 |
| 2960 if (!Token::IsAssignmentOp(peek())) { | 3173 if (!Token::IsAssignmentOp(peek())) { |
| 2961 if (fni_ != NULL) fni_->Leave(); | 3174 if (fni_ != NULL) fni_->Leave(); |
| 2962 // Parsed conditional expression only (no assignment). | 3175 // Parsed conditional expression only (no assignment). |
| 2963 return expression; | 3176 return expression; |
| 2964 } | 3177 } |
| 2965 | 3178 |
| 2966 if (!allow_harmony_destructuring()) { | 3179 if (!allow_harmony_destructuring()) { |
| 2967 BindingPatternUnexpectedToken(classifier); | 3180 BindingPatternUnexpectedToken(classifier); |
| 2968 } | 3181 } |
| 2969 | 3182 |
| 2970 expression = this->CheckAndRewriteReferenceExpression( | 3183 if (!maybe_assignment_pattern || peek() != Token::ASSIGN) { |
| 2971 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, | 3184 expression = this->CheckAndRewriteReferenceExpression( |
| 2972 CHECK_OK); | 3185 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, |
| 3186 CHECK_OK); |
| 3187 } |
| 3188 |
| 2973 expression = this->MarkExpressionAsAssigned(expression); | 3189 expression = this->MarkExpressionAsAssigned(expression); |
| 2974 | 3190 |
| 2975 Token::Value op = Next(); // Get assignment operator. | 3191 Token::Value op = Next(); // Get assignment operator. |
| 2976 if (op != Token::ASSIGN) { | 3192 if (op != Token::ASSIGN) { |
| 2977 classifier->RecordBindingPatternError(scanner()->location(), | 3193 classifier->RecordBindingPatternError(scanner()->location(), |
| 2978 MessageTemplate::kUnexpectedToken, | 3194 MessageTemplate::kUnexpectedToken, |
| 2979 Token::String(op)); | 3195 Token::String(op)); |
| 3196 } else { |
| 3197 classifier->set_assigned(); |
| 2980 } | 3198 } |
| 2981 int pos = position(); | 3199 int pos = position(); |
| 2982 | 3200 |
| 2983 ExpressionClassifier rhs_classifier; | 3201 ExpressionClassifier rhs_classifier; |
| 2984 ExpressionT right = | 3202 ExpressionT right = this->ParseAssignmentExpression( |
| 2985 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3203 accept_IN, maybe_assignment_pattern, &rhs_classifier, CHECK_OK); |
| 2986 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); | 3204 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); |
| 2987 | 3205 |
| 2988 // TODO(1231235): We try to estimate the set of properties set by | 3206 // TODO(1231235): We try to estimate the set of properties set by |
| 2989 // constructors. We define a new property whenever there is an | 3207 // constructors. We define a new property whenever there is an |
| 2990 // assignment to a property of 'this'. We should probably only add | 3208 // assignment to a property of 'this'. We should probably only add |
| 2991 // properties if we haven't seen them before. Otherwise we'll | 3209 // properties if we haven't seen them before. Otherwise we'll |
| 2992 // probably overestimate the number of properties. | 3210 // probably overestimate the number of properties. |
| 2993 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 3211 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 2994 function_state_->AddProperty(); | 3212 function_state_->AddProperty(); |
| 2995 } | 3213 } |
| 2996 | 3214 |
| 2997 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 3215 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
| 2998 | 3216 |
| 2999 if (fni_ != NULL) { | 3217 if (fni_ != NULL) { |
| 3000 // Check if the right hand side is a call to avoid inferring a | 3218 // Check if the right hand side is a call to avoid inferring a |
| 3001 // name if we're dealing with "a = function(){...}();"-like | 3219 // name if we're dealing with "a = function(){...}();"-like |
| 3002 // expression. | 3220 // expression. |
| 3003 if ((op == Token::INIT_VAR | 3221 if ((op == Token::INIT_VAR |
| 3004 || op == Token::INIT_CONST_LEGACY | 3222 || op == Token::INIT_CONST_LEGACY |
| 3005 || op == Token::ASSIGN) | 3223 || op == Token::ASSIGN) |
| 3006 && (!right->IsCall() && !right->IsCallNew())) { | 3224 && (!right->IsCall() && !right->IsCallNew())) { |
| 3007 fni_->Infer(); | 3225 fni_->Infer(); |
| 3008 } else { | 3226 } else { |
| 3009 fni_->RemoveLastFunction(); | 3227 fni_->RemoveLastFunction(); |
| 3010 } | 3228 } |
| 3011 fni_->Leave(); | 3229 fni_->Leave(); |
| 3012 } | 3230 } |
| 3013 | 3231 |
| 3014 return factory()->NewAssignment(op, expression, right, pos); | 3232 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3233 return this->CheckDestructuringAssignment(result, classifier, CHECK_OK); |
| 3015 } | 3234 } |
| 3016 | 3235 |
| 3017 template <class Traits> | 3236 template <class Traits> |
| 3018 typename ParserBase<Traits>::ExpressionT | 3237 typename ParserBase<Traits>::ExpressionT |
| 3019 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3238 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 3020 bool* ok) { | 3239 bool* ok) { |
| 3021 // YieldExpression :: | 3240 // YieldExpression :: |
| 3022 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3241 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 3023 int pos = peek_position(); | 3242 int pos = peek_position(); |
| 3024 Expect(Token::YIELD, CHECK_OK); | 3243 Expect(Token::YIELD, CHECK_OK); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3071 // ConditionalExpression :: | 3290 // ConditionalExpression :: |
| 3072 // LogicalOrExpression | 3291 // LogicalOrExpression |
| 3073 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3292 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 3074 | 3293 |
| 3075 int pos = peek_position(); | 3294 int pos = peek_position(); |
| 3076 // We start using the binary expression parser for prec >= 4 only! | 3295 // We start using the binary expression parser for prec >= 4 only! |
| 3077 ExpressionT expression = | 3296 ExpressionT expression = |
| 3078 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 3297 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
| 3079 if (peek() != Token::CONDITIONAL) return expression; | 3298 if (peek() != Token::CONDITIONAL) return expression; |
| 3080 BindingPatternUnexpectedToken(classifier); | 3299 BindingPatternUnexpectedToken(classifier); |
| 3300 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3081 Consume(Token::CONDITIONAL); | 3301 Consume(Token::CONDITIONAL); |
| 3082 // In parsing the first assignment expression in conditional | 3302 // In parsing the first assignment expression in conditional |
| 3083 // expressions we always accept the 'in' keyword; see ECMA-262, | 3303 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3084 // section 11.12, page 58. | 3304 // section 11.12, page 58. |
| 3085 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 3305 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 3086 Expect(Token::COLON, CHECK_OK); | 3306 Expect(Token::COLON, CHECK_OK); |
| 3087 ExpressionT right = | 3307 ExpressionT right = |
| 3088 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 3308 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
| 3089 return factory()->NewConditional(expression, left, right, pos); | 3309 return factory()->NewConditional(expression, left, right, pos); |
| 3090 } | 3310 } |
| 3091 | 3311 |
| 3092 | 3312 |
| 3093 // Precedence >= 4 | 3313 // Precedence >= 4 |
| 3094 template <class Traits> | 3314 template <class Traits> |
| 3095 typename ParserBase<Traits>::ExpressionT | 3315 typename ParserBase<Traits>::ExpressionT |
| 3096 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 3316 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 3097 ExpressionClassifier* classifier, | 3317 ExpressionClassifier* classifier, |
| 3098 bool* ok) { | 3318 bool* ok) { |
| 3099 DCHECK(prec >= 4); | 3319 DCHECK(prec >= 4); |
| 3100 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 3320 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 3101 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3321 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3102 // prec1 >= 4 | 3322 // prec1 >= 4 |
| 3103 while (Precedence(peek(), accept_IN) == prec1) { | 3323 while (Precedence(peek(), accept_IN) == prec1) { |
| 3104 BindingPatternUnexpectedToken(classifier); | 3324 BindingPatternUnexpectedToken(classifier); |
| 3325 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3105 Token::Value op = Next(); | 3326 Token::Value op = Next(); |
| 3106 Scanner::Location op_location = scanner()->location(); | 3327 Scanner::Location op_location = scanner()->location(); |
| 3107 int pos = position(); | 3328 int pos = position(); |
| 3108 ExpressionT y = | 3329 ExpressionT y = |
| 3109 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); | 3330 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
| 3110 | 3331 |
| 3111 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 3332 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 3112 factory())) { | 3333 factory())) { |
| 3113 continue; | 3334 continue; |
| 3114 } | 3335 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3157 // '++' UnaryExpression | 3378 // '++' UnaryExpression |
| 3158 // '--' UnaryExpression | 3379 // '--' UnaryExpression |
| 3159 // '+' UnaryExpression | 3380 // '+' UnaryExpression |
| 3160 // '-' UnaryExpression | 3381 // '-' UnaryExpression |
| 3161 // '~' UnaryExpression | 3382 // '~' UnaryExpression |
| 3162 // '!' UnaryExpression | 3383 // '!' UnaryExpression |
| 3163 | 3384 |
| 3164 Token::Value op = peek(); | 3385 Token::Value op = peek(); |
| 3165 if (Token::IsUnaryOp(op)) { | 3386 if (Token::IsUnaryOp(op)) { |
| 3166 BindingPatternUnexpectedToken(classifier); | 3387 BindingPatternUnexpectedToken(classifier); |
| 3167 | 3388 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3168 op = Next(); | 3389 op = Next(); |
| 3169 int pos = position(); | 3390 int pos = position(); |
| 3170 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 3391 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 3171 | 3392 |
| 3172 if (op == Token::DELETE && is_strict(language_mode())) { | 3393 if (op == Token::DELETE && is_strict(language_mode())) { |
| 3173 if (is_strong(language_mode())) { | 3394 if (is_strong(language_mode())) { |
| 3174 ReportMessage(MessageTemplate::kStrongDelete); | 3395 ReportMessage(MessageTemplate::kStrongDelete); |
| 3175 *ok = false; | 3396 *ok = false; |
| 3176 return this->EmptyExpression(); | 3397 return this->EmptyExpression(); |
| 3177 } else if (this->IsIdentifier(expression)) { | 3398 } else if (this->IsIdentifier(expression)) { |
| 3178 // "delete identifier" is a syntax error in strict mode. | 3399 // "delete identifier" is a syntax error in strict mode. |
| 3179 ReportMessage(MessageTemplate::kStrictDelete); | 3400 ReportMessage(MessageTemplate::kStrictDelete); |
| 3180 *ok = false; | 3401 *ok = false; |
| 3181 return this->EmptyExpression(); | 3402 return this->EmptyExpression(); |
| 3182 } | 3403 } |
| 3183 } | 3404 } |
| 3184 | 3405 |
| 3185 // Allow Traits do rewrite the expression. | 3406 // Allow Traits do rewrite the expression. |
| 3186 return this->BuildUnaryExpression(expression, op, pos, factory()); | 3407 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 3187 } else if (Token::IsCountOp(op)) { | 3408 } else if (Token::IsCountOp(op)) { |
| 3188 BindingPatternUnexpectedToken(classifier); | 3409 BindingPatternUnexpectedToken(classifier); |
| 3410 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3189 op = Next(); | 3411 op = Next(); |
| 3190 Scanner::Location lhs_location = scanner()->peek_location(); | 3412 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3191 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 3413 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 3192 expression = this->CheckAndRewriteReferenceExpression( | 3414 expression = this->CheckAndRewriteReferenceExpression( |
| 3193 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, | 3415 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, |
| 3194 CHECK_OK); | 3416 CHECK_OK); |
| 3195 this->MarkExpressionAsAssigned(expression); | 3417 this->MarkExpressionAsAssigned(expression); |
| 3196 | 3418 |
| 3197 return factory()->NewCountOperation(op, | 3419 return factory()->NewCountOperation(op, |
| 3198 true /* prefix */, | 3420 true /* prefix */, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3211 bool* ok) { | 3433 bool* ok) { |
| 3212 // PostfixExpression :: | 3434 // PostfixExpression :: |
| 3213 // LeftHandSideExpression ('++' | '--')? | 3435 // LeftHandSideExpression ('++' | '--')? |
| 3214 | 3436 |
| 3215 Scanner::Location lhs_location = scanner()->peek_location(); | 3437 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3216 ExpressionT expression = | 3438 ExpressionT expression = |
| 3217 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3439 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 3218 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3440 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 3219 Token::IsCountOp(peek())) { | 3441 Token::IsCountOp(peek())) { |
| 3220 BindingPatternUnexpectedToken(classifier); | 3442 BindingPatternUnexpectedToken(classifier); |
| 3221 | 3443 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3222 expression = this->CheckAndRewriteReferenceExpression( | 3444 expression = this->CheckAndRewriteReferenceExpression( |
| 3223 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, | 3445 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, |
| 3224 CHECK_OK); | 3446 CHECK_OK); |
| 3225 expression = this->MarkExpressionAsAssigned(expression); | 3447 expression = this->MarkExpressionAsAssigned(expression); |
| 3226 | 3448 |
| 3227 Token::Value next = Next(); | 3449 Token::Value next = Next(); |
| 3228 expression = | 3450 expression = |
| 3229 factory()->NewCountOperation(next, | 3451 factory()->NewCountOperation(next, |
| 3230 false /* postfix */, | 3452 false /* postfix */, |
| 3231 expression, | 3453 expression, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3242 // LeftHandSideExpression :: | 3464 // LeftHandSideExpression :: |
| 3243 // (NewExpression | MemberExpression) ... | 3465 // (NewExpression | MemberExpression) ... |
| 3244 | 3466 |
| 3245 ExpressionT result = | 3467 ExpressionT result = |
| 3246 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3468 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3247 | 3469 |
| 3248 while (true) { | 3470 while (true) { |
| 3249 switch (peek()) { | 3471 switch (peek()) { |
| 3250 case Token::LBRACK: { | 3472 case Token::LBRACK: { |
| 3251 BindingPatternUnexpectedToken(classifier); | 3473 BindingPatternUnexpectedToken(classifier); |
| 3474 classifier->AppendAssignmentTarget( |
| 3475 ExpressionClassifier::TARGET_PROPERTY); |
| 3252 Consume(Token::LBRACK); | 3476 Consume(Token::LBRACK); |
| 3253 int pos = position(); | 3477 int pos = position(); |
| 3254 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3478 ExpressionT index = ParseExpression(true, CHECK_OK); |
| 3255 result = factory()->NewProperty(result, index, pos); | 3479 result = factory()->NewProperty(result, index, pos); |
| 3256 Expect(Token::RBRACK, CHECK_OK); | 3480 Expect(Token::RBRACK, CHECK_OK); |
| 3257 break; | 3481 break; |
| 3258 } | 3482 } |
| 3259 | 3483 |
| 3260 case Token::LPAREN: { | 3484 case Token::LPAREN: { |
| 3261 BindingPatternUnexpectedToken(classifier); | 3485 BindingPatternUnexpectedToken(classifier); |
| 3262 | 3486 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); |
| 3263 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3487 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
| 3264 this->IsEval(this->AsIdentifier(result))) { | 3488 this->IsEval(this->AsIdentifier(result))) { |
| 3265 ReportMessage(MessageTemplate::kStrongDirectEval); | 3489 ReportMessage(MessageTemplate::kStrongDirectEval); |
| 3266 *ok = false; | 3490 *ok = false; |
| 3267 return this->EmptyExpression(); | 3491 return this->EmptyExpression(); |
| 3268 } | 3492 } |
| 3269 int pos; | 3493 int pos; |
| 3270 if (scanner()->current_token() == Token::IDENTIFIER) { | 3494 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3271 // For call of an identifier we want to report position of | 3495 // For call of an identifier we want to report position of |
| 3272 // the identifier as position of the call in the stack trace. | 3496 // the identifier as position of the call in the stack trace. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3303 result = Traits::SpreadCall(result, args, pos); | 3527 result = Traits::SpreadCall(result, args, pos); |
| 3304 } else { | 3528 } else { |
| 3305 result = factory()->NewCall(result, args, pos); | 3529 result = factory()->NewCall(result, args, pos); |
| 3306 } | 3530 } |
| 3307 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3531 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3308 break; | 3532 break; |
| 3309 } | 3533 } |
| 3310 | 3534 |
| 3311 case Token::PERIOD: { | 3535 case Token::PERIOD: { |
| 3312 BindingPatternUnexpectedToken(classifier); | 3536 BindingPatternUnexpectedToken(classifier); |
| 3537 classifier->AppendAssignmentTarget( |
| 3538 ExpressionClassifier::TARGET_PROPERTY); |
| 3313 Consume(Token::PERIOD); | 3539 Consume(Token::PERIOD); |
| 3314 int pos = position(); | 3540 int pos = position(); |
| 3315 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3541 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3316 result = factory()->NewProperty( | 3542 result = factory()->NewProperty( |
| 3317 result, factory()->NewStringLiteral(name, pos), pos); | 3543 result, factory()->NewStringLiteral(name, pos), pos); |
| 3318 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 3544 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
| 3319 break; | 3545 break; |
| 3320 } | 3546 } |
| 3321 | 3547 |
| 3322 default: | 3548 default: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3342 // Examples of new expression: | 3568 // Examples of new expression: |
| 3343 // new foo.bar().baz means (new (foo.bar)()).baz | 3569 // new foo.bar().baz means (new (foo.bar)()).baz |
| 3344 // new foo()() means (new foo())() | 3570 // new foo()() means (new foo())() |
| 3345 // new new foo()() means (new (new foo())()) | 3571 // new new foo()() means (new (new foo())()) |
| 3346 // new new foo means new (new foo) | 3572 // new new foo means new (new foo) |
| 3347 // new new foo() means new (new foo()) | 3573 // new new foo() means new (new foo()) |
| 3348 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3574 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 3349 | 3575 |
| 3350 if (peek() == Token::NEW) { | 3576 if (peek() == Token::NEW) { |
| 3351 BindingPatternUnexpectedToken(classifier); | 3577 BindingPatternUnexpectedToken(classifier); |
| 3578 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); |
| 3352 Consume(Token::NEW); | 3579 Consume(Token::NEW); |
| 3353 int new_pos = position(); | 3580 int new_pos = position(); |
| 3354 ExpressionT result = this->EmptyExpression(); | 3581 ExpressionT result = this->EmptyExpression(); |
| 3355 if (peek() == Token::SUPER) { | 3582 if (peek() == Token::SUPER) { |
| 3356 const bool is_new = true; | 3583 const bool is_new = true; |
| 3357 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3584 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 3358 } else { | 3585 } else { |
| 3359 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3586 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3360 } | 3587 } |
| 3361 if (peek() == Token::LPAREN) { | 3588 if (peek() == Token::LPAREN) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3393 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3620 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 3394 | 3621 |
| 3395 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3622 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 3396 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3623 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 3397 // caller. | 3624 // caller. |
| 3398 | 3625 |
| 3399 // Parse the initial primary or function expression. | 3626 // Parse the initial primary or function expression. |
| 3400 ExpressionT result = this->EmptyExpression(); | 3627 ExpressionT result = this->EmptyExpression(); |
| 3401 if (peek() == Token::FUNCTION) { | 3628 if (peek() == Token::FUNCTION) { |
| 3402 BindingPatternUnexpectedToken(classifier); | 3629 BindingPatternUnexpectedToken(classifier); |
| 3403 | 3630 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY); |
| 3404 Consume(Token::FUNCTION); | 3631 Consume(Token::FUNCTION); |
| 3405 int function_token_position = position(); | 3632 int function_token_position = position(); |
| 3406 bool is_generator = Check(Token::MUL); | 3633 bool is_generator = Check(Token::MUL); |
| 3407 IdentifierT name = this->EmptyIdentifier(); | 3634 IdentifierT name = this->EmptyIdentifier(); |
| 3408 bool is_strict_reserved_name = false; | 3635 bool is_strict_reserved_name = false; |
| 3409 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3636 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3410 FunctionLiteral::FunctionType function_type = | 3637 FunctionLiteral::FunctionType function_type = |
| 3411 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3638 FunctionLiteral::ANONYMOUS_EXPRESSION; |
| 3412 if (peek_any_identifier()) { | 3639 if (peek_any_identifier()) { |
| 3413 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3640 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 while (scope->is_eval_scope() || scope->is_arrow_scope()) { | 3809 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
| 3583 scope = scope->outer_scope(); | 3810 scope = scope->outer_scope(); |
| 3584 DCHECK_NOT_NULL(scope); | 3811 DCHECK_NOT_NULL(scope); |
| 3585 scope = scope->DeclarationScope(); | 3812 scope = scope->DeclarationScope(); |
| 3586 } | 3813 } |
| 3587 | 3814 |
| 3588 FunctionKind kind = scope->function_kind(); | 3815 FunctionKind kind = scope->function_kind(); |
| 3589 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3816 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 3590 i::IsConstructor(kind)) { | 3817 i::IsConstructor(kind)) { |
| 3591 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3818 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 3819 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY); |
| 3592 scope->RecordSuperPropertyUsage(); | 3820 scope->RecordSuperPropertyUsage(); |
| 3593 return this->SuperPropertyReference(scope_, factory(), pos); | 3821 return this->SuperPropertyReference(scope_, factory(), pos); |
| 3594 } | 3822 } |
| 3595 // new super() is never allowed. | 3823 // new super() is never allowed. |
| 3596 // super() is only allowed in derived constructor | 3824 // super() is only allowed in derived constructor |
| 3597 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3825 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3826 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); |
| 3598 if (is_strong(language_mode())) { | 3827 if (is_strong(language_mode())) { |
| 3599 // Super calls in strong mode are parsed separately. | 3828 // Super calls in strong mode are parsed separately. |
| 3600 ReportMessageAt(scanner()->location(), | 3829 ReportMessageAt(scanner()->location(), |
| 3601 MessageTemplate::kStrongConstructorSuper); | 3830 MessageTemplate::kStrongConstructorSuper); |
| 3602 *ok = false; | 3831 *ok = false; |
| 3603 return this->EmptyExpression(); | 3832 return this->EmptyExpression(); |
| 3604 } | 3833 } |
| 3605 // TODO(rossberg): This might not be the correct FunctionState for the | 3834 // TODO(rossberg): This might not be the correct FunctionState for the |
| 3606 // method here. | 3835 // method here. |
| 3607 function_state_->set_super_location(scanner()->location()); | 3836 function_state_->set_super_location(scanner()->location()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3618 template <class Traits> | 3847 template <class Traits> |
| 3619 typename ParserBase<Traits>::ExpressionT | 3848 typename ParserBase<Traits>::ExpressionT |
| 3620 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3849 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 3621 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3850 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| 3622 // Parses this part of MemberExpression: | 3851 // Parses this part of MemberExpression: |
| 3623 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3852 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3624 while (true) { | 3853 while (true) { |
| 3625 switch (peek()) { | 3854 switch (peek()) { |
| 3626 case Token::LBRACK: { | 3855 case Token::LBRACK: { |
| 3627 BindingPatternUnexpectedToken(classifier); | 3856 BindingPatternUnexpectedToken(classifier); |
| 3628 | 3857 classifier->AppendAssignmentTarget( |
| 3858 ExpressionClassifier::TARGET_PROPERTY); |
| 3629 Consume(Token::LBRACK); | 3859 Consume(Token::LBRACK); |
| 3630 int pos = position(); | 3860 int pos = position(); |
| 3631 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3861 // Ignore pattern errors within expression |
| 3862 ExpressionClassifier prop_classifier; |
| 3863 ExpressionT index = |
| 3864 this->ParseExpression(true, &prop_classifier, CHECK_OK); |
| 3632 expression = factory()->NewProperty(expression, index, pos); | 3865 expression = factory()->NewProperty(expression, index, pos); |
| 3633 if (fni_ != NULL) { | 3866 if (fni_ != NULL) { |
| 3634 this->PushPropertyName(fni_, index); | 3867 this->PushPropertyName(fni_, index); |
| 3635 } | 3868 } |
| 3636 Expect(Token::RBRACK, CHECK_OK); | 3869 Expect(Token::RBRACK, CHECK_OK); |
| 3637 break; | 3870 break; |
| 3638 } | 3871 } |
| 3639 case Token::PERIOD: { | 3872 case Token::PERIOD: { |
| 3640 BindingPatternUnexpectedToken(classifier); | 3873 BindingPatternUnexpectedToken(classifier); |
| 3874 classifier->AppendAssignmentTarget( |
| 3875 ExpressionClassifier::TARGET_PROPERTY); |
| 3641 | 3876 |
| 3642 Consume(Token::PERIOD); | 3877 Consume(Token::PERIOD); |
| 3643 int pos = position(); | 3878 int pos = position(); |
| 3644 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3879 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3645 expression = factory()->NewProperty( | 3880 expression = factory()->NewProperty( |
| 3646 expression, factory()->NewStringLiteral(name, pos), pos); | 3881 expression, factory()->NewStringLiteral(name, pos), pos); |
| 3647 if (fni_ != NULL) { | 3882 if (fni_ != NULL) { |
| 3648 this->PushLiteralName(fni_, name); | 3883 this->PushLiteralName(fni_, name); |
| 3649 } | 3884 } |
| 3650 break; | 3885 break; |
| 3651 } | 3886 } |
| 3652 case Token::TEMPLATE_SPAN: | 3887 case Token::TEMPLATE_SPAN: |
| 3653 case Token::TEMPLATE_TAIL: { | 3888 case Token::TEMPLATE_TAIL: { |
| 3654 BindingPatternUnexpectedToken(classifier); | 3889 BindingPatternUnexpectedToken(classifier); |
| 3890 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); |
| 3655 int pos; | 3891 int pos; |
| 3656 if (scanner()->current_token() == Token::IDENTIFIER) { | 3892 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3657 pos = position(); | 3893 pos = position(); |
| 3658 } else { | 3894 } else { |
| 3659 pos = peek_position(); | 3895 pos = peek_position(); |
| 3660 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3896 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3661 // If the tag function looks like an IIFE, set_parenthesized() to | 3897 // If the tag function looks like an IIFE, set_parenthesized() to |
| 3662 // force eager compilation. | 3898 // force eager compilation. |
| 3663 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3899 expression->AsFunctionLiteral()->set_should_eager_compile(); |
| 3664 } | 3900 } |
| 3665 } | 3901 } |
| 3902 // Ignore classifying tagged template |
| 3903 ExpressionClassifier call_classifier; |
| 3666 expression = | 3904 expression = |
| 3667 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | 3905 ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK); |
| 3668 break; | 3906 break; |
| 3669 } | 3907 } |
| 3670 default: | 3908 default: |
| 3671 return expression; | 3909 return expression; |
| 3672 } | 3910 } |
| 3673 } | 3911 } |
| 3674 DCHECK(false); | 3912 DCHECK(false); |
| 3675 return this->EmptyExpression(); | 3913 return this->EmptyExpression(); |
| 3676 } | 3914 } |
| 3677 | 3915 |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4049 *ok = false; | 4287 *ok = false; |
| 4050 return; | 4288 return; |
| 4051 } | 4289 } |
| 4052 has_seen_constructor_ = true; | 4290 has_seen_constructor_ = true; |
| 4053 return; | 4291 return; |
| 4054 } | 4292 } |
| 4055 } | 4293 } |
| 4056 } } // v8::internal | 4294 } } // v8::internal |
| 4057 | 4295 |
| 4058 #endif // V8_PREPARSER_H | 4296 #endif // V8_PREPARSER_H |
| OLD | NEW |