Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/preparser.h

Issue 1168643005: [es6] parse destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Nits ForIn/Of tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698