OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/bailout-reason.h" | 8 #include "src/bailout-reason.h" |
9 #include "src/expression-classifier.h" | 9 #include "src/expression-classifier.h" |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 kSyntaxError); | 541 kSyntaxError); |
542 } | 542 } |
543 | 543 |
544 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { | 544 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { |
545 if (!classifier->is_valid_expression()) { | 545 if (!classifier->is_valid_expression()) { |
546 ReportClassifierError(classifier->expression_error()); | 546 ReportClassifierError(classifier->expression_error()); |
547 *ok = false; | 547 *ok = false; |
548 } | 548 } |
549 } | 549 } |
550 | 550 |
| 551 void ValidateFormalParameterInitializer( |
| 552 const ExpressionClassifier* classifier, bool* ok) { |
| 553 if (!classifier->is_valid_formal_parameter_initializer()) { |
| 554 ReportClassifierError(classifier->formal_parameter_initializer_error()); |
| 555 *ok = false; |
| 556 } |
| 557 } |
| 558 |
551 void ValidateBindingPattern(const ExpressionClassifier* classifier, | 559 void ValidateBindingPattern(const ExpressionClassifier* classifier, |
552 bool* ok) { | 560 bool* ok) { |
553 if (!classifier->is_valid_binding_pattern()) { | 561 if (!classifier->is_valid_binding_pattern()) { |
554 ReportClassifierError(classifier->binding_pattern_error()); | 562 ReportClassifierError(classifier->binding_pattern_error()); |
555 *ok = false; | 563 *ok = false; |
556 } | 564 } |
557 } | 565 } |
558 | 566 |
559 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, | 567 void ValidateAssignmentPattern(const ExpressionClassifier* classifier, |
560 bool* ok) { | 568 bool* ok) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 } | 630 } |
623 | 631 |
624 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { | 632 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { |
625 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 633 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
626 const char* arg; | 634 const char* arg; |
627 GetUnexpectedTokenMessage(peek(), &message, &arg); | 635 GetUnexpectedTokenMessage(peek(), &message, &arg); |
628 classifier->RecordArrowFormalParametersError(scanner()->peek_location(), | 636 classifier->RecordArrowFormalParametersError(scanner()->peek_location(), |
629 message, arg); | 637 message, arg); |
630 } | 638 } |
631 | 639 |
| 640 void FormalParameterInitializerUnexpectedToken( |
| 641 ExpressionClassifier* classifier) { |
| 642 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| 643 const char* arg; |
| 644 GetUnexpectedTokenMessage(peek(), &message, &arg); |
| 645 classifier->RecordFormalParameterInitializerError( |
| 646 scanner()->peek_location(), message, arg); |
| 647 } |
| 648 |
632 // Recursive descent functions: | 649 // Recursive descent functions: |
633 | 650 |
634 // Parses an identifier that is valid for the current scope, in particular it | 651 // Parses an identifier that is valid for the current scope, in particular it |
635 // fails on strict mode future reserved keywords in a strict scope. If | 652 // fails on strict mode future reserved keywords in a strict scope. If |
636 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 653 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
637 // "arguments" as identifier even in strict mode (this is needed in cases like | 654 // "arguments" as identifier even in strict mode (this is needed in cases like |
638 // "var foo = eval;"). | 655 // "var foo = eval;"). |
639 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 656 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
640 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 657 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
641 bool* ok); | 658 bool* ok); |
(...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2515 *name = this->GetNumberAsSymbol(scanner()); | 2532 *name = this->GetNumberAsSymbol(scanner()); |
2516 break; | 2533 break; |
2517 | 2534 |
2518 case Token::LBRACK: { | 2535 case Token::LBRACK: { |
2519 *is_computed_name = true; | 2536 *is_computed_name = true; |
2520 Consume(Token::LBRACK); | 2537 Consume(Token::LBRACK); |
2521 ExpressionClassifier computed_name_classifier; | 2538 ExpressionClassifier computed_name_classifier; |
2522 ExpressionT expression = | 2539 ExpressionT expression = |
2523 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 2540 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
2524 classifier->Accumulate(computed_name_classifier, | 2541 classifier->Accumulate(computed_name_classifier, |
2525 ExpressionClassifier::ExpressionProduction); | 2542 ExpressionClassifier::ExpressionProductions); |
2526 Expect(Token::RBRACK, CHECK_OK); | 2543 Expect(Token::RBRACK, CHECK_OK); |
2527 return expression; | 2544 return expression; |
2528 } | 2545 } |
2529 | 2546 |
2530 case Token::STATIC: | 2547 case Token::STATIC: |
2531 *is_static = true; | 2548 *is_static = true; |
2532 | 2549 |
2533 // Fall through. | 2550 // Fall through. |
2534 default: | 2551 default: |
2535 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 2552 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 | 2678 |
2662 ExpressionT lhs = this->ExpressionFromIdentifier( | 2679 ExpressionT lhs = this->ExpressionFromIdentifier( |
2663 name, next_beg_pos, next_end_pos, scope_, factory()); | 2680 name, next_beg_pos, next_end_pos, scope_, factory()); |
2664 if (peek() == Token::ASSIGN) { | 2681 if (peek() == Token::ASSIGN) { |
2665 this->ExpressionUnexpectedToken(classifier); | 2682 this->ExpressionUnexpectedToken(classifier); |
2666 Consume(Token::ASSIGN); | 2683 Consume(Token::ASSIGN); |
2667 ExpressionClassifier rhs_classifier; | 2684 ExpressionClassifier rhs_classifier; |
2668 ExpressionT rhs = this->ParseAssignmentExpression( | 2685 ExpressionT rhs = this->ParseAssignmentExpression( |
2669 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2686 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2670 classifier->Accumulate(rhs_classifier, | 2687 classifier->Accumulate(rhs_classifier, |
2671 ExpressionClassifier::ExpressionProduction); | 2688 ExpressionClassifier::ExpressionProductions); |
2672 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2689 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2673 RelocInfo::kNoPosition); | 2690 RelocInfo::kNoPosition); |
2674 } else { | 2691 } else { |
2675 value = lhs; | 2692 value = lhs; |
2676 } | 2693 } |
2677 return factory()->NewObjectLiteralProperty( | 2694 return factory()->NewObjectLiteralProperty( |
2678 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); | 2695 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); |
2679 | 2696 |
2680 } else { | 2697 } else { |
2681 Token::Value next = Next(); | 2698 Token::Value next = Next(); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2903 classifier->RecordBindingPatternError(scanner()->location(), | 2920 classifier->RecordBindingPatternError(scanner()->location(), |
2904 MessageTemplate::kUnexpectedToken, | 2921 MessageTemplate::kUnexpectedToken, |
2905 Token::String(op)); | 2922 Token::String(op)); |
2906 } | 2923 } |
2907 int pos = position(); | 2924 int pos = position(); |
2908 | 2925 |
2909 ExpressionClassifier rhs_classifier; | 2926 ExpressionClassifier rhs_classifier; |
2910 ExpressionT right = | 2927 ExpressionT right = |
2911 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2928 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
2912 classifier->Accumulate(rhs_classifier, | 2929 classifier->Accumulate(rhs_classifier, |
2913 ExpressionClassifier::ExpressionProduction); | 2930 ExpressionClassifier::ExpressionProductions); |
2914 | 2931 |
2915 // TODO(1231235): We try to estimate the set of properties set by | 2932 // TODO(1231235): We try to estimate the set of properties set by |
2916 // constructors. We define a new property whenever there is an | 2933 // constructors. We define a new property whenever there is an |
2917 // assignment to a property of 'this'. We should probably only add | 2934 // assignment to a property of 'this'. We should probably only add |
2918 // properties if we haven't seen them before. Otherwise we'll | 2935 // properties if we haven't seen them before. Otherwise we'll |
2919 // probably overestimate the number of properties. | 2936 // probably overestimate the number of properties. |
2920 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2937 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
2921 function_state_->AddProperty(); | 2938 function_state_->AddProperty(); |
2922 } | 2939 } |
2923 | 2940 |
(...skipping 18 matching lines...) Expand all Loading... |
2942 } | 2959 } |
2943 | 2960 |
2944 template <class Traits> | 2961 template <class Traits> |
2945 typename ParserBase<Traits>::ExpressionT | 2962 typename ParserBase<Traits>::ExpressionT |
2946 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, | 2963 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
2947 bool* ok) { | 2964 bool* ok) { |
2948 // YieldExpression :: | 2965 // YieldExpression :: |
2949 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2966 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2950 int pos = peek_position(); | 2967 int pos = peek_position(); |
2951 BindingPatternUnexpectedToken(classifier); | 2968 BindingPatternUnexpectedToken(classifier); |
| 2969 FormalParameterInitializerUnexpectedToken(classifier); |
2952 Expect(Token::YIELD, CHECK_OK); | 2970 Expect(Token::YIELD, CHECK_OK); |
2953 ExpressionT generator_object = | 2971 ExpressionT generator_object = |
2954 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2972 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
2955 ExpressionT expression = Traits::EmptyExpression(); | 2973 ExpressionT expression = Traits::EmptyExpression(); |
2956 Yield::Kind kind = Yield::kSuspend; | 2974 Yield::Kind kind = Yield::kSuspend; |
2957 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2975 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2958 if (Check(Token::MUL)) kind = Yield::kDelegating; | 2976 if (Check(Token::MUL)) kind = Yield::kDelegating; |
2959 switch (peek()) { | 2977 switch (peek()) { |
2960 case Token::EOS: | 2978 case Token::EOS: |
2961 case Token::SEMICOLON: | 2979 case Token::SEMICOLON: |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3669 ValidateBindingPattern(classifier, ok); | 3687 ValidateBindingPattern(classifier, ok); |
3670 if (!*ok) return; | 3688 if (!*ok) return; |
3671 | 3689 |
3672 if (!Traits::IsIdentifier(pattern)) { | 3690 if (!Traits::IsIdentifier(pattern)) { |
3673 if (is_rest || !allow_harmony_destructuring()) { | 3691 if (is_rest || !allow_harmony_destructuring()) { |
3674 ReportUnexpectedToken(next); | 3692 ReportUnexpectedToken(next); |
3675 *ok = false; | 3693 *ok = false; |
3676 return; | 3694 return; |
3677 } | 3695 } |
3678 parameters->is_simple = false; | 3696 parameters->is_simple = false; |
| 3697 ValidateFormalParameterInitializer(classifier, ok); |
| 3698 if (!*ok) return; |
3679 classifier->RecordNonSimpleParameter(); | 3699 classifier->RecordNonSimpleParameter(); |
3680 } | 3700 } |
3681 | 3701 |
3682 ExpressionT initializer = Traits::EmptyExpression(); | 3702 ExpressionT initializer = Traits::EmptyExpression(); |
3683 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { | 3703 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { |
3684 ExpressionClassifier init_classifier; | 3704 ExpressionClassifier init_classifier; |
3685 initializer = ParseAssignmentExpression(true, &init_classifier, ok); | 3705 initializer = ParseAssignmentExpression(true, &init_classifier, ok); |
3686 if (!*ok) return; | 3706 if (!*ok) return; |
3687 ValidateExpression(&init_classifier, ok); | 3707 ValidateExpression(&init_classifier, ok); |
| 3708 ValidateFormalParameterInitializer(&init_classifier, ok); |
3688 if (!*ok) return; | 3709 if (!*ok) return; |
3689 parameters->is_simple = false; | 3710 parameters->is_simple = false; |
3690 classifier->RecordNonSimpleParameter(); | 3711 classifier->RecordNonSimpleParameter(); |
3691 } | 3712 } |
3692 | 3713 |
3693 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); | 3714 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); |
3694 } | 3715 } |
3695 | 3716 |
3696 | 3717 |
3697 template <class Traits> | 3718 template <class Traits> |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4076 *ok = false; | 4097 *ok = false; |
4077 return; | 4098 return; |
4078 } | 4099 } |
4079 has_seen_constructor_ = true; | 4100 has_seen_constructor_ = true; |
4080 return; | 4101 return; |
4081 } | 4102 } |
4082 } | 4103 } |
4083 } } // v8::internal | 4104 } } // v8::internal |
4084 | 4105 |
4085 #endif // V8_PREPARSER_H | 4106 #endif // V8_PREPARSER_H |
OLD | NEW |