| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 if (unresolved_class.qualifier() == String::null()) { | 264 if (unresolved_class.qualifier() == String::null()) { |
| 265 lib = cls.library(); | 265 lib = cls.library(); |
| 266 } else { | 266 } else { |
| 267 const String& qualifier = String::Handle(unresolved_class.qualifier()); | 267 const String& qualifier = String::Handle(unresolved_class.qualifier()); |
| 268 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | 268 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 269 lib_prefix = cls.LookupLibraryPrefix(qualifier); | 269 lib_prefix = cls.LookupLibraryPrefix(qualifier); |
| 270 if (lib_prefix.IsNull()) { | 270 if (lib_prefix.IsNull()) { |
| 271 const Script& script = Script::Handle(cls.script()); | 271 const Script& script = Script::Handle(cls.script()); |
| 272 ReportError(script, unresolved_class.token_index(), | 272 ReportError(script, unresolved_class.token_index(), |
| 273 "cannot resolve library prefix '%s' from '%s'.\n", | 273 "cannot resolve library prefix '%s' from '%s'.\n", |
| 274 String::Handle(unresolved_class.Name()).ToCString(), | 274 qualifier.ToCString(), |
| 275 String::Handle(cls.Name()).ToCString()); | 275 String::Handle(cls.Name()).ToCString()); |
| 276 } | 276 } |
| 277 lib = lib_prefix.library(); | 277 lib = lib_prefix.library(); |
| 278 } | 278 } |
| 279 ASSERT(!lib.IsNull()); | 279 ASSERT(!lib.IsNull()); |
| 280 const String& class_name = String::Handle(unresolved_class.ident()); | 280 const String& class_name = String::Handle(unresolved_class.ident()); |
| 281 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name)); | 281 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name)); |
| 282 if (resolved_class.IsNull()) { | 282 if (resolved_class.IsNull()) { |
| 283 const Script& script = Script::Handle(cls.script()); | 283 const Script& script = Script::Handle(cls.script()); |
| 284 ReportError(script, unresolved_class.token_index(), | 284 ReportError(script, unresolved_class.token_index(), |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 if (factory_class.is_interface()) { | 371 if (factory_class.is_interface()) { |
| 372 const String& interface_name = String::Handle(interface.Name()); | 372 const String& interface_name = String::Handle(interface.Name()); |
| 373 const String& factory_name = String::Handle(factory_class.Name()); | 373 const String& factory_name = String::Handle(factory_class.Name()); |
| 374 const Script& script = Script::Handle(interface.script()); | 374 const Script& script = Script::Handle(interface.script()); |
| 375 ReportError(script, unresolved_factory_class.token_index(), | 375 ReportError(script, unresolved_factory_class.token_index(), |
| 376 "default clause of interface '%s' names non-class '%s'.\n", | 376 "default clause of interface '%s' names non-class '%s'.\n", |
| 377 interface_name.ToCString(), | 377 interface_name.ToCString(), |
| 378 factory_name.ToCString()); | 378 factory_name.ToCString()); |
| 379 } | 379 } |
| 380 interface.set_factory_class(factory_class); | 380 interface.set_factory_class(factory_class); |
| 381 // Check that the type parameter lists are identical. | 381 ResolveAndFinalizeUpperBounds(factory_class); |
| 382 const intptr_t num_factory_type_params = factory_class.NumTypeParameters(); |
| 382 const Class& factory_signature_class = Class::Handle( | 383 const Class& factory_signature_class = Class::Handle( |
| 383 unresolved_factory_class.factory_signature_class()); | 384 unresolved_factory_class.factory_signature_class()); |
| 384 ASSERT(!factory_signature_class.IsNull()); | 385 ASSERT(!factory_signature_class.IsNull()); |
| 385 ResolveAndFinalizeUpperBounds(factory_class); | 386 const intptr_t num_default_type_params = |
| 386 ResolveAndFinalizeUpperBounds(factory_signature_class); | 387 factory_signature_class.NumTypeParameters(); |
| 387 String& expected_type_name = String::Handle(); | 388 // If a type parameter list is included in the default factory clause (it |
| 388 String& actual_type_name = String::Handle(); | 389 // can be omitted), verify that it matches the list of type parameters of |
| 389 AbstractType& expected_type_extends = AbstractType::Handle(); | 390 // the factory class in number, names, and bounds. |
| 390 AbstractType& actual_type_extends = AbstractType::Handle(); | 391 if (num_default_type_params > 0) { |
| 391 const Array& expected_type_names = | 392 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 392 Array::Handle(factory_signature_class.type_parameters()); | 393 String& expected_type_name = String::Handle(); |
| 393 const Array& actual_type_names = | 394 String& actual_type_name = String::Handle(); |
| 395 AbstractType& expected_type_extends = AbstractType::Handle(); |
| 396 AbstractType& actual_type_extends = AbstractType::Handle(); |
| 397 const Array& expected_type_names = |
| 398 Array::Handle(factory_signature_class.type_parameters()); |
| 399 const Array& actual_type_names = |
| 400 Array::Handle(factory_class.type_parameters()); |
| 401 const TypeArguments& expected_extends_array = |
| 402 TypeArguments::Handle(factory_signature_class.type_parameter_extends()); |
| 403 const TypeArguments& actual_extends_array = |
| 404 TypeArguments::Handle(factory_class.type_parameter_extends()); |
| 405 bool mismatch = num_factory_type_params != num_default_type_params; |
| 406 for (intptr_t i = 0; !mismatch && (i < num_default_type_params); i++) { |
| 407 expected_type_name ^= expected_type_names.At(i); |
| 408 actual_type_name ^= actual_type_names.At(i); |
| 409 expected_type_extends = expected_extends_array.TypeAt(i); |
| 410 actual_type_extends = actual_extends_array.TypeAt(i); |
| 411 if (!expected_type_name.Equals(actual_type_name) || |
| 412 !expected_type_extends.Equals(actual_type_extends)) { |
| 413 mismatch = true; |
| 414 } |
| 415 } |
| 416 if (mismatch) { |
| 417 const String& interface_name = String::Handle(interface.Name()); |
| 418 const String& factory_name = String::Handle(factory_class.Name()); |
| 419 const Script& script = Script::Handle(interface.script()); |
| 420 ReportError(script, unresolved_factory_class.token_index(), |
| 421 "mismatch in number, names, or bounds of type parameters " |
| 422 "between default clause of interface '%s' and actual factory " |
| 423 "class '%s'.\n", |
| 424 interface_name.ToCString(), |
| 425 factory_name.ToCString()); |
| 426 } |
| 427 } |
| 428 // Verify that the type parameters of the factory class and of the interface |
| 429 // have identical names. |
| 430 String& interface_type_param_name = String::Handle(); |
| 431 String& factory_type_param_name = String::Handle(); |
| 432 const Array& interface_type_param_names = |
| 433 Array::Handle(interface.type_parameters()); |
| 434 const Array& factory_type_param_names = |
| 394 Array::Handle(factory_class.type_parameters()); | 435 Array::Handle(factory_class.type_parameters()); |
| 395 const TypeArguments& expected_extends_array = | 436 const intptr_t num_interface_type_params = interface.NumTypeParameters(); |
| 396 TypeArguments::Handle(factory_signature_class.type_parameter_extends()); | 437 bool mismatch = num_interface_type_params != num_factory_type_params; |
| 397 const TypeArguments& actual_extends_array = | 438 for (intptr_t i = 0; !mismatch && (i < num_factory_type_params); i++) { |
| 398 TypeArguments::Handle(factory_class.type_parameter_extends()); | 439 interface_type_param_name ^= interface_type_param_names.At(i); |
| 399 const intptr_t num_type_params = factory_signature_class.NumTypeParameters(); | 440 factory_type_param_name ^= factory_type_param_names.At(i); |
| 400 bool mismatch = factory_class.NumTypeParameters() != num_type_params; | 441 if (!interface_type_param_name.Equals(factory_type_param_name)) { |
| 401 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { | |
| 402 expected_type_name ^= expected_type_names.At(i); | |
| 403 actual_type_name ^= actual_type_names.At(i); | |
| 404 expected_type_extends = expected_extends_array.TypeAt(i); | |
| 405 actual_type_extends = actual_extends_array.TypeAt(i); | |
| 406 if (!expected_type_name.Equals(actual_type_name) || | |
| 407 !expected_type_extends.Equals(actual_type_extends)) { | |
| 408 mismatch = true; | 442 mismatch = true; |
| 409 } | 443 } |
| 410 } | 444 } |
| 411 // The list of type parameters in the default factory clause can be omitted. | 445 if (mismatch) { |
| 412 if (mismatch && (num_type_params > 0)) { | |
| 413 const String& interface_name = String::Handle(interface.Name()); | 446 const String& interface_name = String::Handle(interface.Name()); |
| 414 const String& factory_name = String::Handle(factory_class.Name()); | 447 const String& factory_name = String::Handle(factory_class.Name()); |
| 415 const Script& script = Script::Handle(interface.script()); | 448 const Script& script = Script::Handle(interface.script()); |
| 416 ReportError(script, unresolved_factory_class.token_index(), | 449 ReportError(script, unresolved_factory_class.token_index(), |
| 417 "mismatch in number, names, or bounds of type parameters " | 450 "mismatch in number or names of type parameters between " |
| 418 "between default clause of interface '%s' and actual factory " | 451 "interface '%s' and default factory class '%s'.\n", |
| 419 "class '%s'.\n", | |
| 420 interface_name.ToCString(), | 452 interface_name.ToCString(), |
| 421 factory_name.ToCString()); | 453 factory_name.ToCString()); |
| 422 } | 454 } |
| 423 } | 455 } |
| 424 | 456 |
| 425 | 457 |
| 426 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { | 458 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
| 427 if (type.IsResolved()) { | 459 if (type.IsResolved()) { |
| 428 return; | 460 return; |
| 429 } | 461 } |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 va_end(args); | 1279 va_end(args); |
| 1248 if (FLAG_warning_as_error) { | 1280 if (FLAG_warning_as_error) { |
| 1249 Isolate::Current()->long_jump_base()->Jump(1, error); | 1281 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1250 UNREACHABLE(); | 1282 UNREACHABLE(); |
| 1251 } else { | 1283 } else { |
| 1252 OS::Print("%s", error.ToErrorCString()); | 1284 OS::Print("%s", error.ToErrorCString()); |
| 1253 } | 1285 } |
| 1254 } | 1286 } |
| 1255 | 1287 |
| 1256 } // namespace dart | 1288 } // namespace dart |
| OLD | NEW |