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

Side by Side Diff: src/parsing/parser-base.h

Issue 1841093002: Add optional types to function/method declarations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@types-1817353007-typ-mod
Patch Set: More tests, disallow optional setter parameter Created 4 years, 8 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
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698