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

Side by Side Diff: runtime/vm/parser.cc

Issue 2696783002: Properly resolve upper bounds of generic function's type parameters. (Closed)
Patch Set: Created 3 years, 10 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 | « runtime/vm/object.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 DEFINE_FLAG(bool, 47 DEFINE_FLAG(bool,
48 support_deprecated_tearoff_syntax, 48 support_deprecated_tearoff_syntax,
49 false, 49 false,
50 "Support new tear-off syntax."); 50 "Support new tear-off syntax.");
51 // TODO(floitsch): remove the conditional-directive flag, once we publicly 51 // TODO(floitsch): remove the conditional-directive flag, once we publicly
52 // committed to the current version. 52 // committed to the current version.
53 DEFINE_FLAG(bool, 53 DEFINE_FLAG(bool,
54 conditional_directives, 54 conditional_directives,
55 true, 55 true,
56 "Enable conditional directives"); 56 "Enable conditional directives");
57 DEFINE_FLAG(bool, generic_method_syntax, true, "Enable generic functions."); 57 DEFINE_FLAG(bool,
58 generic_method_syntax,
59 true,
60 "Enable generic function syntax.");
61 DEFINE_FLAG(bool,
62 generic_method_semantics,
63 true,
64 "Enable generic function semantics (not yet supported).");
58 DEFINE_FLAG(bool, 65 DEFINE_FLAG(bool,
59 initializing_formal_access, 66 initializing_formal_access,
60 true, 67 true,
61 "Make initializing formal parameters visible in initializer list."); 68 "Make initializing formal parameters visible in initializer list.");
62 DEFINE_FLAG(bool, 69 DEFINE_FLAG(bool,
63 warn_super, 70 warn_super,
64 false, 71 false,
65 "Warning if super initializer not last in initializer list."); 72 "Warning if super initializer not last in initializer list.");
66 DEFINE_FLAG( 73 DEFINE_FLAG(
67 bool, 74 bool,
(...skipping 5430 matching lines...) Expand 10 before | Expand all | Expand 10 after
5498 } 5505 }
5499 if ((CurrentToken() == Token::kEXTENDS) || 5506 if ((CurrentToken() == Token::kEXTENDS) ||
5500 (!parameterizing_class && (CurrentToken() == Token::kSUPER))) { 5507 (!parameterizing_class && (CurrentToken() == Token::kSUPER))) {
5501 ConsumeToken(); 5508 ConsumeToken();
5502 // TODO(regis): Handle 'super' differently than 'extends'. 5509 // TODO(regis): Handle 'super' differently than 'extends'.
5503 // A bound may refer to the owner of the type parameter it applies to, 5510 // A bound may refer to the owner of the type parameter it applies to,
5504 // i.e. to the class or function currently being parsed. 5511 // i.e. to the class or function currently being parsed.
5505 // Postpone resolution in order to avoid resolving the owner and its 5512 // Postpone resolution in order to avoid resolving the owner and its
5506 // type parameters, as they are not fully parsed yet. 5513 // type parameters, as they are not fully parsed yet.
5507 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); 5514 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve);
5508 if (!parameterizing_class) {
5509 // TODO(regis): Resolve and finalize function type parameter bounds in
5510 // class finalizer. For now, ignore parsed bounds to avoid unresolved
5511 // bounds while writing snapshots.
5512 type_parameter_bound = I->object_store()->object_type();
5513 }
5514 } else { 5515 } else {
5515 type_parameter_bound = I->object_store()->object_type(); 5516 type_parameter_bound = I->object_store()->object_type();
5516 } 5517 }
5517 type_parameter = TypeParameter::New( 5518 type_parameter = TypeParameter::New(
5518 parameterizing_class ? current_class() : Class::Handle(Z), 5519 parameterizing_class ? current_class() : Class::Handle(Z),
5519 parameterizing_class ? Function::Handle(Z) : innermost_function(), 5520 parameterizing_class ? Function::Handle(Z) : innermost_function(),
5520 index, type_parameter_name, type_parameter_bound, declaration_pos); 5521 index, 0, type_parameter_name, type_parameter_bound, declaration_pos);
5521 if (!parameterizing_class) {
5522 // TODO(regis): Resolve and finalize function type parameter in
5523 // class finalizer. For now, already mark as finalized.
5524 type_parameter.SetIsFinalized();
5525 }
5526 type_parameters_array.Add( 5522 type_parameters_array.Add(
5527 &AbstractType::ZoneHandle(Z, type_parameter.raw())); 5523 &AbstractType::ZoneHandle(Z, type_parameter.raw()));
5528 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { 5524 if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
5529 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); 5525 library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
5530 } 5526 }
5531 index++; 5527 index++;
5532 } while (CurrentToken() == Token::kCOMMA); 5528 } while (CurrentToken() == Token::kCOMMA);
5533 Token::Kind token = CurrentToken(); 5529 Token::Kind token = CurrentToken();
5534 if ((token == Token::kGT) || (token == Token::kSHR)) { 5530 if ((token == Token::kGT) || (token == Token::kSHR)) {
5535 ConsumeRightAngleBracket(); 5531 ConsumeRightAngleBracket();
5536 } else { 5532 } else {
5537 ReportError("right angle bracket expected"); 5533 ReportError("right angle bracket expected");
5538 } 5534 }
5539 const TypeArguments& type_parameters = 5535 const TypeArguments& type_parameters =
5540 TypeArguments::Handle(Z, NewTypeArguments(type_parameters_array)); 5536 TypeArguments::Handle(Z, NewTypeArguments(type_parameters_array));
5541 if (parameterizing_class) { 5537 if (parameterizing_class) {
5542 current_class().set_type_parameters(type_parameters); 5538 current_class().set_type_parameters(type_parameters);
5543 } else { 5539 } else {
5544 innermost_function().set_type_parameters(type_parameters); 5540 innermost_function().set_type_parameters(type_parameters);
5545 } 5541 }
5546 // Try to resolve the upper bounds, which will at least resolve the 5542 // Resolve type parameters referenced by upper bounds.
5547 // referenced type parameters.
5548 const intptr_t num_types = type_parameters.Length(); 5543 const intptr_t num_types = type_parameters.Length();
5549 for (intptr_t i = 0; i < num_types; i++) { 5544 for (intptr_t i = 0; i < num_types; i++) {
5550 type_parameter ^= type_parameters.TypeAt(i); 5545 type_parameter ^= type_parameters.TypeAt(i);
5551 type_parameter_bound = type_parameter.bound(); 5546 type_parameter_bound = type_parameter.bound();
5552 ResolveType(&type_parameter_bound); 5547 ResolveType(&type_parameter_bound);
5553 type_parameter.set_bound(type_parameter_bound); 5548 type_parameter.set_bound(type_parameter_bound);
5554 } 5549 }
5555 } 5550 }
5556 } 5551 }
5557 5552
(...skipping 6689 matching lines...) Expand 10 before | Expand all | Expand 10 after
12247 } 12242 }
12248 12243
12249 12244
12250 // Resolve the type parameters that may appear in the given signature from the 12245 // Resolve the type parameters that may appear in the given signature from the
12251 // signature function and current class. 12246 // signature function and current class.
12252 // Unresolved type classes get resolved later by the class finalizer. 12247 // Unresolved type classes get resolved later by the class finalizer.
12253 void Parser::ResolveSignature(const Function& signature) { 12248 void Parser::ResolveSignature(const Function& signature) {
12254 const Function& saved_innermost_function = 12249 const Function& saved_innermost_function =
12255 Function::Handle(Z, innermost_function().raw()); 12250 Function::Handle(Z, innermost_function().raw());
12256 innermost_function_ = signature.raw(); 12251 innermost_function_ = signature.raw();
12257 // TODO(regis): Resolve upper bounds of function type parameters. 12252 AbstractType& type = AbstractType::Handle();
12258 AbstractType& type = AbstractType::Handle(signature.result_type()); 12253 // Resolve upper bounds of function type parameters.
12254 const intptr_t num_type_params = signature.NumTypeParameters();
12255 if (num_type_params > 0) {
12256 TypeParameter& type_param = TypeParameter::Handle();
12257 const TypeArguments& type_params =
12258 TypeArguments::Handle(signature.type_parameters());
12259 for (intptr_t i = 0; i < num_type_params; i++) {
12260 type_param ^= type_params.TypeAt(i);
12261 type = type_param.bound();
12262 ResolveType(&type);
12263 type_param.set_bound(type);
12264 }
12265 }
12266 // Resolve result type.
12267 type = signature.result_type();
12259 ResolveType(&type); 12268 ResolveType(&type);
12260 signature.set_result_type(type); 12269 signature.set_result_type(type);
12270 // Resolve formal parameter types.
12261 const intptr_t num_parameters = signature.NumParameters(); 12271 const intptr_t num_parameters = signature.NumParameters();
12262 for (intptr_t i = 0; i < num_parameters; i++) { 12272 for (intptr_t i = 0; i < num_parameters; i++) {
12263 type = signature.ParameterTypeAt(i); 12273 type = signature.ParameterTypeAt(i);
12264 ResolveType(&type); 12274 ResolveType(&type);
12265 signature.SetParameterTypeAt(i, type); 12275 signature.SetParameterTypeAt(i, type);
12266 } 12276 }
12267 innermost_function_ = saved_innermost_function.raw(); 12277 innermost_function_ = saved_innermost_function.raw();
12268 } 12278 }
12269 12279
12270 12280
12271 // Resolve the type parameters that may appear in the given type and in its type 12281 // Resolve the type parameters that may appear in the given type and in its type
12272 // arguments from the current function and current class. 12282 // arguments from the current function and current class.
12273 // Unresolved type classes get resolved later by the class finalizer. 12283 // Unresolved type classes get resolved later by the class finalizer.
12274 void Parser::ResolveType(AbstractType* type) { 12284 void Parser::ResolveType(AbstractType* type) {
12275 ASSERT(type != NULL); 12285 ASSERT(type != NULL);
12276 if (type->IsResolved()) { 12286 if (type->IsResolved()) {
12277 // Some types are resolved by definition, such as a TypeParameter. 12287 // Some types are resolved by definition, such as a TypeParameter.
12278 return; 12288 return;
12279 } 12289 }
12280 // Resolve type class. 12290 // Resolve type class.
12281 if (!type->HasResolvedTypeClass()) { 12291 if (!type->HasResolvedTypeClass()) {
12282 const UnresolvedClass& unresolved_class = 12292 const UnresolvedClass& unresolved_class =
12283 UnresolvedClass::Handle(Z, type->unresolved_class()); 12293 UnresolvedClass::Handle(Z, type->unresolved_class());
12284 const String& unresolved_class_name = 12294 const String& unresolved_class_name =
12285 String::Handle(Z, unresolved_class.ident()); 12295 String::Handle(Z, unresolved_class.ident());
12286 if (unresolved_class.library_or_library_prefix() == Object::null()) { 12296 if (unresolved_class.library_or_library_prefix() == Object::null()) {
12287 // First check if the type is a function type parameter. 12297 // First check if the type is a function type parameter.
12288 if (!innermost_function().IsNull()) { 12298 if (!innermost_function().IsNull()) {
12289 // TODO(regis): Shortcut this lookup if no generic functions in scope. 12299 // TODO(regis): Shortcut this lookup if no generic functions in scope.
12300 // A bit has_generic_parent() would be useful on Function.
12301 // Unfortunately, all 32 kind bits are used in Function.
12290 TypeParameter& type_parameter = TypeParameter::ZoneHandle( 12302 TypeParameter& type_parameter = TypeParameter::ZoneHandle(
12291 Z, innermost_function().LookupTypeParameter(unresolved_class_name, 12303 Z, innermost_function().LookupTypeParameter(unresolved_class_name,
12292 NULL)); 12304 NULL));
12293 if (!type_parameter.IsNull()) { 12305 if (!type_parameter.IsNull()) {
12294 // TODO(regis): Check for absence of type arguments. 12306 // A type parameter cannot be parameterized, so make the type
12307 // malformed if type arguments have previously been parsed.
12308 if (type->arguments() != TypeArguments::null()) {
12309 *type = ClassFinalizer::NewFinalizedMalformedType(
12310 Error::Handle(Z), // No previous error.
12311 script_, type_parameter.token_pos(),
12312 "type parameter '%s' cannot be parameterized",
12313 String::Handle(Z, type_parameter.name()).ToCString());
12314 return;
12315 }
12316 // TODO(regis): Mark function type parameter as finalized (its index
12317 // does not need adjustment upon finalization) and return it.
12295 // For now, resolve the function type parameter to dynamic. 12318 // For now, resolve the function type parameter to dynamic.
12296 *type = Type::DynamicType(); 12319 *type = Type::DynamicType();
12297 return; 12320 return;
12298 } 12321 }
12299 } 12322 }
12300 // Then check if the type is a class type parameter. 12323 // Then check if the type is a class type parameter.
12301 const TypeParameter& type_parameter = TypeParameter::Handle( 12324 const TypeParameter& type_parameter = TypeParameter::Handle(
12302 Z, current_class().LookupTypeParameter(unresolved_class_name)); 12325 Z, current_class().LookupTypeParameter(unresolved_class_name));
12303 if (!type_parameter.IsNull()) { 12326 if (!type_parameter.IsNull()) {
12304 // A type parameter is considered to be a malformed type when 12327 // A type parameter is considered to be a malformed type when
(...skipping 22 matching lines...) Expand all
12327 } 12350 }
12328 } 12351 }
12329 } 12352 }
12330 // Resolve type arguments, if any. 12353 // Resolve type arguments, if any.
12331 if (type->arguments() != TypeArguments::null()) { 12354 if (type->arguments() != TypeArguments::null()) {
12332 const TypeArguments& arguments = 12355 const TypeArguments& arguments =
12333 TypeArguments::Handle(Z, type->arguments()); 12356 TypeArguments::Handle(Z, type->arguments());
12334 const intptr_t num_arguments = arguments.Length(); 12357 const intptr_t num_arguments = arguments.Length();
12335 AbstractType& type_argument = AbstractType::Handle(Z); 12358 AbstractType& type_argument = AbstractType::Handle(Z);
12336 for (intptr_t i = 0; i < num_arguments; i++) { 12359 for (intptr_t i = 0; i < num_arguments; i++) {
12337 type_argument ^= arguments.TypeAt(i); 12360 type_argument = arguments.TypeAt(i);
12338 ResolveType(&type_argument); 12361 ResolveType(&type_argument);
12339 arguments.SetTypeAt(i, type_argument); 12362 arguments.SetTypeAt(i, type_argument);
12340 } 12363 }
12341 } 12364 }
12342 if (type->IsFunctionType()) { 12365 if (type->IsFunctionType()) {
12343 const Function& signature = 12366 const Function& signature =
12344 Function::Handle(Z, Type::Cast(*type).signature()); 12367 Function::Handle(Z, Type::Cast(*type).signature());
12345 Type& signature_type = Type::Handle(Z, signature.SignatureType()); 12368 Type& signature_type = Type::Handle(Z, signature.SignatureType());
12346 if (signature_type.raw() != type->raw()) { 12369 if (signature_type.raw() != type->raw()) {
12347 ResolveType(&signature_type); 12370 ResolveType(&signature_type);
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
12883 TypeParameter::ZoneHandle(Z, innermost_function().LookupTypeParameter( 12906 TypeParameter::ZoneHandle(Z, innermost_function().LookupTypeParameter(
12884 ident, &type_param_func_level)); 12907 ident, &type_param_func_level));
12885 if (!type_parameter.IsNull()) { 12908 if (!type_parameter.IsNull()) {
12886 if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) { 12909 if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) {
12887 // The identifier is a function type parameter, possibly shadowing 12910 // The identifier is a function type parameter, possibly shadowing
12888 // 'resolved'. 12911 // 'resolved'.
12889 if (type_param_func_level < FunctionLevel()) { 12912 if (type_param_func_level < FunctionLevel()) {
12890 // Make sure that the function instantiator is captured. 12913 // Make sure that the function instantiator is captured.
12891 CaptureFunctionInstantiator(); 12914 CaptureFunctionInstantiator();
12892 } 12915 }
12893 // TODO(regis): Finalize type parameter and return as type node. 12916 // TODO(regis): Mark function type parameter as finalized (its index
12894 // For now, map to dynamic type. 12917 // does not need adjustment upon finalization) and return as type node.
12918 // For now, resolve the function type parameter to dynamic.
12895 Type& type = Type::ZoneHandle(Z, Type::DynamicType()); 12919 Type& type = Type::ZoneHandle(Z, Type::DynamicType());
12896 return new (Z) TypeNode(ident_pos, type); 12920 return new (Z) TypeNode(ident_pos, type);
12897 } 12921 }
12898 } 12922 }
12899 } 12923 }
12900 if (resolved == NULL) { 12924 if (resolved == NULL) {
12901 // Check whether the identifier is a class type parameter. 12925 // Check whether the identifier is a class type parameter.
12902 if (!current_class().IsNull()) { 12926 if (!current_class().IsNull()) {
12903 TypeParameter& type_parameter = TypeParameter::ZoneHandle( 12927 TypeParameter& type_parameter = TypeParameter::ZoneHandle(
12904 Z, current_class().LookupTypeParameter(ident)); 12928 Z, current_class().LookupTypeParameter(ident));
(...skipping 2136 matching lines...) Expand 10 before | Expand all | Expand 10 after
15041 const ArgumentListNode& function_args, 15065 const ArgumentListNode& function_args,
15042 const LocalVariable* temp_for_last_arg, 15066 const LocalVariable* temp_for_last_arg,
15043 bool is_super_invocation) { 15067 bool is_super_invocation) {
15044 UNREACHABLE(); 15068 UNREACHABLE();
15045 return NULL; 15069 return NULL;
15046 } 15070 }
15047 15071
15048 } // namespace dart 15072 } // namespace dart
15049 15073
15050 #endif // DART_PRECOMPILED_RUNTIME 15074 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698