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

Side by Side Diff: src/parsing/parser.cc

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: 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
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 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 743
744 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { 744 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
745 return parser_->ParseV8Intrinsic(ok); 745 return parser_->ParseV8Intrinsic(ok);
746 } 746 }
747 747
748 748
749 FunctionLiteral* ParserTraits::ParseFunctionLiteral( 749 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
750 const AstRawString* name, Scanner::Location function_name_location, 750 const AstRawString* name, Scanner::Location function_name_location,
751 FunctionNameValidity function_name_validity, FunctionKind kind, 751 FunctionNameValidity function_name_validity, FunctionKind kind,
752 int function_token_position, FunctionLiteral::FunctionType type, 752 int function_token_position, FunctionLiteral::FunctionType type,
753 LanguageMode language_mode, bool* ok) { 753 LanguageMode language_mode, typesystem::TypeFlags type_flags, bool* ok) {
754 return parser_->ParseFunctionLiteral( 754 return parser_->ParseFunctionLiteral(
755 name, function_name_location, function_name_validity, kind, 755 name, function_name_location, function_name_validity, kind,
756 function_token_position, type, language_mode, ok); 756 function_token_position, type, language_mode, type_flags, ok);
757 } 757 }
758 758
759 759
760 ClassLiteral* ParserTraits::ParseClassLiteral( 760 ClassLiteral* ParserTraits::ParseClassLiteral(
761 const AstRawString* name, Scanner::Location class_name_location, 761 const AstRawString* name, Scanner::Location class_name_location,
762 bool name_is_strict_reserved, int pos, bool* ok) { 762 bool name_is_strict_reserved, int pos, bool* ok) {
763 return parser_->ParseClassLiteral(name, class_name_location, 763 return parser_->ParseClassLiteral(name, class_name_location,
764 name_is_strict_reserved, pos, ok); 764 name_is_strict_reserved, pos, ok);
765 } 765 }
766 766
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 ok = false; 1128 ok = false;
1129 } 1129 }
1130 } 1130 }
1131 } 1131 }
1132 } else if (shared_info->is_default_constructor()) { 1132 } else if (shared_info->is_default_constructor()) {
1133 result = DefaultConstructor( 1133 result = DefaultConstructor(
1134 raw_name, IsSubclassConstructor(shared_info->kind()), scope, 1134 raw_name, IsSubclassConstructor(shared_info->kind()), scope,
1135 shared_info->start_position(), shared_info->end_position(), 1135 shared_info->start_position(), shared_info->end_position(),
1136 shared_info->language_mode()); 1136 shared_info->language_mode());
1137 } else { 1137 } else {
1138 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), 1138 result = ParseFunctionLiteral(
1139 kSkipFunctionNameCheck, shared_info->kind(), 1139 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck,
1140 RelocInfo::kNoPosition, function_type, 1140 shared_info->kind(), RelocInfo::kNoPosition, function_type,
1141 shared_info->language_mode(), &ok); 1141 shared_info->language_mode(), typesystem::kNormalTypes, &ok);
1142 } 1142 }
1143 // Make sure the results agree. 1143 // Make sure the results agree.
1144 DCHECK(ok == (result != NULL)); 1144 DCHECK(ok == (result != NULL));
1145 } 1145 }
1146 1146
1147 // Make sure the target stack is empty. 1147 // Make sure the target stack is empty.
1148 DCHECK(target_stack_ == NULL); 1148 DCHECK(target_stack_ == NULL);
1149 1149
1150 if (result != NULL) { 1150 if (result != NULL) {
1151 Handle<String> inferred_name(shared_info->inferred_name()); 1151 Handle<String> inferred_name(shared_info->inferred_name());
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 1598
1599 const AstRawString* default_string = ast_value_factory()->default_string(); 1599 const AstRawString* default_string = ast_value_factory()->default_string();
1600 ZoneList<const AstRawString*> names(1, zone()); 1600 ZoneList<const AstRawString*> names(1, zone());
1601 Statement* result = nullptr; 1601 Statement* result = nullptr;
1602 Expression* default_export = nullptr; 1602 Expression* default_export = nullptr;
1603 switch (peek()) { 1603 switch (peek()) {
1604 case Token::FUNCTION: { 1604 case Token::FUNCTION: {
1605 Consume(Token::FUNCTION); 1605 Consume(Token::FUNCTION);
1606 int pos = position(); 1606 int pos = position();
1607 bool is_generator = Check(Token::MUL); 1607 bool is_generator = Check(Token::MUL);
1608 if (peek() == Token::LPAREN) { 1608 if (peek() == Token::LPAREN || (scope_->typed() && Check(Token::LT))) {
1609 // FunctionDeclaration[+Default] :: 1609 // FunctionDeclaration[+Default] ::
1610 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' 1610 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1611 // 1611 //
1612 // GeneratorDeclaration[+Default] :: 1612 // GeneratorDeclaration[+Default] ::
1613 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' 1613 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1614 default_export = ParseFunctionLiteral( 1614 default_export = ParseFunctionLiteral(
1615 default_string, Scanner::Location::invalid(), 1615 default_string, Scanner::Location::invalid(),
1616 kSkipFunctionNameCheck, 1616 kSkipFunctionNameCheck,
1617 is_generator ? FunctionKind::kGeneratorFunction 1617 is_generator ? FunctionKind::kGeneratorFunction
1618 : FunctionKind::kNormalFunction, 1618 : FunctionKind::kNormalFunction,
1619 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 1619 pos, FunctionLiteral::kDeclaration, language_mode(),
1620 typesystem::kAllowSignature, CHECK_OK);
1620 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1621 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1621 } else { 1622 } else {
1622 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK); 1623 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK);
1623 } 1624 }
1624 break; 1625 break;
1625 } 1626 }
1626 1627
1627 case Token::CLASS: 1628 case Token::CLASS:
1628 Consume(Token::CLASS); 1629 Consume(Token::CLASS);
1629 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { 1630 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 // GeneratorDeclaration :: 2161 // GeneratorDeclaration ::
2161 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' 2162 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2162 // 2163 //
2163 // 'function' and '*' (if present) have been consumed by the caller. 2164 // 'function' and '*' (if present) have been consumed by the caller.
2164 bool is_strict_reserved = false; 2165 bool is_strict_reserved = false;
2165 const AstRawString* name = ParseIdentifierOrStrictReservedWord( 2166 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2166 &is_strict_reserved, CHECK_OK); 2167 &is_strict_reserved, CHECK_OK);
2167 2168
2168 FuncNameInferrer::State fni_state(fni_); 2169 FuncNameInferrer::State fni_state(fni_);
2169 if (fni_ != NULL) fni_->PushEnclosingName(name); 2170 if (fni_ != NULL) fni_->PushEnclosingName(name);
2170 FunctionLiteral* fun = ParseFunctionLiteral( 2171 FunctionLiteral* fun =
2171 name, scanner()->location(), 2172 ParseFunctionLiteral(name, scanner()->location(),
2172 is_strict_reserved ? kFunctionNameIsStrictReserved 2173 is_strict_reserved ? kFunctionNameIsStrictReserved
2173 : kFunctionNameValidityUnknown, 2174 : kFunctionNameValidityUnknown,
2174 is_generator ? FunctionKind::kGeneratorFunction 2175 is_generator ? FunctionKind::kGeneratorFunction
2175 : FunctionKind::kNormalFunction, 2176 : FunctionKind::kNormalFunction,
2176 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 2177 pos, FunctionLiteral::kDeclaration, language_mode(),
2178 typesystem::kAllowSignature, CHECK_OK);
2179 // Return no function declaration if just the signature was given.
2180 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2181 if (fun == nullptr) return empty;
2177 2182
2178 // Even if we're not at the top-level of the global or a function 2183 // Even if we're not at the top-level of the global or a function
2179 // scope, we treat it as such and introduce the function with its 2184 // scope, we treat it as such and introduce the function with its
2180 // initial value upon entering the corresponding scope. 2185 // initial value upon entering the corresponding scope.
2181 // In ES6, a function behaves as a lexical binding, except in 2186 // In ES6, a function behaves as a lexical binding, except in
2182 // a script scope, or the initial scope of eval or another function. 2187 // a script scope, or the initial scope of eval or another function.
2183 VariableMode mode = 2188 VariableMode mode =
2184 (is_strict(language_mode()) || allow_harmony_sloppy_function()) && 2189 (is_strict(language_mode()) || allow_harmony_sloppy_function()) &&
2185 !scope_->is_declaration_scope() 2190 !scope_->is_declaration_scope()
2186 ? LET 2191 ? LET
2187 : VAR; 2192 : VAR;
2188 VariableProxy* proxy = NewUnresolved(name, mode); 2193 VariableProxy* proxy = NewUnresolved(name, mode);
2189 Declaration* declaration = 2194 Declaration* declaration =
2190 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 2195 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2191 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2196 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2192 if (names) names->Add(name, zone()); 2197 if (names) names->Add(name, zone());
2193 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2194 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() && 2198 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() &&
2195 !scope_->is_declaration_scope()) { 2199 !scope_->is_declaration_scope()) {
2196 SloppyBlockFunctionStatement* delegate = 2200 SloppyBlockFunctionStatement* delegate =
2197 factory()->NewSloppyBlockFunctionStatement(empty, scope_); 2201 factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2198 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name, 2202 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2199 delegate); 2203 delegate);
2200 return delegate; 2204 return delegate;
2201 } 2205 }
2202 return empty; 2206 return empty;
2203 } 2207 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 int decl_pos = peek_position(); 2394 int decl_pos = peek_position();
2391 { 2395 {
2392 ExpressionClassifier pattern_classifier(this); 2396 ExpressionClassifier pattern_classifier(this);
2393 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 2397 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2394 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 2398 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2395 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { 2399 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
2396 ValidateLetPattern(&pattern_classifier, CHECK_OK); 2400 ValidateLetPattern(&pattern_classifier, CHECK_OK);
2397 } 2401 }
2398 } 2402 }
2399 2403
2400 // Optional type annotation. 2404 // Parse optional type annotation.
2401 if (scope_->typed() && Check(Token::COLON)) { 2405 typename TypeSystem::Type type = this->EmptyType();
2402 typename TypeSystem::Type type = ParseValidType(CHECK_OK); 2406 if (scope_->typed() && Check(Token::COLON)) { // Braces required here.
2403 USE(type); 2407 type = ParseValidType(CHECK_OK);
2404 } 2408 }
2409 USE(type); // TODO(nikolaos): really use it!
2405 2410
2406 Scanner::Location variable_loc = scanner()->location(); 2411 Scanner::Location variable_loc = scanner()->location();
2407 const AstRawString* single_name = 2412 const AstRawString* single_name =
2408 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name() 2413 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2409 : nullptr; 2414 : nullptr;
2410 if (single_name != nullptr) { 2415 if (single_name != nullptr) {
2411 if (fni_ != NULL) fni_->PushVariableName(single_name); 2416 if (fni_ != NULL) fni_->PushVariableName(single_name);
2412 } 2417 }
2413 2418
2414 Expression* value = NULL; 2419 Expression* value = NULL;
(...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after
4091 DCHECK(reindexer.count() <= 4096 DCHECK(reindexer.count() <=
4092 parser_->function_state_->materialized_literal_count()); 4097 parser_->function_state_->materialized_literal_count());
4093 } 4098 }
4094 } 4099 }
4095 4100
4096 4101
4097 FunctionLiteral* Parser::ParseFunctionLiteral( 4102 FunctionLiteral* Parser::ParseFunctionLiteral(
4098 const AstRawString* function_name, Scanner::Location function_name_location, 4103 const AstRawString* function_name, Scanner::Location function_name_location,
4099 FunctionNameValidity function_name_validity, FunctionKind kind, 4104 FunctionNameValidity function_name_validity, FunctionKind kind,
4100 int function_token_pos, FunctionLiteral::FunctionType function_type, 4105 int function_token_pos, FunctionLiteral::FunctionType function_type,
4101 LanguageMode language_mode, bool* ok) { 4106 LanguageMode language_mode, typesystem::TypeFlags type_flags, bool* ok) {
4102 // Function :: 4107 // Function ::
4103 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4108 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4104 // 4109 //
4105 // Getter :: 4110 // Getter ::
4106 // '(' ')' '{' FunctionBody '}' 4111 // '(' ')' '{' FunctionBody '}'
4107 // 4112 //
4108 // Setter :: 4113 // Setter ::
4109 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 4114 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4110 4115
4111 int pos = function_token_pos == RelocInfo::kNoPosition 4116 int pos = function_token_pos == RelocInfo::kNoPosition
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 scope_->ForceContextAllocation(); 4191 scope_->ForceContextAllocation();
4187 4192
4188 // Calling a generator returns a generator object. That object is stored 4193 // Calling a generator returns a generator object. That object is stored
4189 // in a temporary variable, a definition that is used by "yield" 4194 // in a temporary variable, a definition that is used by "yield"
4190 // expressions. This also marks the FunctionState as a generator. 4195 // expressions. This also marks the FunctionState as a generator.
4191 Variable* temp = scope_->NewTemporary( 4196 Variable* temp = scope_->NewTemporary(
4192 ast_value_factory()->dot_generator_object_string()); 4197 ast_value_factory()->dot_generator_object_string());
4193 function_state.set_generator_object_variable(temp); 4198 function_state.set_generator_object_variable(temp);
4194 } 4199 }
4195 4200
4201 // Parse optional type parameters.
4202 typename TypeSystem::TypeParameters type_parameters =
4203 this->NullTypeParameters();
4204 if (scope_->typed() &&
4205 !(type_flags & typesystem::kDisallowTypeParameters) &&
4206 peek() == Token::LT) { // Braces required here.
4207 type_parameters = ParseTypeParameters(CHECK_OK);
4208 }
4209 USE(type_parameters); // TODO(nikolaos): really use them!
4210
4196 Expect(Token::LPAREN, CHECK_OK); 4211 Expect(Token::LPAREN, CHECK_OK);
4197 int start_position = scanner()->location().beg_pos; 4212 int start_position = scanner()->location().beg_pos;
4198 scope_->set_start_position(start_position); 4213 scope_->set_start_position(start_position);
4199 ParserFormalParameters formals(scope); 4214 ParserFormalParameters formals(scope);
4200 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 4215 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4201 arity = formals.Arity(); 4216 arity = formals.Arity();
4202 Expect(Token::RPAREN, CHECK_OK); 4217 Expect(Token::RPAREN, CHECK_OK);
4203 int formals_end_position = scanner()->location().end_pos; 4218 int formals_end_position = scanner()->location().end_pos;
4204 4219
4205 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, 4220 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
4206 formals_end_position, CHECK_OK); 4221 formals_end_position, CHECK_OK);
4222
4223 // Parse optional type annotation.
4224 typename TypeSystem::Type result_type = this->EmptyType();
4225 if (scope_->typed() &&
4226 !(type_flags & typesystem::kDisallowTypeAnnotation) &&
4227 Check(Token::COLON)) { // Braces required here.
4228 result_type = ParseValidType(CHECK_OK);
4229 }
4230 USE(result_type); // TODO(nikolaos): really use it!
4231
4232 // Allow for a function signature (i.e., a literal without body).
4233 // In that case, return a nullptr instead of a function literal.
rossberg 2016/04/18 09:22:24 May be worth documenting at the funciton declarati
nickie 2016/04/19 10:58:10 Done.
4234 if (peek() != Token::LBRACE && scope_->typed() &&
4235 (type_flags & typesystem::kAllowSignature)) {
4236 ExpectSemicolon(CHECK_OK);
4237 return nullptr;
4238 }
4239
4207 Expect(Token::LBRACE, CHECK_OK); 4240 Expect(Token::LBRACE, CHECK_OK);
4208 4241
4209 // Don't include the rest parameter into the function's formal parameter 4242 // Don't include the rest parameter into the function's formal parameter
4210 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, 4243 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
4211 // which says whether we need to create an arguments adaptor frame). 4244 // which says whether we need to create an arguments adaptor frame).
4212 if (formals.has_rest) arity--; 4245 if (formals.has_rest) arity--;
4213 4246
4214 // Determine if the function can be parsed lazily. Lazy parsing is different 4247 // Determine if the function can be parsed lazily. Lazy parsing is different
4215 // from lazy compilation; we need to parse more eagerly than we compile. 4248 // from lazy compilation; we need to parse more eagerly than we compile.
4216 4249
(...skipping 2730 matching lines...) Expand 10 before | Expand all | Expand 10 after
6947 try_block, target); 6980 try_block, target);
6948 final_loop = target; 6981 final_loop = target;
6949 } 6982 }
6950 6983
6951 return final_loop; 6984 return final_loop;
6952 } 6985 }
6953 6986
6954 6987
6955 } // namespace internal 6988 } // namespace internal
6956 } // namespace v8 6989 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698