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

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: Fix arrow function parsing 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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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