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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 const FormalParametersT& parameters, | 788 const FormalParametersT& parameters, |
789 const ExpressionClassifier& classifier, | 789 const ExpressionClassifier& classifier, |
790 bool* ok); | 790 bool* ok); |
791 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 791 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
792 ExpressionClassifier* classifier, bool* ok); | 792 ExpressionClassifier* classifier, bool* ok); |
793 void AddTemplateExpression(ExpressionT); | 793 void AddTemplateExpression(ExpressionT); |
794 ExpressionT ParseSuperExpression(bool is_new, | 794 ExpressionT ParseSuperExpression(bool is_new, |
795 ExpressionClassifier* classifier, bool* ok); | 795 ExpressionClassifier* classifier, bool* ok); |
796 ExpressionT ParseNewTargetExpression(bool* ok); | 796 ExpressionT ParseNewTargetExpression(bool* ok); |
797 | 797 |
798 void ParseFormalParameter(FormalParametersT* parameters, | 798 void ParseFormalParameter(FormalParametersT* parameters, bool allow_optional, |
799 ExpressionClassifier* classifier, bool* ok); | 799 ExpressionClassifier* classifier, bool* ok); |
800 void ParseFormalParameterList(FormalParametersT* parameters, | 800 void ParseFormalParameterList(FormalParametersT* parameters, |
| 801 bool allow_optional, |
801 ExpressionClassifier* classifier, bool* ok); | 802 ExpressionClassifier* classifier, bool* ok); |
802 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 803 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
803 bool has_rest, int formals_start_pos, | 804 bool has_rest, int formals_start_pos, |
804 int formals_end_pos, bool* ok); | 805 int formals_end_pos, bool* ok); |
805 | 806 |
806 bool IsNextLetKeyword(); | 807 bool IsNextLetKeyword(); |
807 | 808 |
808 // Checks if the expression is a valid reference expression (e.g., on the | 809 // Checks if the expression is a valid reference expression (e.g., on the |
809 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 810 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
810 // we allow calls for web compatibility and rewrite them to a runtime throw. | 811 // we allow calls for web compatibility and rewrite them to a runtime throw. |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 1740 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
1740 false); | 1741 false); |
1741 } | 1742 } |
1742 } | 1743 } |
1743 | 1744 |
1744 // Method definitions are never valid in patterns. | 1745 // Method definitions are never valid in patterns. |
1745 classifier->RecordPatternError( | 1746 classifier->RecordPatternError( |
1746 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1747 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
1747 MessageTemplate::kInvalidDestructuringTarget); | 1748 MessageTemplate::kInvalidDestructuringTarget); |
1748 | 1749 |
1749 if (is_generator || peek() == Token::LPAREN) { | 1750 if (is_generator || peek() == Token::LPAREN || |
| 1751 (scope_->typed() && peek() == Token::LT)) { |
1750 // MethodDefinition | 1752 // MethodDefinition |
1751 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1753 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1752 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1754 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1753 if (!*is_computed_name) { | 1755 if (!*is_computed_name) { |
1754 checker->CheckProperty(name_token, kMethodProperty, is_static, | 1756 checker->CheckProperty(name_token, kMethodProperty, is_static, |
1755 is_generator, | 1757 is_generator, |
1756 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1758 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1757 } | 1759 } |
1758 | 1760 |
1759 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1761 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
1760 : FunctionKind::kConciseMethod; | 1762 : FunctionKind::kConciseMethod; |
| 1763 typesystem::TypeFlags type_flags = typesystem::kNormalTypes; |
1761 | 1764 |
1762 if (in_class && !is_static && this->IsConstructor(*name)) { | 1765 if (in_class && !is_static && this->IsConstructor(*name)) { |
1763 *has_seen_constructor = true; | 1766 *has_seen_constructor = true; |
1764 kind = has_extends ? FunctionKind::kSubclassConstructor | 1767 kind = has_extends ? FunctionKind::kSubclassConstructor |
1765 : FunctionKind::kBaseConstructor; | 1768 : FunctionKind::kBaseConstructor; |
| 1769 type_flags = typesystem::kConstructorTypes; |
1766 } | 1770 } |
1767 | 1771 |
1768 value = this->ParseFunctionLiteral( | 1772 value = this->ParseFunctionLiteral( |
1769 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 1773 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
1770 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 1774 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
1771 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1775 language_mode(), type_flags, |
| 1776 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1772 | 1777 |
1773 return factory()->NewObjectLiteralProperty(name_expression, value, | 1778 return factory()->NewObjectLiteralProperty(name_expression, value, |
1774 ObjectLiteralProperty::COMPUTED, | 1779 ObjectLiteralProperty::COMPUTED, |
1775 is_static, *is_computed_name); | 1780 is_static, *is_computed_name); |
1776 } | 1781 } |
1777 | 1782 |
1778 if (in_class && name_token == Token::STATIC && !is_static) { | 1783 if (in_class && name_token == Token::STATIC && !is_static) { |
1779 // ClassElement (static) | 1784 // ClassElement (static) |
1780 // 'static' MethodDefinition | 1785 // 'static' MethodDefinition |
1781 *name = this->EmptyIdentifier(); | 1786 *name = this->EmptyIdentifier(); |
(...skipping 19 matching lines...) Expand all Loading... |
1801 if (!*is_computed_name) { | 1806 if (!*is_computed_name) { |
1802 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 1807 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
1803 is_generator, | 1808 is_generator, |
1804 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1809 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1805 } | 1810 } |
1806 | 1811 |
1807 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 1812 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
1808 *name, scanner()->location(), kSkipFunctionNameCheck, | 1813 *name, scanner()->location(), kSkipFunctionNameCheck, |
1809 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, | 1814 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, |
1810 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, | 1815 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, |
1811 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1816 language_mode(), typesystem::kDisallowTypeParameters, |
| 1817 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1812 | 1818 |
1813 // Make sure the name expression is a string since we need a Name for | 1819 // Make sure the name expression is a string since we need a Name for |
1814 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 1820 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
1815 // statically we can skip the extra runtime check. | 1821 // statically we can skip the extra runtime check. |
1816 if (!*is_computed_name) { | 1822 if (!*is_computed_name) { |
1817 name_expression = | 1823 name_expression = |
1818 factory()->NewStringLiteral(*name, name_expression->position()); | 1824 factory()->NewStringLiteral(*name, name_expression->position()); |
1819 } | 1825 } |
1820 | 1826 |
1821 return factory()->NewObjectLiteralProperty( | 1827 return factory()->NewObjectLiteralProperty( |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2586 is_generator, &is_strict_reserved_name, CHECK_OK); | 2592 is_generator, &is_strict_reserved_name, CHECK_OK); |
2587 function_name_location = scanner()->location(); | 2593 function_name_location = scanner()->location(); |
2588 function_type = FunctionLiteral::kNamedExpression; | 2594 function_type = FunctionLiteral::kNamedExpression; |
2589 } | 2595 } |
2590 result = this->ParseFunctionLiteral( | 2596 result = this->ParseFunctionLiteral( |
2591 name, function_name_location, | 2597 name, function_name_location, |
2592 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 2598 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
2593 : kFunctionNameValidityUnknown, | 2599 : kFunctionNameValidityUnknown, |
2594 is_generator ? FunctionKind::kGeneratorFunction | 2600 is_generator ? FunctionKind::kGeneratorFunction |
2595 : FunctionKind::kNormalFunction, | 2601 : FunctionKind::kNormalFunction, |
2596 function_token_position, function_type, language_mode(), CHECK_OK); | 2602 function_token_position, function_type, language_mode(), |
| 2603 typesystem::kNormalTypes, CHECK_OK); |
2597 } else if (peek() == Token::SUPER) { | 2604 } else if (peek() == Token::SUPER) { |
2598 const bool is_new = false; | 2605 const bool is_new = false; |
2599 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 2606 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
2600 } else { | 2607 } else { |
2601 result = ParsePrimaryExpression(classifier, CHECK_OK); | 2608 result = ParsePrimaryExpression(classifier, CHECK_OK); |
2602 } | 2609 } |
2603 | 2610 |
2604 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 2611 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
2605 return result; | 2612 return result; |
2606 } | 2613 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2736 default: | 2743 default: |
2737 return expression; | 2744 return expression; |
2738 } | 2745 } |
2739 } | 2746 } |
2740 DCHECK(false); | 2747 DCHECK(false); |
2741 return this->EmptyExpression(); | 2748 return this->EmptyExpression(); |
2742 } | 2749 } |
2743 | 2750 |
2744 | 2751 |
2745 template <class Traits> | 2752 template <class Traits> |
2746 void ParserBase<Traits>::ParseFormalParameter( | 2753 void ParserBase<Traits>::ParseFormalParameter(FormalParametersT* parameters, |
2747 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 2754 bool allow_optional, |
| 2755 ExpressionClassifier* classifier, |
| 2756 bool* ok) { |
2748 // FormalParameter[Yield,GeneratorParameter] : | 2757 // FormalParameter[Yield,GeneratorParameter] : |
2749 // BindingElement[?Yield, ?GeneratorParameter] | 2758 // BindingElement[?Yield, ?GeneratorParameter] |
2750 bool is_rest = parameters->has_rest; | 2759 bool is_rest = parameters->has_rest; |
2751 | 2760 |
2752 ExpressionT pattern = ParsePrimaryExpression(classifier, ok); | 2761 ExpressionT pattern = ParsePrimaryExpression(classifier, ok); |
2753 if (!*ok) return; | 2762 if (!*ok) return; |
2754 | 2763 |
2755 ValidateBindingPattern(classifier, ok); | 2764 ValidateBindingPattern(classifier, ok); |
2756 if (!*ok) return; | 2765 if (!*ok) return; |
2757 | 2766 |
2758 if (!Traits::IsIdentifier(pattern)) { | 2767 if (!Traits::IsIdentifier(pattern)) { |
2759 parameters->is_simple = false; | 2768 parameters->is_simple = false; |
2760 ValidateFormalParameterInitializer(classifier, ok); | 2769 ValidateFormalParameterInitializer(classifier, ok); |
2761 if (!*ok) return; | 2770 if (!*ok) return; |
2762 classifier->RecordNonSimpleParameter(); | 2771 classifier->RecordNonSimpleParameter(); |
2763 } | 2772 } |
2764 | 2773 |
| 2774 // Parse optional question mark. |
| 2775 bool optional = false; |
| 2776 if (scope_->typed() && allow_optional) optional = Check(Token::CONDITIONAL); |
| 2777 |
| 2778 // Parse optional type annotation. |
| 2779 typename TypeSystem::Type type = this->EmptyType(); |
| 2780 if (scope_->typed() && Check(Token::COLON)) { |
| 2781 type = ParseValidType(ok); |
| 2782 if (!*ok) return; |
| 2783 } |
| 2784 USE(type); // TODO(nikolaos): really use it! |
| 2785 |
2765 ExpressionT initializer = Traits::EmptyExpression(); | 2786 ExpressionT initializer = Traits::EmptyExpression(); |
2766 if (!is_rest && Check(Token::ASSIGN)) { | 2787 if (!is_rest && !optional && Check(Token::ASSIGN)) { |
2767 ExpressionClassifier init_classifier(this); | 2788 ExpressionClassifier init_classifier(this); |
2768 initializer = ParseAssignmentExpression(true, &init_classifier, ok); | 2789 initializer = ParseAssignmentExpression(true, &init_classifier, ok); |
2769 if (!*ok) return; | 2790 if (!*ok) return; |
2770 Traits::RewriteNonPattern(&init_classifier, ok); | 2791 Traits::RewriteNonPattern(&init_classifier, ok); |
2771 ValidateFormalParameterInitializer(&init_classifier, ok); | 2792 ValidateFormalParameterInitializer(&init_classifier, ok); |
2772 if (!*ok) return; | 2793 if (!*ok) return; |
2773 parameters->is_simple = false; | 2794 parameters->is_simple = false; |
2774 init_classifier.Discard(); | 2795 init_classifier.Discard(); |
2775 classifier->RecordNonSimpleParameter(); | 2796 classifier->RecordNonSimpleParameter(); |
2776 | 2797 |
2777 if (allow_harmony_function_name()) { | 2798 if (allow_harmony_function_name()) { |
2778 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); | 2799 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); |
2779 } | 2800 } |
2780 } | 2801 } |
2781 | 2802 |
2782 Traits::AddFormalParameter(parameters, pattern, initializer, | 2803 Traits::AddFormalParameter(parameters, pattern, initializer, |
2783 scanner()->location().end_pos, is_rest); | 2804 scanner()->location().end_pos, is_rest); |
2784 } | 2805 } |
2785 | 2806 |
2786 | 2807 |
2787 template <class Traits> | 2808 template <class Traits> |
2788 void ParserBase<Traits>::ParseFormalParameterList( | 2809 void ParserBase<Traits>::ParseFormalParameterList( |
2789 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 2810 FormalParametersT* parameters, bool allow_optional, |
| 2811 ExpressionClassifier* classifier, bool* ok) { |
2790 // FormalParameters[Yield,GeneratorParameter] : | 2812 // FormalParameters[Yield,GeneratorParameter] : |
2791 // [empty] | 2813 // [empty] |
2792 // FormalParameterList[?Yield, ?GeneratorParameter] | 2814 // FormalParameterList[?Yield, ?GeneratorParameter] |
2793 // | 2815 // |
2794 // FormalParameterList[Yield,GeneratorParameter] : | 2816 // FormalParameterList[Yield,GeneratorParameter] : |
2795 // FunctionRestParameter[?Yield] | 2817 // FunctionRestParameter[?Yield] |
2796 // FormalsList[?Yield, ?GeneratorParameter] | 2818 // FormalsList[?Yield, ?GeneratorParameter] |
2797 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] | 2819 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] |
2798 // | 2820 // |
2799 // FormalsList[Yield,GeneratorParameter] : | 2821 // FormalsList[Yield,GeneratorParameter] : |
2800 // FormalParameter[?Yield, ?GeneratorParameter] | 2822 // FormalParameter[?Yield, ?GeneratorParameter] |
2801 // FormalsList[?Yield, ?GeneratorParameter] , | 2823 // FormalsList[?Yield, ?GeneratorParameter] , |
2802 // FormalParameter[?Yield,?GeneratorParameter] | 2824 // FormalParameter[?Yield,?GeneratorParameter] |
2803 | 2825 |
2804 DCHECK_EQ(0, parameters->Arity()); | 2826 DCHECK_EQ(0, parameters->Arity()); |
2805 | 2827 |
2806 if (peek() != Token::RPAREN) { | 2828 if (peek() != Token::RPAREN) { |
2807 do { | 2829 do { |
2808 if (parameters->Arity() > Code::kMaxArguments) { | 2830 if (parameters->Arity() > Code::kMaxArguments) { |
2809 ReportMessage(MessageTemplate::kTooManyParameters); | 2831 ReportMessage(MessageTemplate::kTooManyParameters); |
2810 *ok = false; | 2832 *ok = false; |
2811 return; | 2833 return; |
2812 } | 2834 } |
2813 parameters->has_rest = Check(Token::ELLIPSIS); | 2835 parameters->has_rest = Check(Token::ELLIPSIS); |
2814 ParseFormalParameter(parameters, classifier, ok); | 2836 ParseFormalParameter(parameters, allow_optional, classifier, ok); |
2815 if (!*ok) return; | 2837 if (!*ok) return; |
2816 } while (!parameters->has_rest && Check(Token::COMMA)); | 2838 } while (!parameters->has_rest && Check(Token::COMMA)); |
2817 | 2839 |
2818 if (parameters->has_rest) { | 2840 if (parameters->has_rest) { |
2819 parameters->is_simple = false; | 2841 parameters->is_simple = false; |
2820 classifier->RecordNonSimpleParameter(); | 2842 classifier->RecordNonSimpleParameter(); |
2821 if (peek() == Token::COMMA) { | 2843 if (peek() == Token::COMMA) { |
2822 ReportMessageAt(scanner()->peek_location(), | 2844 ReportMessageAt(scanner()->peek_location(), |
2823 MessageTemplate::kParamAfterRest); | 2845 MessageTemplate::kParamAfterRest); |
2824 *ok = false; | 2846 *ok = false; |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3635 has_seen_constructor_ = true; | 3657 has_seen_constructor_ = true; |
3636 return; | 3658 return; |
3637 } | 3659 } |
3638 } | 3660 } |
3639 | 3661 |
3640 | 3662 |
3641 } // namespace internal | 3663 } // namespace internal |
3642 } // namespace v8 | 3664 } // namespace v8 |
3643 | 3665 |
3644 #endif // V8_PARSING_PARSER_BASE_H | 3666 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |