Chromium Code Reviews| 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 void AppendAssignmentTarget(AssignmentTargetType value) { | |
|
arv (Not doing code reviews)
2015/06/04 20:08:03
s/value/type/
caitp (gmail)
2015/06/05 18:37:13
Done.
| |
| 627 if (lhs_type_ == UNACCEPTABLE_TARGET) return; | |
| 628 lhs_type_ = value; | |
| 629 } | |
| 630 | |
| 631 inline void ReportInvalidSimpleAssignmentTarget() { | |
| 632 lhs_type_ = UNACCEPTABLE_TARGET; | |
| 633 } | |
| 634 | |
| 635 inline bool IsValidSimpleAssignmentTarget() const { | |
| 636 // Only identifiers and properties are valid targets. | |
| 637 return lhs_type_ >= TARGET_IDENTIFIER && lhs_type_ <= TARGET_PROPERTY; | |
| 638 } | |
| 639 | |
| 640 inline bool IsPatternAssignmentElement() const { | |
| 641 // Any AssignmentElement for which IsValidSimpleAssignmentTarget is false. | |
| 642 // Used for nested AssignmentPatterns | |
| 643 return lhs_type_ == TARGET_PATTERN && is_valid_assignment_pattern(); | |
| 644 } | |
| 645 | |
| 646 void set_assigned() { assigned_ = true; } | |
| 647 | |
| 648 bool is_destructuring_assignment() const { | |
| 649 return lhs_type_ == TARGET_PATTERN && assigned_; | |
| 650 } | |
| 574 | 651 |
| 575 bool is_valid_expression() const { return !expression_error_.HasError(); } | 652 bool is_valid_expression() const { return !expression_error_.HasError(); } |
| 576 | 653 |
| 577 bool is_valid_binding_pattern() const { | 654 bool is_valid_binding_pattern() const { |
| 578 return !binding_pattern_error_.HasError(); | 655 return !binding_pattern_error_.HasError(); |
| 579 } | 656 } |
| 580 | 657 |
| 581 bool is_valid_assignment_pattern() const { | 658 bool is_valid_assignment_pattern() const { |
| 582 return !assignment_pattern_error_.HasError(); | 659 return !assignment_pattern_error_.HasError(); |
| 583 } | 660 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 FormalParametersProduction = 1 << 3, | 777 FormalParametersProduction = 1 << 3, |
| 701 ArrowFormalParametersProduction = 1 << 4, | 778 ArrowFormalParametersProduction = 1 << 4, |
| 702 StandardProductions = (ExpressionProduction | BindingPatternProduction | | 779 StandardProductions = (ExpressionProduction | BindingPatternProduction | |
| 703 AssignmentPatternProduction), | 780 AssignmentPatternProduction), |
| 704 PatternProductions = | 781 PatternProductions = |
| 705 BindingPatternProduction | AssignmentPatternProduction, | 782 BindingPatternProduction | AssignmentPatternProduction, |
| 706 AllProductions = (StandardProductions | FormalParametersProduction | | 783 AllProductions = (StandardProductions | FormalParametersProduction | |
| 707 ArrowFormalParametersProduction), | 784 ArrowFormalParametersProduction), |
| 708 }; | 785 }; |
| 709 | 786 |
| 787 void AccumulateValidSimpleAssignmentTarget( | |
| 788 const ExpressionClassifier& inner) { | |
| 789 if (lhs_type_ != UNACCEPTABLE_TARGET) { | |
| 790 lhs_type_ = inner.lhs_type_; | |
| 791 } | |
| 792 } | |
| 793 | |
| 710 void Accumulate(const ExpressionClassifier& inner, | 794 void Accumulate(const ExpressionClassifier& inner, |
| 711 unsigned productions = StandardProductions) { | 795 unsigned productions = StandardProductions) { |
| 712 if (productions & ExpressionProduction && is_valid_expression()) { | 796 if (productions & ExpressionProduction && is_valid_expression()) { |
| 713 expression_error_ = inner.expression_error_; | 797 expression_error_ = inner.expression_error_; |
| 714 } | 798 } |
| 715 if (productions & BindingPatternProduction && | 799 if (productions & BindingPatternProduction && |
| 716 is_valid_binding_pattern()) { | 800 is_valid_binding_pattern()) { |
| 717 binding_pattern_error_ = inner.binding_pattern_error_; | 801 binding_pattern_error_ = inner.binding_pattern_error_; |
| 718 } | 802 } |
| 719 if (productions & AssignmentPatternProduction && | 803 if (productions & AssignmentPatternProduction && |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 748 if (is_valid_binding_pattern()) { | 832 if (is_valid_binding_pattern()) { |
| 749 binding_pattern_error_ = inner.expression_error(); | 833 binding_pattern_error_ = inner.expression_error(); |
| 750 } | 834 } |
| 751 if (is_valid_assignment_pattern()) { | 835 if (is_valid_assignment_pattern()) { |
| 752 assignment_pattern_error_ = inner.expression_error(); | 836 assignment_pattern_error_ = inner.expression_error(); |
| 753 } | 837 } |
| 754 } | 838 } |
| 755 } | 839 } |
| 756 | 840 |
| 757 private: | 841 private: |
| 842 AssignmentTargetType lhs_type_; | |
| 843 bool assigned_; | |
| 758 Error expression_error_; | 844 Error expression_error_; |
| 759 Error binding_pattern_error_; | 845 Error binding_pattern_error_; |
| 760 Error assignment_pattern_error_; | 846 Error assignment_pattern_error_; |
| 761 Error arrow_formal_parameters_error_; | 847 Error arrow_formal_parameters_error_; |
| 762 Error duplicate_formal_parameter_error_; | 848 Error duplicate_formal_parameter_error_; |
| 763 Error strict_mode_formal_parameter_error_; | 849 Error strict_mode_formal_parameter_error_; |
| 764 Error strong_mode_formal_parameter_error_; | 850 Error strong_mode_formal_parameter_error_; |
| 765 }; | 851 }; |
| 766 | 852 |
| 853 ExpressionT CheckDestructuringAssignment(ExpressionT expr, | |
| 854 ExpressionClassifier* classifier, | |
| 855 bool* ok) { | |
| 856 if (classifier->is_destructuring_assignment()) { | |
| 857 if (!classifier->is_valid_assignment_pattern()) { | |
| 858 this->ReportClassifierError(classifier->assignment_pattern_error()); | |
| 859 *ok = false; | |
| 860 return this->EmptyExpression(); | |
| 861 } | |
| 862 return Traits::RewriteDestructuringAssignment(expr); | |
| 863 } | |
| 864 return expr; | |
| 865 } | |
| 866 | |
| 767 void ReportClassifierError( | 867 void ReportClassifierError( |
| 768 const typename ExpressionClassifier::Error& error) { | 868 const typename ExpressionClassifier::Error& error) { |
| 769 Traits::ReportMessageAt(error.location, error.message, error.arg, | 869 Traits::ReportMessageAt(error.location, error.message, error.arg, |
| 770 kSyntaxError); | 870 kSyntaxError); |
| 771 } | 871 } |
| 772 | 872 |
| 773 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 873 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
| 774 if (!classifier->is_valid_expression()) { | 874 if (!classifier->is_valid_expression()) { |
| 775 ReportClassifierError(classifier->expression_error()); | 875 ReportClassifierError(classifier->expression_error()); |
| 776 *ok = false; | 876 *ok = false; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 bool* is_static, bool* is_computed_name, | 978 bool* is_static, bool* is_computed_name, |
| 879 ExpressionClassifier* classifier, bool* ok); | 979 ExpressionClassifier* classifier, bool* ok); |
| 880 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 980 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 881 ObjectLiteralPropertyT ParsePropertyDefinition( | 981 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 882 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 982 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 883 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 983 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 884 ExpressionClassifier* classifier, bool* ok); | 984 ExpressionClassifier* classifier, bool* ok); |
| 885 typename Traits::Type::ExpressionList ParseArguments( | 985 typename Traits::Type::ExpressionList ParseArguments( |
| 886 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 986 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 887 bool* ok); | 987 bool* ok); |
| 988 ExpressionT ParseAssignmentExpression(bool accept_IN, bool is_rhs, | |
| 989 ExpressionClassifier* classifier, | |
| 990 bool* ok); | |
| 888 ExpressionT ParseAssignmentExpression(bool accept_IN, | 991 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 889 ExpressionClassifier* classifier, | 992 ExpressionClassifier* classifier, |
| 890 bool* ok); | 993 bool* ok) { |
| 994 return ParseAssignmentExpression(accept_IN, false, classifier, ok); | |
| 995 } | |
| 891 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); | 996 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| 892 ExpressionT ParseConditionalExpression(bool accept_IN, | 997 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 893 ExpressionClassifier* classifier, | 998 ExpressionClassifier* classifier, |
| 894 bool* ok); | 999 bool* ok); |
| 895 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 1000 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 896 ExpressionClassifier* classifier, bool* ok); | 1001 ExpressionClassifier* classifier, bool* ok); |
| 897 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 1002 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 898 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 1003 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 899 bool* ok); | 1004 bool* ok); |
| 900 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 1005 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 | 1934 |
| 1830 inline void MaterializeUnspreadArgumentsLiterals(int count); | 1935 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1831 | 1936 |
| 1832 inline PreParserExpression SpreadCall(PreParserExpression function, | 1937 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1833 PreParserExpressionList args, int pos); | 1938 PreParserExpressionList args, int pos); |
| 1834 | 1939 |
| 1835 inline PreParserExpression SpreadCallNew(PreParserExpression function, | 1940 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1836 PreParserExpressionList args, | 1941 PreParserExpressionList args, |
| 1837 int pos); | 1942 int pos); |
| 1838 | 1943 |
| 1944 inline PreParserExpression RewriteDestructuringAssignment( | |
| 1945 PreParserExpression expr) { | |
| 1946 return expr; | |
| 1947 } | |
| 1948 | |
| 1839 private: | 1949 private: |
| 1840 PreParser* pre_parser_; | 1950 PreParser* pre_parser_; |
| 1841 }; | 1951 }; |
| 1842 | 1952 |
| 1843 | 1953 |
| 1844 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1954 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1845 // a later parsing to be faster. | 1955 // a later parsing to be faster. |
| 1846 // See preparse-data-format.h for the data format. | 1956 // See preparse-data-format.h for the data format. |
| 1847 | 1957 |
| 1848 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1958 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2306 // ObjectLiteral | 2416 // ObjectLiteral |
| 2307 // RegExpLiteral | 2417 // RegExpLiteral |
| 2308 // ClassLiteral | 2418 // ClassLiteral |
| 2309 // '(' Expression ')' | 2419 // '(' Expression ')' |
| 2310 // TemplateLiteral | 2420 // TemplateLiteral |
| 2311 | 2421 |
| 2312 int beg_pos = scanner()->peek_location().beg_pos; | 2422 int beg_pos = scanner()->peek_location().beg_pos; |
| 2313 int end_pos = scanner()->peek_location().end_pos; | 2423 int end_pos = scanner()->peek_location().end_pos; |
| 2314 ExpressionT result = this->EmptyExpression(); | 2424 ExpressionT result = this->EmptyExpression(); |
| 2315 Token::Value token = peek(); | 2425 Token::Value token = peek(); |
| 2426 typename ExpressionClassifier::AssignmentTargetType lhs_part = | |
| 2427 ExpressionClassifier::TARGET_PRIMARY; | |
| 2316 switch (token) { | 2428 switch (token) { |
| 2317 case Token::THIS: { | 2429 case Token::THIS: { |
| 2318 BindingPatternUnexpectedToken(classifier); | 2430 BindingPatternUnexpectedToken(classifier); |
| 2319 Consume(Token::THIS); | 2431 Consume(Token::THIS); |
| 2320 if (is_strong(language_mode())) { | 2432 if (is_strong(language_mode())) { |
| 2321 // Constructors' usages of 'this' in strong mode are parsed separately. | 2433 // Constructors' usages of 'this' in strong mode are parsed separately. |
| 2322 // TODO(rossberg): this does not work with arrow functions yet. | 2434 // TODO(rossberg): this does not work with arrow functions yet. |
| 2323 if (i::IsConstructor(function_state_->kind())) { | 2435 if (i::IsConstructor(function_state_->kind())) { |
| 2324 ReportMessage(MessageTemplate::kStrongConstructorThis); | 2436 ReportMessage(MessageTemplate::kStrongConstructorThis); |
| 2325 *ok = false; | 2437 *ok = false; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2346 result = | 2458 result = |
| 2347 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2459 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
| 2348 break; | 2460 break; |
| 2349 | 2461 |
| 2350 case Token::IDENTIFIER: | 2462 case Token::IDENTIFIER: |
| 2351 case Token::LET: | 2463 case Token::LET: |
| 2352 case Token::STATIC: | 2464 case Token::STATIC: |
| 2353 case Token::YIELD: | 2465 case Token::YIELD: |
| 2354 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2466 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 2355 // Using eval or arguments in this context is OK even in strict mode. | 2467 // Using eval or arguments in this context is OK even in strict mode. |
| 2468 lhs_part = ExpressionClassifier::TARGET_IDENTIFIER; | |
| 2356 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2469 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 2357 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2470 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
| 2358 factory()); | 2471 factory()); |
| 2359 break; | 2472 break; |
| 2360 } | 2473 } |
| 2361 | 2474 |
| 2362 case Token::STRING: { | 2475 case Token::STRING: { |
| 2363 classifier->RecordBindingPatternError( | 2476 classifier->RecordBindingPatternError( |
| 2364 scanner()->location(), MessageTemplate::kUnexpectedTokenString); | 2477 scanner()->location(), MessageTemplate::kUnexpectedTokenString); |
| 2365 Consume(Token::STRING); | 2478 Consume(Token::STRING); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2409 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 2522 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2410 scope->set_start_position(beg_pos); | 2523 scope->set_start_position(beg_pos); |
| 2411 ExpressionClassifier args_classifier; | 2524 ExpressionClassifier args_classifier; |
| 2412 bool has_rest = false; | 2525 bool has_rest = false; |
| 2413 result = this->ParseArrowFunctionLiteral(scope, has_rest, | 2526 result = this->ParseArrowFunctionLiteral(scope, has_rest, |
| 2414 args_classifier, CHECK_OK); | 2527 args_classifier, CHECK_OK); |
| 2415 } else { | 2528 } else { |
| 2416 // Heuristically try to detect immediately called functions before | 2529 // Heuristically try to detect immediately called functions before |
| 2417 // seeing the call parentheses. | 2530 // seeing the call parentheses. |
| 2418 parenthesized_function_ = (peek() == Token::FUNCTION); | 2531 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2419 result = this->ParseExpression(true, classifier, CHECK_OK); | 2532 ExpressionClassifier expr_classifier; |
| 2533 result = this->ParseExpression(true, &expr_classifier, CHECK_OK); | |
| 2420 Expect(Token::RPAREN, CHECK_OK); | 2534 Expect(Token::RPAREN, CHECK_OK); |
| 2535 if (peek() == Token::ARROW || parenthesized_function_) { | |
| 2536 classifier->Accumulate( | |
| 2537 expr_classifier, | |
| 2538 ExpressionClassifier::ArrowFormalParametersProduction | | |
| 2539 ExpressionClassifier::FormalParametersProduction); | |
| 2540 } | |
| 2421 } | 2541 } |
| 2422 break; | 2542 break; |
| 2423 | 2543 |
| 2424 case Token::CLASS: { | 2544 case Token::CLASS: { |
| 2425 BindingPatternUnexpectedToken(classifier); | 2545 BindingPatternUnexpectedToken(classifier); |
| 2426 Consume(Token::CLASS); | 2546 Consume(Token::CLASS); |
| 2427 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2547 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2428 ReportMessage(MessageTemplate::kSloppyLexical); | 2548 ReportMessage(MessageTemplate::kSloppyLexical); |
| 2429 *ok = false; | 2549 *ok = false; |
| 2430 break; | 2550 break; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2446 | 2566 |
| 2447 case Token::TEMPLATE_SPAN: | 2567 case Token::TEMPLATE_SPAN: |
| 2448 case Token::TEMPLATE_TAIL: | 2568 case Token::TEMPLATE_TAIL: |
| 2449 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2569 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
| 2450 classifier, CHECK_OK); | 2570 classifier, CHECK_OK); |
| 2451 break; | 2571 break; |
| 2452 | 2572 |
| 2453 case Token::MOD: | 2573 case Token::MOD: |
| 2454 if (allow_natives() || extension_ != NULL) { | 2574 if (allow_natives() || extension_ != NULL) { |
| 2455 result = this->ParseV8Intrinsic(CHECK_OK); | 2575 result = this->ParseV8Intrinsic(CHECK_OK); |
| 2576 lhs_part = ExpressionClassifier::TARGET_CALL; | |
| 2456 break; | 2577 break; |
| 2457 } | 2578 } |
| 2458 // If we're not allowing special syntax we fall-through to the | 2579 // If we're not allowing special syntax we fall-through to the |
| 2459 // default case. | 2580 // default case. |
| 2460 | 2581 |
| 2461 default: { | 2582 default: { |
| 2462 Next(); | 2583 Next(); |
| 2463 ReportUnexpectedToken(token); | 2584 ReportUnexpectedToken(token); |
| 2464 *ok = false; | 2585 *ok = false; |
| 2465 } | 2586 } |
| 2466 } | 2587 } |
| 2467 | 2588 |
| 2589 if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) { | |
| 2590 classifier->AppendAssignmentTarget(lhs_part); | |
| 2591 } | |
| 2592 | |
| 2468 return result; | 2593 return result; |
| 2469 } | 2594 } |
| 2470 | 2595 |
| 2471 | 2596 |
| 2472 template <class Traits> | 2597 template <class Traits> |
| 2473 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2598 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2474 bool accept_IN, bool* ok) { | 2599 bool accept_IN, bool* ok) { |
| 2475 ExpressionClassifier classifier; | 2600 ExpressionClassifier classifier; |
| 2476 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2601 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 2477 ValidateExpression(&classifier, CHECK_OK); | 2602 ValidateExpression(&classifier, CHECK_OK); |
| 2478 return result; | 2603 return result; |
| 2479 } | 2604 } |
| 2480 | 2605 |
| 2481 | 2606 |
| 2482 // Precedence = 1 | 2607 // Precedence = 1 |
| 2483 template <class Traits> | 2608 template <class Traits> |
| 2484 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2609 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2485 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2610 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2486 // Expression :: | 2611 // Expression :: |
| 2487 // AssignmentExpression | 2612 // AssignmentExpression |
| 2488 // Expression ',' AssignmentExpression | 2613 // Expression ',' AssignmentExpression |
| 2489 | 2614 |
| 2490 ExpressionClassifier binding_classifier; | 2615 ExpressionClassifier binding_classifier; |
|
arv (Not doing code reviews)
2015/06/04 20:08:03
rename this?
caitp (gmail)
2015/06/05 18:37:13
Done.
| |
| 2491 ExpressionT result = | 2616 ExpressionT result = |
| 2492 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 2617 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
| 2493 classifier->Accumulate(binding_classifier, | 2618 if (binding_classifier.is_destructuring_assignment()) { |
| 2494 ExpressionClassifier::AllProductions); | 2619 classifier->Accumulate(binding_classifier, |
| 2620 ExpressionClassifier::PatternProductions); | |
| 2621 } else { | |
| 2622 classifier->Accumulate(binding_classifier, | |
| 2623 ExpressionClassifier::AllProductions); | |
| 2624 } | |
| 2495 while (peek() == Token::COMMA) { | 2625 while (peek() == Token::COMMA) { |
| 2496 Expect(Token::COMMA, CHECK_OK); | 2626 Expect(Token::COMMA, CHECK_OK); |
| 2497 int pos = position(); | 2627 int pos = position(); |
| 2628 ExpressionClassifier binding_classifier; | |
| 2498 ExpressionT right = this->ParseAssignmentExpression( | 2629 ExpressionT right = this->ParseAssignmentExpression( |
| 2499 accept_IN, &binding_classifier, CHECK_OK); | 2630 accept_IN, &binding_classifier, CHECK_OK); |
| 2500 classifier->Accumulate(binding_classifier, | 2631 if (binding_classifier.is_destructuring_assignment()) { |
| 2501 ExpressionClassifier::AllProductions); | 2632 classifier->Accumulate(binding_classifier, |
| 2633 ExpressionClassifier::PatternProductions); | |
| 2634 } else { | |
| 2635 classifier->Accumulate(binding_classifier, | |
| 2636 ExpressionClassifier::AllProductions); | |
| 2637 } | |
| 2638 | |
| 2502 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2639 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2503 } | 2640 } |
| 2504 return result; | 2641 return result; |
| 2505 } | 2642 } |
| 2506 | 2643 |
| 2507 | 2644 |
| 2508 template <class Traits> | 2645 template <class Traits> |
| 2509 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2646 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| 2510 ExpressionClassifier* classifier, bool* ok) { | 2647 ExpressionClassifier* classifier, bool* ok) { |
| 2511 // ArrayLiteral :: | 2648 // ArrayLiteral :: |
| 2512 // '[' Expression? (',' Expression?)* ']' | 2649 // '[' Expression? (',' Expression?)* ']' |
| 2513 | 2650 |
| 2514 int pos = peek_position(); | 2651 int pos = peek_position(); |
| 2515 typename Traits::Type::ExpressionList values = | 2652 typename Traits::Type::ExpressionList values = |
| 2516 this->NewExpressionList(4, zone_); | 2653 this->NewExpressionList(4, zone_); |
| 2517 Expect(Token::LBRACK, CHECK_OK); | 2654 Expect(Token::LBRACK, CHECK_OK); |
| 2518 while (peek() != Token::RBRACK) { | 2655 while (peek() != Token::RBRACK) { |
| 2519 bool seen_spread = false; | 2656 bool seen_spread = false; |
| 2520 ExpressionT elem = this->EmptyExpression(); | 2657 ExpressionT elem = this->EmptyExpression(); |
| 2658 ExpressionClassifier element_classifier; | |
| 2521 if (peek() == Token::COMMA) { | 2659 if (peek() == Token::COMMA) { |
| 2522 if (is_strong(language_mode())) { | 2660 if (is_strong(language_mode())) { |
| 2523 ReportMessageAt(scanner()->peek_location(), | 2661 ReportMessageAt(scanner()->peek_location(), |
| 2524 MessageTemplate::kStrongEllision); | 2662 MessageTemplate::kStrongEllision); |
| 2525 *ok = false; | 2663 *ok = false; |
| 2526 return this->EmptyExpression(); | 2664 return this->EmptyExpression(); |
| 2527 } | 2665 } |
| 2528 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2666 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2529 } else if (peek() == Token::ELLIPSIS) { | 2667 } else if (peek() == Token::ELLIPSIS) { |
| 2530 if (!allow_harmony_spread_arrays()) { | 2668 if (!allow_harmony_spread_arrays()) { |
| 2531 ExpressionUnexpectedToken(classifier); | 2669 ExpressionUnexpectedToken(classifier); |
| 2532 } | 2670 } |
| 2533 int start_pos = peek_position(); | 2671 int start_pos = peek_position(); |
| 2534 Consume(Token::ELLIPSIS); | 2672 Consume(Token::ELLIPSIS); |
| 2535 ExpressionT argument = | 2673 ExpressionT argument = |
| 2536 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2674 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2537 elem = factory()->NewSpread(argument, start_pos); | 2675 elem = factory()->NewSpread(argument, start_pos); |
| 2538 seen_spread = true; | 2676 seen_spread = true; |
| 2539 } else { | 2677 } else { |
| 2540 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2678 int start_pos = peek_position(); |
| 2679 elem = | |
| 2680 this->ParseAssignmentExpression(true, &element_classifier, CHECK_OK); | |
| 2681 if (!element_classifier.IsValidSimpleAssignmentTarget() && | |
| 2682 !element_classifier.IsPatternAssignmentElement()) { | |
| 2683 Scanner::Location location(start_pos, scanner()->location().end_pos); | |
| 2684 classifier->RecordAssignmentPatternError( | |
| 2685 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); | |
| 2686 } | |
| 2687 classifier->Accumulate(element_classifier); | |
| 2541 } | 2688 } |
| 2542 values->Add(elem, zone_); | 2689 values->Add(elem, zone_); |
| 2543 if (peek() != Token::RBRACK) { | 2690 if (peek() != Token::RBRACK) { |
| 2544 if (seen_spread) { | 2691 if (seen_spread) { |
| 2545 BindingPatternUnexpectedToken(classifier); | 2692 BindingPatternUnexpectedToken(classifier); |
| 2546 } | 2693 } |
| 2547 Expect(Token::COMMA, CHECK_OK); | 2694 Expect(Token::COMMA, CHECK_OK); |
| 2548 } | 2695 } |
| 2549 } | 2696 } |
| 2550 Expect(Token::RBRACK, CHECK_OK); | 2697 Expect(Token::RBRACK, CHECK_OK); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2624 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 2771 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 2625 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 2772 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 2626 ExpressionClassifier* classifier, bool* ok) { | 2773 ExpressionClassifier* classifier, bool* ok) { |
| 2627 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 2774 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| 2628 ExpressionT value = this->EmptyExpression(); | 2775 ExpressionT value = this->EmptyExpression(); |
| 2629 IdentifierT name = this->EmptyIdentifier(); | 2776 IdentifierT name = this->EmptyIdentifier(); |
| 2630 bool is_get = false; | 2777 bool is_get = false; |
| 2631 bool is_set = false; | 2778 bool is_set = false; |
| 2632 bool name_is_static = false; | 2779 bool name_is_static = false; |
| 2633 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2780 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
| 2634 | 2781 // Classify destructuring assignment target for ObjectAssignmentPattern |
| 2782 ExpressionClassifier property_classifier; | |
| 2635 Token::Value name_token = peek(); | 2783 Token::Value name_token = peek(); |
| 2636 int next_beg_pos = scanner()->peek_location().beg_pos; | 2784 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2637 int next_end_pos = scanner()->peek_location().end_pos; | 2785 int next_end_pos = scanner()->peek_location().end_pos; |
| 2786 int value_start = next_beg_pos; | |
| 2787 int value_end = next_end_pos; | |
| 2638 ExpressionT name_expression = ParsePropertyName( | 2788 ExpressionT name_expression = ParsePropertyName( |
| 2639 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, | 2789 &name, &is_get, &is_set, &name_is_static, is_computed_name, |
| 2640 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2790 &property_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2641 | 2791 |
| 2642 if (fni_ != nullptr && !*is_computed_name) { | 2792 if (fni_ != nullptr && !*is_computed_name) { |
| 2643 this->PushLiteralName(fni_, name); | 2793 this->PushLiteralName(fni_, name); |
| 2644 } | 2794 } |
| 2645 | 2795 |
| 2646 if (!in_class && !is_generator && peek() == Token::COLON) { | 2796 if (!in_class && !is_generator && peek() == Token::COLON) { |
| 2647 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2797 // PropertyDefinition : PropertyName ':' AssignmentExpression |
| 2648 if (!*is_computed_name) { | 2798 if (!*is_computed_name) { |
| 2649 checker->CheckProperty(name_token, kValueProperty, is_static, | 2799 checker->CheckProperty(name_token, kValueProperty, is_static, |
| 2650 is_generator, | 2800 is_generator, |
| 2651 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2801 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2652 } | 2802 } |
| 2653 Consume(Token::COLON); | 2803 Consume(Token::COLON); |
| 2804 property_classifier = ExpressionClassifier(); | |
| 2805 value_start = peek_position(); | |
| 2654 value = this->ParseAssignmentExpression( | 2806 value = this->ParseAssignmentExpression( |
| 2655 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2807 true, &property_classifier, |
| 2656 | 2808 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2809 value_end = scanner()->location().end_pos; | |
| 2657 } else if (is_generator || | 2810 } else if (is_generator || |
| 2658 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2811 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
| 2659 // Concise Method | 2812 // Concise Method |
| 2813 property_classifier.ReportInvalidSimpleAssignmentTarget(); | |
| 2660 if (!*is_computed_name) { | 2814 if (!*is_computed_name) { |
| 2661 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2815 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 2662 is_generator, | 2816 is_generator, |
| 2663 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2817 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2664 } | 2818 } |
| 2665 | 2819 |
| 2666 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 2820 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
| 2667 : FunctionKind::kConciseMethod; | 2821 : FunctionKind::kConciseMethod; |
| 2668 | 2822 |
| 2669 if (in_class && !is_static && this->IsConstructor(name)) { | 2823 if (in_class && !is_static && this->IsConstructor(name)) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2680 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2834 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 2681 FunctionLiteral::NORMAL_ARITY, | 2835 FunctionLiteral::NORMAL_ARITY, |
| 2682 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2836 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2683 | 2837 |
| 2684 return factory()->NewObjectLiteralProperty(name_expression, value, | 2838 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 2685 ObjectLiteralProperty::COMPUTED, | 2839 ObjectLiteralProperty::COMPUTED, |
| 2686 is_static, *is_computed_name); | 2840 is_static, *is_computed_name); |
| 2687 | 2841 |
| 2688 } else if (in_class && name_is_static && !is_static) { | 2842 } else if (in_class && name_is_static && !is_static) { |
| 2689 // static MethodDefinition | 2843 // static MethodDefinition |
| 2844 property_classifier.ReportInvalidSimpleAssignmentTarget(); | |
| 2690 return ParsePropertyDefinition(checker, true, has_extends, true, | 2845 return ParsePropertyDefinition(checker, true, has_extends, true, |
| 2691 is_computed_name, nullptr, classifier, ok); | 2846 is_computed_name, nullptr, classifier, ok); |
| 2692 } else if (is_get || is_set) { | 2847 } else if (is_get || is_set) { |
| 2693 // Accessor | 2848 // Accessor |
| 2849 property_classifier.ReportInvalidSimpleAssignmentTarget(); | |
| 2694 name = this->EmptyIdentifier(); | 2850 name = this->EmptyIdentifier(); |
| 2695 bool dont_care = false; | 2851 bool dont_care = false; |
| 2696 name_token = peek(); | 2852 name_token = peek(); |
| 2697 | 2853 |
| 2698 name_expression = ParsePropertyName( | 2854 name_expression = ParsePropertyName( |
| 2699 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, | 2855 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 2700 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2856 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2701 | 2857 |
| 2702 if (!*is_computed_name) { | 2858 if (!*is_computed_name) { |
| 2703 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2859 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2715 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2871 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2716 | 2872 |
| 2717 // Make sure the name expression is a string since we need a Name for | 2873 // Make sure the name expression is a string since we need a Name for |
| 2718 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 2874 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
| 2719 // statically we can skip the extra runtime check. | 2875 // statically we can skip the extra runtime check. |
| 2720 if (!*is_computed_name) { | 2876 if (!*is_computed_name) { |
| 2721 name_expression = | 2877 name_expression = |
| 2722 factory()->NewStringLiteral(name, name_expression->position()); | 2878 factory()->NewStringLiteral(name, name_expression->position()); |
| 2723 } | 2879 } |
| 2724 | 2880 |
| 2881 value_end = scanner()->location().end_pos; | |
| 2882 Scanner::Location location(value_start, value_end); | |
| 2883 classifier->RecordAssignmentPatternError( | |
| 2884 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); | |
| 2885 | |
| 2725 return factory()->NewObjectLiteralProperty( | 2886 return factory()->NewObjectLiteralProperty( |
| 2726 name_expression, value, | 2887 name_expression, value, |
| 2727 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 2888 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
| 2728 is_static, *is_computed_name); | 2889 is_static, *is_computed_name); |
| 2729 | 2890 |
| 2730 } else if (!in_class && allow_harmony_object_literals_ && | 2891 } else if (!in_class && allow_harmony_object_literals_ && |
| 2731 Token::IsIdentifier(name_token, language_mode(), | 2892 Token::IsIdentifier(name_token, language_mode(), |
| 2732 this->is_generator())) { | 2893 this->is_generator())) { |
| 2733 DCHECK(!*is_computed_name); | 2894 DCHECK(!*is_computed_name); |
| 2734 DCHECK(!is_static); | 2895 DCHECK(!is_static); |
| 2735 | 2896 |
| 2736 ExpressionT lhs = this->ExpressionFromIdentifier( | 2897 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 2737 name, next_beg_pos, next_end_pos, scope_, factory()); | 2898 name, next_beg_pos, next_end_pos, scope_, factory()); |
| 2738 if (peek() == Token::ASSIGN) { | 2899 if (peek() == Token::ASSIGN) { |
| 2739 this->ExpressionUnexpectedToken(classifier); | 2900 this->ExpressionUnexpectedToken(classifier); |
| 2740 Consume(Token::ASSIGN); | 2901 Consume(Token::ASSIGN); |
| 2741 ExpressionClassifier rhs_classifier; | 2902 ExpressionClassifier rhs_classifier; |
| 2742 ExpressionT rhs = this->ParseAssignmentExpression( | 2903 ExpressionT rhs = this->ParseAssignmentExpression( |
| 2743 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2904 true, true, &rhs_classifier, |
| 2905 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 2744 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); | 2906 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); |
| 2745 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2907 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 2746 RelocInfo::kNoPosition); | 2908 RelocInfo::kNoPosition); |
| 2747 } else { | 2909 } else { |
| 2748 value = lhs; | 2910 value = lhs; |
| 2749 } | 2911 } |
| 2750 return factory()->NewObjectLiteralProperty( | 2912 return factory()->NewObjectLiteralProperty( |
| 2751 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); | 2913 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); |
| 2752 | 2914 |
| 2753 } else { | 2915 } else { |
| 2754 Token::Value next = Next(); | 2916 Token::Value next = Next(); |
| 2755 ReportUnexpectedToken(next); | 2917 ReportUnexpectedToken(next); |
| 2756 *ok = false; | 2918 *ok = false; |
| 2757 return this->EmptyObjectLiteralProperty(); | 2919 return this->EmptyObjectLiteralProperty(); |
| 2758 } | 2920 } |
| 2759 | 2921 |
| 2922 if (!property_classifier.IsValidSimpleAssignmentTarget() && | |
| 2923 !property_classifier.IsPatternAssignmentElement()) { | |
| 2924 Scanner::Location location(value_start, value_end); | |
| 2925 classifier->RecordAssignmentPatternError( | |
| 2926 location, MessageTemplate::kInvalidDestructuringAssignmentTarget); | |
| 2927 } | |
| 2928 classifier->Accumulate(property_classifier); | |
| 2929 | |
| 2760 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2930 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
| 2761 *is_computed_name); | 2931 *is_computed_name); |
| 2762 } | 2932 } |
| 2763 | 2933 |
| 2764 | 2934 |
| 2765 template <class Traits> | 2935 template <class Traits> |
| 2766 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2936 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| 2767 ExpressionClassifier* classifier, bool* ok) { | 2937 ExpressionClassifier* classifier, bool* ok) { |
| 2768 // ObjectLiteral :: | 2938 // ObjectLiteral :: |
| 2769 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2939 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2892 // the parser and preparser | 3062 // the parser and preparser |
| 2893 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 3063 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2894 } | 3064 } |
| 2895 | 3065 |
| 2896 return result; | 3066 return result; |
| 2897 } | 3067 } |
| 2898 | 3068 |
| 2899 // Precedence = 2 | 3069 // Precedence = 2 |
| 2900 template <class Traits> | 3070 template <class Traits> |
| 2901 typename ParserBase<Traits>::ExpressionT | 3071 typename ParserBase<Traits>::ExpressionT |
| 2902 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 3072 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool is_rhs, |
|
arv (Not doing code reviews)
2015/06/04 20:08:03
TODO: Maybe add enums for this and accept_IN?
caitp (gmail)
2015/06/05 18:37:13
Done.
| |
| 2903 ExpressionClassifier* classifier, | 3073 ExpressionClassifier* classifier, |
| 2904 bool* ok) { | 3074 bool* ok) { |
| 2905 // AssignmentExpression :: | 3075 // AssignmentExpression :: |
| 2906 // ConditionalExpression | 3076 // ConditionalExpression |
| 2907 // ArrowFunction | 3077 // ArrowFunction |
| 2908 // YieldExpression | 3078 // YieldExpression |
| 2909 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3079 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2910 | 3080 |
| 2911 Scanner::Location lhs_location = scanner()->peek_location(); | 3081 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2912 | 3082 |
| 2913 if (peek() == Token::YIELD && is_generator()) { | 3083 if (peek() == Token::YIELD && is_generator()) { |
| 2914 return this->ParseYieldExpression(classifier, ok); | 3084 return this->ParseYieldExpression(classifier, ok); |
| 2915 } | 3085 } |
| 2916 | 3086 |
| 3087 bool maybeAssignmentPattern = | |
|
arv (Not doing code reviews)
2015/06/04 20:08:03
maybe_assignment_pattern
caitp (gmail)
2015/06/05 18:37:13
Done.
| |
| 3088 allow_harmony_destructuring() && !is_rhs && | |
|
arv (Not doing code reviews)
2015/06/04 20:08:04
maybe rename is_rhs to is_lhs?
caitp (gmail)
2015/06/05 18:37:13
renamed to `pattern_lhs` in a previous patch
| |
| 3089 classifier->is_valid_assignment_pattern() && | |
| 3090 (peek() == Token::LBRACK || peek() == Token::LBRACE); | |
| 3091 | |
| 2917 if (fni_ != NULL) fni_->Enter(); | 3092 if (fni_ != NULL) fni_->Enter(); |
| 2918 ParserBase<Traits>::Checkpoint checkpoint(this); | 3093 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2919 ExpressionClassifier arrow_formals_classifier; | 3094 ExpressionClassifier arrow_formals_classifier; |
| 2920 if (peek() != Token::LPAREN) { | 3095 if (peek() != Token::LPAREN) { |
| 2921 // The expression we are going to read is not a parenthesized arrow function | 3096 // The expression we are going to read is not a parenthesized arrow function |
| 2922 // formal parameter list. | 3097 // formal parameter list. |
| 2923 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 3098 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
| 2924 } | 3099 } |
| 3100 | |
| 2925 ExpressionT expression = this->ParseConditionalExpression( | 3101 ExpressionT expression = this->ParseConditionalExpression( |
| 2926 accept_IN, &arrow_formals_classifier, CHECK_OK); | 3102 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 3103 | |
| 3104 if (!arrow_formals_classifier.is_valid_assignment_pattern()) { | |
| 3105 if (maybeAssignmentPattern && peek() == Token::ASSIGN) { | |
| 3106 // ObjectAssignmentPattern or ArrayAssignmentPattern contains an error | |
| 3107 ReportClassifierError( | |
| 3108 arrow_formals_classifier.assignment_pattern_error()); | |
| 3109 *ok = false; | |
| 3110 return this->EmptyExpression(); | |
| 3111 } | |
| 3112 } | |
| 3113 | |
| 2927 classifier->Accumulate(arrow_formals_classifier); | 3114 classifier->Accumulate(arrow_formals_classifier); |
| 2928 | 3115 |
| 2929 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 3116 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2930 checkpoint.Restore(); | 3117 checkpoint.Restore(); |
| 2931 BindingPatternUnexpectedToken(classifier); | 3118 BindingPatternUnexpectedToken(classifier); |
| 3119 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY); | |
| 2932 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 3120 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
| 2933 CHECK_OK); | 3121 CHECK_OK); |
| 2934 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 3122 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2935 bool has_rest = false; | 3123 bool has_rest = false; |
| 2936 Scope* scope = | 3124 Scope* scope = |
| 2937 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); | 3125 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| 2938 scope->set_start_position(lhs_location.beg_pos); | 3126 scope->set_start_position(lhs_location.beg_pos); |
| 2939 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 3127 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2940 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, | 3128 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, |
| 2941 &duplicate_loc, CHECK_OK); | 3129 &duplicate_loc, CHECK_OK); |
| 2942 if (duplicate_loc.IsValid()) { | 3130 if (duplicate_loc.IsValid()) { |
| 2943 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 3131 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
| 2944 duplicate_loc); | 3132 duplicate_loc); |
| 2945 } | 3133 } |
| 2946 expression = this->ParseArrowFunctionLiteral( | 3134 expression = this->ParseArrowFunctionLiteral( |
| 2947 scope, has_rest, arrow_formals_classifier, CHECK_OK); | 3135 scope, has_rest, arrow_formals_classifier, CHECK_OK); |
| 2948 return expression; | 3136 return expression; |
| 2949 } | 3137 } |
| 2950 | 3138 |
| 2951 // "expression" was not itself an arrow function parameter list, but it might | 3139 // "expression" was not itself an arrow function parameter list, but it might |
| 2952 // form part of one. Propagate speculative formal parameter error locations. | 3140 // form part of one. Propagate speculative formal parameter error locations. |
| 2953 classifier->Accumulate(arrow_formals_classifier, | 3141 classifier->Accumulate(arrow_formals_classifier, |
| 2954 ExpressionClassifier::FormalParametersProduction); | 3142 ExpressionClassifier::FormalParametersProduction); |
| 2955 | 3143 |
| 3144 bool validDestructuringAssignmentTarget = | |
|
arv (Not doing code reviews)
2015/06/04 20:08:04
s/validDestructuringAssignmentTarget/valid_destruc
caitp (gmail)
2015/06/05 18:37:13
Done.
| |
| 3145 arrow_formals_classifier.IsValidSimpleAssignmentTarget(); | |
| 3146 if (validDestructuringAssignmentTarget) { | |
| 3147 classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier); | |
| 3148 } else if (!maybeAssignmentPattern || | |
| 3149 !arrow_formals_classifier.is_valid_assignment_pattern()) { | |
| 3150 // Potentially a bad DestructuringAssignmentTarget | |
| 3151 classifier->RecordAssignmentPatternError( | |
| 3152 Scanner::Location(lhs_location.beg_pos, scanner()->location().end_pos), | |
| 3153 MessageTemplate::kInvalidDestructuringAssignmentTarget); | |
| 3154 } | |
| 3155 | |
| 3156 if (maybeAssignmentPattern) { | |
| 3157 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN); | |
| 3158 } | |
| 3159 | |
| 2956 if (!Token::IsAssignmentOp(peek())) { | 3160 if (!Token::IsAssignmentOp(peek())) { |
| 2957 if (fni_ != NULL) fni_->Leave(); | 3161 if (fni_ != NULL) fni_->Leave(); |
| 2958 // Parsed conditional expression only (no assignment). | 3162 // Parsed conditional expression only (no assignment). |
| 2959 return expression; | 3163 return expression; |
| 2960 } | 3164 } |
| 2961 | 3165 |
| 2962 if (!allow_harmony_destructuring()) { | 3166 if (!allow_harmony_destructuring()) { |
| 2963 BindingPatternUnexpectedToken(classifier); | 3167 BindingPatternUnexpectedToken(classifier); |
| 2964 } | 3168 } |
| 2965 | 3169 |
| 2966 expression = this->CheckAndRewriteReferenceExpression( | 3170 if (!maybeAssignmentPattern || peek() != Token::ASSIGN) { |
| 2967 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, | 3171 expression = this->CheckAndRewriteReferenceExpression( |
| 2968 CHECK_OK); | 3172 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, |
| 3173 CHECK_OK); | |
| 3174 } | |
| 3175 | |
| 2969 expression = this->MarkExpressionAsAssigned(expression); | 3176 expression = this->MarkExpressionAsAssigned(expression); |
| 2970 | 3177 |
| 2971 Token::Value op = Next(); // Get assignment operator. | 3178 Token::Value op = Next(); // Get assignment operator. |
| 2972 if (op != Token::ASSIGN) { | 3179 if (op != Token::ASSIGN) { |
| 2973 classifier->RecordBindingPatternError(scanner()->location(), | 3180 classifier->RecordBindingPatternError(scanner()->location(), |
| 2974 MessageTemplate::kUnexpectedToken, | 3181 MessageTemplate::kUnexpectedToken, |
| 2975 Token::String(op)); | 3182 Token::String(op)); |
| 3183 } else { | |
| 3184 classifier->set_assigned(); | |
| 2976 } | 3185 } |
| 2977 int pos = position(); | 3186 int pos = position(); |
| 2978 | 3187 |
| 2979 ExpressionClassifier rhs_classifier; | 3188 ExpressionClassifier rhs_classifier; |
| 2980 ExpressionT right = | 3189 ExpressionT right = |
| 2981 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 3190 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
| 2982 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); | 3191 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); |
| 2983 | 3192 |
| 2984 // TODO(1231235): We try to estimate the set of properties set by | 3193 // TODO(1231235): We try to estimate the set of properties set by |
| 2985 // constructors. We define a new property whenever there is an | 3194 // constructors. We define a new property whenever there is an |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 3000 || op == Token::INIT_CONST_LEGACY | 3209 || op == Token::INIT_CONST_LEGACY |
| 3001 || op == Token::ASSIGN) | 3210 || op == Token::ASSIGN) |
| 3002 && (!right->IsCall() && !right->IsCallNew())) { | 3211 && (!right->IsCall() && !right->IsCallNew())) { |
| 3003 fni_->Infer(); | 3212 fni_->Infer(); |
| 3004 } else { | 3213 } else { |
| 3005 fni_->RemoveLastFunction(); | 3214 fni_->RemoveLastFunction(); |
| 3006 } | 3215 } |
| 3007 fni_->Leave(); | 3216 fni_->Leave(); |
| 3008 } | 3217 } |
| 3009 | 3218 |
| 3010 return factory()->NewAssignment(op, expression, right, pos); | 3219 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
| 3220 return this->CheckDestructuringAssignment(result, classifier, CHECK_OK); | |
| 3011 } | 3221 } |
| 3012 | 3222 |
| 3013 template <class Traits> | 3223 template <class Traits> |
| 3014 typename ParserBase<Traits>::ExpressionT | 3224 typename ParserBase<Traits>::ExpressionT |
| 3015 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 3225 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 3016 bool* ok) { | 3226 bool* ok) { |
| 3017 // YieldExpression :: | 3227 // YieldExpression :: |
| 3018 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 3228 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 3019 int pos = peek_position(); | 3229 int pos = peek_position(); |
| 3020 Expect(Token::YIELD, CHECK_OK); | 3230 Expect(Token::YIELD, CHECK_OK); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3067 // ConditionalExpression :: | 3277 // ConditionalExpression :: |
| 3068 // LogicalOrExpression | 3278 // LogicalOrExpression |
| 3069 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3279 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 3070 | 3280 |
| 3071 int pos = peek_position(); | 3281 int pos = peek_position(); |
| 3072 // We start using the binary expression parser for prec >= 4 only! | 3282 // We start using the binary expression parser for prec >= 4 only! |
| 3073 ExpressionT expression = | 3283 ExpressionT expression = |
| 3074 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 3284 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
| 3075 if (peek() != Token::CONDITIONAL) return expression; | 3285 if (peek() != Token::CONDITIONAL) return expression; |
| 3076 BindingPatternUnexpectedToken(classifier); | 3286 BindingPatternUnexpectedToken(classifier); |
| 3287 classifier->ReportInvalidSimpleAssignmentTarget(); | |
| 3077 Consume(Token::CONDITIONAL); | 3288 Consume(Token::CONDITIONAL); |
| 3078 // In parsing the first assignment expression in conditional | 3289 // In parsing the first assignment expression in conditional |
| 3079 // expressions we always accept the 'in' keyword; see ECMA-262, | 3290 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3080 // section 11.12, page 58. | 3291 // section 11.12, page 58. |
| 3081 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 3292 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 3082 Expect(Token::COLON, CHECK_OK); | 3293 Expect(Token::COLON, CHECK_OK); |
| 3083 ExpressionT right = | 3294 ExpressionT right = |
| 3084 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 3295 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
| 3085 return factory()->NewConditional(expression, left, right, pos); | 3296 return factory()->NewConditional(expression, left, right, pos); |
| 3086 } | 3297 } |
| 3087 | 3298 |
| 3088 | 3299 |
| 3089 // Precedence >= 4 | 3300 // Precedence >= 4 |
| 3090 template <class Traits> | 3301 template <class Traits> |
| 3091 typename ParserBase<Traits>::ExpressionT | 3302 typename ParserBase<Traits>::ExpressionT |
| 3092 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 3303 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 3093 ExpressionClassifier* classifier, | 3304 ExpressionClassifier* classifier, |
| 3094 bool* ok) { | 3305 bool* ok) { |
| 3095 DCHECK(prec >= 4); | 3306 DCHECK(prec >= 4); |
| 3096 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 3307 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 3097 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3308 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3098 // prec1 >= 4 | 3309 // prec1 >= 4 |
| 3099 while (Precedence(peek(), accept_IN) == prec1) { | 3310 while (Precedence(peek(), accept_IN) == prec1) { |
| 3100 BindingPatternUnexpectedToken(classifier); | 3311 BindingPatternUnexpectedToken(classifier); |
| 3312 classifier->ReportInvalidSimpleAssignmentTarget(); | |
| 3101 Token::Value op = Next(); | 3313 Token::Value op = Next(); |
| 3102 Scanner::Location op_location = scanner()->location(); | 3314 Scanner::Location op_location = scanner()->location(); |
| 3103 int pos = position(); | 3315 int pos = position(); |
| 3104 ExpressionT y = | 3316 ExpressionT y = |
| 3105 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); | 3317 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
| 3106 | 3318 |
| 3107 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 3319 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 3108 factory())) { | 3320 factory())) { |
| 3109 continue; | 3321 continue; |
| 3110 } | 3322 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3153 // '++' UnaryExpression | 3365 // '++' UnaryExpression |
| 3154 // '--' UnaryExpression | 3366 // '--' UnaryExpression |
| 3155 // '+' UnaryExpression | 3367 // '+' UnaryExpression |
| 3156 // '-' UnaryExpression | 3368 // '-' UnaryExpression |
| 3157 // '~' UnaryExpression | 3369 // '~' UnaryExpression |
| 3158 // '!' UnaryExpression | 3370 // '!' UnaryExpression |
| 3159 | 3371 |
| 3160 Token::Value op = peek(); | 3372 Token::Value op = peek(); |
| 3161 if (Token::IsUnaryOp(op)) { | 3373 if (Token::IsUnaryOp(op)) { |
| 3162 BindingPatternUnexpectedToken(classifier); | 3374 BindingPatternUnexpectedToken(classifier); |
| 3163 | 3375 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3164 op = Next(); | 3376 op = Next(); |
| 3165 int pos = position(); | 3377 int pos = position(); |
| 3166 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 3378 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 3167 | 3379 |
| 3168 if (op == Token::DELETE && is_strict(language_mode())) { | 3380 if (op == Token::DELETE && is_strict(language_mode())) { |
| 3169 if (is_strong(language_mode())) { | 3381 if (is_strong(language_mode())) { |
| 3170 ReportMessage(MessageTemplate::kStrongDelete); | 3382 ReportMessage(MessageTemplate::kStrongDelete); |
| 3171 *ok = false; | 3383 *ok = false; |
| 3172 return this->EmptyExpression(); | 3384 return this->EmptyExpression(); |
| 3173 } else if (this->IsIdentifier(expression)) { | 3385 } else if (this->IsIdentifier(expression)) { |
| 3174 // "delete identifier" is a syntax error in strict mode. | 3386 // "delete identifier" is a syntax error in strict mode. |
| 3175 ReportMessage(MessageTemplate::kStrictDelete); | 3387 ReportMessage(MessageTemplate::kStrictDelete); |
| 3176 *ok = false; | 3388 *ok = false; |
| 3177 return this->EmptyExpression(); | 3389 return this->EmptyExpression(); |
| 3178 } | 3390 } |
| 3179 } | 3391 } |
| 3180 | 3392 |
| 3181 // Allow Traits do rewrite the expression. | 3393 // Allow Traits do rewrite the expression. |
| 3182 return this->BuildUnaryExpression(expression, op, pos, factory()); | 3394 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 3183 } else if (Token::IsCountOp(op)) { | 3395 } else if (Token::IsCountOp(op)) { |
| 3184 BindingPatternUnexpectedToken(classifier); | 3396 BindingPatternUnexpectedToken(classifier); |
| 3397 classifier->ReportInvalidSimpleAssignmentTarget(); | |
| 3185 op = Next(); | 3398 op = Next(); |
| 3186 Scanner::Location lhs_location = scanner()->peek_location(); | 3399 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3187 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 3400 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 3188 expression = this->CheckAndRewriteReferenceExpression( | 3401 expression = this->CheckAndRewriteReferenceExpression( |
| 3189 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, | 3402 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, |
| 3190 CHECK_OK); | 3403 CHECK_OK); |
| 3191 this->MarkExpressionAsAssigned(expression); | 3404 this->MarkExpressionAsAssigned(expression); |
| 3192 | 3405 |
| 3193 return factory()->NewCountOperation(op, | 3406 return factory()->NewCountOperation(op, |
| 3194 true /* prefix */, | 3407 true /* prefix */, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3207 bool* ok) { | 3420 bool* ok) { |
| 3208 // PostfixExpression :: | 3421 // PostfixExpression :: |
| 3209 // LeftHandSideExpression ('++' | '--')? | 3422 // LeftHandSideExpression ('++' | '--')? |
| 3210 | 3423 |
| 3211 Scanner::Location lhs_location = scanner()->peek_location(); | 3424 Scanner::Location lhs_location = scanner()->peek_location(); |
| 3212 ExpressionT expression = | 3425 ExpressionT expression = |
| 3213 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 3426 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 3214 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3427 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 3215 Token::IsCountOp(peek())) { | 3428 Token::IsCountOp(peek())) { |
| 3216 BindingPatternUnexpectedToken(classifier); | 3429 BindingPatternUnexpectedToken(classifier); |
| 3217 | 3430 classifier->ReportInvalidSimpleAssignmentTarget(); |
| 3218 expression = this->CheckAndRewriteReferenceExpression( | 3431 expression = this->CheckAndRewriteReferenceExpression( |
| 3219 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, | 3432 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, |
| 3220 CHECK_OK); | 3433 CHECK_OK); |
| 3221 expression = this->MarkExpressionAsAssigned(expression); | 3434 expression = this->MarkExpressionAsAssigned(expression); |
| 3222 | 3435 |
| 3223 Token::Value next = Next(); | 3436 Token::Value next = Next(); |
| 3224 expression = | 3437 expression = |
| 3225 factory()->NewCountOperation(next, | 3438 factory()->NewCountOperation(next, |
| 3226 false /* postfix */, | 3439 false /* postfix */, |
| 3227 expression, | 3440 expression, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3238 // LeftHandSideExpression :: | 3451 // LeftHandSideExpression :: |
| 3239 // (NewExpression | MemberExpression) ... | 3452 // (NewExpression | MemberExpression) ... |
| 3240 | 3453 |
| 3241 ExpressionT result = | 3454 ExpressionT result = |
| 3242 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3455 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3243 | 3456 |
| 3244 while (true) { | 3457 while (true) { |
| 3245 switch (peek()) { | 3458 switch (peek()) { |
| 3246 case Token::LBRACK: { | 3459 case Token::LBRACK: { |
| 3247 BindingPatternUnexpectedToken(classifier); | 3460 BindingPatternUnexpectedToken(classifier); |
| 3461 classifier->AppendAssignmentTarget( | |
| 3462 ExpressionClassifier::TARGET_PROPERTY); | |
| 3248 Consume(Token::LBRACK); | 3463 Consume(Token::LBRACK); |
| 3249 int pos = position(); | 3464 int pos = position(); |
| 3250 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 3465 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
| 3251 result = factory()->NewProperty(result, index, pos); | 3466 result = factory()->NewProperty(result, index, pos); |
| 3252 Expect(Token::RBRACK, CHECK_OK); | 3467 Expect(Token::RBRACK, CHECK_OK); |
| 3253 break; | 3468 break; |
| 3254 } | 3469 } |
| 3255 | 3470 |
| 3256 case Token::LPAREN: { | 3471 case Token::LPAREN: { |
| 3257 BindingPatternUnexpectedToken(classifier); | 3472 BindingPatternUnexpectedToken(classifier); |
| 3258 | 3473 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); |
| 3259 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 3474 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
| 3260 this->IsEval(this->AsIdentifier(result))) { | 3475 this->IsEval(this->AsIdentifier(result))) { |
| 3261 ReportMessage(MessageTemplate::kStrongDirectEval); | 3476 ReportMessage(MessageTemplate::kStrongDirectEval); |
| 3262 *ok = false; | 3477 *ok = false; |
| 3263 return this->EmptyExpression(); | 3478 return this->EmptyExpression(); |
| 3264 } | 3479 } |
| 3265 int pos; | 3480 int pos; |
| 3266 if (scanner()->current_token() == Token::IDENTIFIER) { | 3481 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3267 // For call of an identifier we want to report position of | 3482 // For call of an identifier we want to report position of |
| 3268 // the identifier as position of the call in the stack trace. | 3483 // the identifier as position of the call in the stack trace. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3299 result = Traits::SpreadCall(result, args, pos); | 3514 result = Traits::SpreadCall(result, args, pos); |
| 3300 } else { | 3515 } else { |
| 3301 result = factory()->NewCall(result, args, pos); | 3516 result = factory()->NewCall(result, args, pos); |
| 3302 } | 3517 } |
| 3303 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3518 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3304 break; | 3519 break; |
| 3305 } | 3520 } |
| 3306 | 3521 |
| 3307 case Token::PERIOD: { | 3522 case Token::PERIOD: { |
| 3308 BindingPatternUnexpectedToken(classifier); | 3523 BindingPatternUnexpectedToken(classifier); |
| 3524 classifier->AppendAssignmentTarget( | |
| 3525 ExpressionClassifier::TARGET_PROPERTY); | |
| 3309 Consume(Token::PERIOD); | 3526 Consume(Token::PERIOD); |
| 3310 int pos = position(); | 3527 int pos = position(); |
| 3311 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3528 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3312 result = factory()->NewProperty( | 3529 result = factory()->NewProperty( |
| 3313 result, factory()->NewStringLiteral(name, pos), pos); | 3530 result, factory()->NewStringLiteral(name, pos), pos); |
| 3314 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 3531 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
| 3315 break; | 3532 break; |
| 3316 } | 3533 } |
| 3317 | 3534 |
| 3318 default: | 3535 default: |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3338 // Examples of new expression: | 3555 // Examples of new expression: |
| 3339 // new foo.bar().baz means (new (foo.bar)()).baz | 3556 // new foo.bar().baz means (new (foo.bar)()).baz |
| 3340 // new foo()() means (new foo())() | 3557 // new foo()() means (new foo())() |
| 3341 // new new foo()() means (new (new foo())()) | 3558 // new new foo()() means (new (new foo())()) |
| 3342 // new new foo means new (new foo) | 3559 // new new foo means new (new foo) |
| 3343 // new new foo() means new (new foo()) | 3560 // new new foo() means new (new foo()) |
| 3344 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3561 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 3345 | 3562 |
| 3346 if (peek() == Token::NEW) { | 3563 if (peek() == Token::NEW) { |
| 3347 BindingPatternUnexpectedToken(classifier); | 3564 BindingPatternUnexpectedToken(classifier); |
| 3565 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
| 3348 Consume(Token::NEW); | 3566 Consume(Token::NEW); |
| 3349 int new_pos = position(); | 3567 int new_pos = position(); |
| 3350 ExpressionT result = this->EmptyExpression(); | 3568 ExpressionT result = this->EmptyExpression(); |
| 3351 if (peek() == Token::SUPER) { | 3569 if (peek() == Token::SUPER) { |
| 3352 const bool is_new = true; | 3570 const bool is_new = true; |
| 3353 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3571 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
| 3354 } else { | 3572 } else { |
| 3355 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3573 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 3356 } | 3574 } |
| 3357 if (peek() == Token::LPAREN) { | 3575 if (peek() == Token::LPAREN) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3389 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3607 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 3390 | 3608 |
| 3391 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3609 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 3392 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3610 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 3393 // caller. | 3611 // caller. |
| 3394 | 3612 |
| 3395 // Parse the initial primary or function expression. | 3613 // Parse the initial primary or function expression. |
| 3396 ExpressionT result = this->EmptyExpression(); | 3614 ExpressionT result = this->EmptyExpression(); |
| 3397 if (peek() == Token::FUNCTION) { | 3615 if (peek() == Token::FUNCTION) { |
| 3398 BindingPatternUnexpectedToken(classifier); | 3616 BindingPatternUnexpectedToken(classifier); |
| 3399 | 3617 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY); |
| 3400 Consume(Token::FUNCTION); | 3618 Consume(Token::FUNCTION); |
| 3401 int function_token_position = position(); | 3619 int function_token_position = position(); |
| 3402 bool is_generator = Check(Token::MUL); | 3620 bool is_generator = Check(Token::MUL); |
| 3403 IdentifierT name = this->EmptyIdentifier(); | 3621 IdentifierT name = this->EmptyIdentifier(); |
| 3404 bool is_strict_reserved_name = false; | 3622 bool is_strict_reserved_name = false; |
| 3405 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3623 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3406 FunctionLiteral::FunctionType function_type = | 3624 FunctionLiteral::FunctionType function_type = |
| 3407 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3625 FunctionLiteral::ANONYMOUS_EXPRESSION; |
| 3408 if (peek_any_identifier()) { | 3626 if (peek_any_identifier()) { |
| 3409 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3627 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3578 while (scope->is_eval_scope() || scope->is_arrow_scope()) { | 3796 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
| 3579 scope = scope->outer_scope(); | 3797 scope = scope->outer_scope(); |
| 3580 DCHECK_NOT_NULL(scope); | 3798 DCHECK_NOT_NULL(scope); |
| 3581 scope = scope->DeclarationScope(); | 3799 scope = scope->DeclarationScope(); |
| 3582 } | 3800 } |
| 3583 | 3801 |
| 3584 FunctionKind kind = scope->function_kind(); | 3802 FunctionKind kind = scope->function_kind(); |
| 3585 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3803 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 3586 i::IsConstructor(kind)) { | 3804 i::IsConstructor(kind)) { |
| 3587 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3805 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 3806 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY); | |
| 3588 scope->RecordSuperPropertyUsage(); | 3807 scope->RecordSuperPropertyUsage(); |
| 3589 return this->SuperPropertyReference(scope_, factory(), pos); | 3808 return this->SuperPropertyReference(scope_, factory(), pos); |
| 3590 } | 3809 } |
| 3591 // new super() is never allowed. | 3810 // new super() is never allowed. |
| 3592 // super() is only allowed in derived constructor | 3811 // super() is only allowed in derived constructor |
| 3593 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3812 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 3813 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
| 3594 if (is_strong(language_mode())) { | 3814 if (is_strong(language_mode())) { |
| 3595 // Super calls in strong mode are parsed separately. | 3815 // Super calls in strong mode are parsed separately. |
| 3596 ReportMessageAt(scanner()->location(), | 3816 ReportMessageAt(scanner()->location(), |
| 3597 MessageTemplate::kStrongConstructorSuper); | 3817 MessageTemplate::kStrongConstructorSuper); |
| 3598 *ok = false; | 3818 *ok = false; |
| 3599 return this->EmptyExpression(); | 3819 return this->EmptyExpression(); |
| 3600 } | 3820 } |
| 3601 // TODO(rossberg): This might not be the correct FunctionState for the | 3821 // TODO(rossberg): This might not be the correct FunctionState for the |
| 3602 // method here. | 3822 // method here. |
| 3603 function_state_->set_super_location(scanner()->location()); | 3823 function_state_->set_super_location(scanner()->location()); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3614 template <class Traits> | 3834 template <class Traits> |
| 3615 typename ParserBase<Traits>::ExpressionT | 3835 typename ParserBase<Traits>::ExpressionT |
| 3616 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3836 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 3617 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3837 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| 3618 // Parses this part of MemberExpression: | 3838 // Parses this part of MemberExpression: |
| 3619 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3839 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 3620 while (true) { | 3840 while (true) { |
| 3621 switch (peek()) { | 3841 switch (peek()) { |
| 3622 case Token::LBRACK: { | 3842 case Token::LBRACK: { |
| 3623 BindingPatternUnexpectedToken(classifier); | 3843 BindingPatternUnexpectedToken(classifier); |
| 3624 | 3844 classifier->AppendAssignmentTarget( |
| 3845 ExpressionClassifier::TARGET_PROPERTY); | |
| 3625 Consume(Token::LBRACK); | 3846 Consume(Token::LBRACK); |
| 3626 int pos = position(); | 3847 int pos = position(); |
| 3627 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3848 // Ignore pattern errors within expression |
| 3849 ExpressionClassifier prop_classifier; | |
| 3850 ExpressionT index = | |
| 3851 this->ParseExpression(true, &prop_classifier, CHECK_OK); | |
| 3628 expression = factory()->NewProperty(expression, index, pos); | 3852 expression = factory()->NewProperty(expression, index, pos); |
| 3629 if (fni_ != NULL) { | 3853 if (fni_ != NULL) { |
| 3630 this->PushPropertyName(fni_, index); | 3854 this->PushPropertyName(fni_, index); |
| 3631 } | 3855 } |
| 3632 Expect(Token::RBRACK, CHECK_OK); | 3856 Expect(Token::RBRACK, CHECK_OK); |
| 3633 break; | 3857 break; |
| 3634 } | 3858 } |
| 3635 case Token::PERIOD: { | 3859 case Token::PERIOD: { |
| 3636 BindingPatternUnexpectedToken(classifier); | 3860 BindingPatternUnexpectedToken(classifier); |
| 3861 classifier->AppendAssignmentTarget( | |
| 3862 ExpressionClassifier::TARGET_PROPERTY); | |
| 3637 | 3863 |
| 3638 Consume(Token::PERIOD); | 3864 Consume(Token::PERIOD); |
| 3639 int pos = position(); | 3865 int pos = position(); |
| 3640 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3866 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 3641 expression = factory()->NewProperty( | 3867 expression = factory()->NewProperty( |
| 3642 expression, factory()->NewStringLiteral(name, pos), pos); | 3868 expression, factory()->NewStringLiteral(name, pos), pos); |
| 3643 if (fni_ != NULL) { | 3869 if (fni_ != NULL) { |
| 3644 this->PushLiteralName(fni_, name); | 3870 this->PushLiteralName(fni_, name); |
| 3645 } | 3871 } |
| 3646 break; | 3872 break; |
| 3647 } | 3873 } |
| 3648 case Token::TEMPLATE_SPAN: | 3874 case Token::TEMPLATE_SPAN: |
| 3649 case Token::TEMPLATE_TAIL: { | 3875 case Token::TEMPLATE_TAIL: { |
| 3650 BindingPatternUnexpectedToken(classifier); | 3876 BindingPatternUnexpectedToken(classifier); |
| 3877 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
| 3651 int pos; | 3878 int pos; |
| 3652 if (scanner()->current_token() == Token::IDENTIFIER) { | 3879 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3653 pos = position(); | 3880 pos = position(); |
| 3654 } else { | 3881 } else { |
| 3655 pos = peek_position(); | 3882 pos = peek_position(); |
| 3656 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3883 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3657 // If the tag function looks like an IIFE, set_parenthesized() to | 3884 // If the tag function looks like an IIFE, set_parenthesized() to |
| 3658 // force eager compilation. | 3885 // force eager compilation. |
| 3659 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3886 expression->AsFunctionLiteral()->set_should_eager_compile(); |
| 3660 } | 3887 } |
| 3661 } | 3888 } |
| 3889 // Ignore classifying tagged template | |
| 3890 ExpressionClassifier call_classifier; | |
| 3662 expression = | 3891 expression = |
| 3663 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | 3892 ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK); |
| 3664 break; | 3893 break; |
| 3665 } | 3894 } |
| 3666 default: | 3895 default: |
| 3667 return expression; | 3896 return expression; |
| 3668 } | 3897 } |
| 3669 } | 3898 } |
| 3670 DCHECK(false); | 3899 DCHECK(false); |
| 3671 return this->EmptyExpression(); | 3900 return this->EmptyExpression(); |
| 3672 } | 3901 } |
| 3673 | 3902 |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4045 *ok = false; | 4274 *ok = false; |
| 4046 return; | 4275 return; |
| 4047 } | 4276 } |
| 4048 has_seen_constructor_ = true; | 4277 has_seen_constructor_ = true; |
| 4049 return; | 4278 return; |
| 4050 } | 4279 } |
| 4051 } | 4280 } |
| 4052 } } // v8::internal | 4281 } } // v8::internal |
| 4053 | 4282 |
| 4054 #endif // V8_PREPARSER_H | 4283 #endif // V8_PREPARSER_H |
| OLD | NEW |