Chromium Code Reviews| 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" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 17 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 17 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 18 DEFINE_FLAG(bool, verify_implements, false, | 18 DEFINE_FLAG(bool, verify_implements, false, |
| 19 "Verify that all classes implement their interface."); | 19 "Verify that all classes implement their interface."); |
| 20 DECLARE_FLAG(bool, enable_type_checks); | 20 DECLARE_FLAG(bool, enable_type_checks); |
| 21 DECLARE_FLAG(bool, silent_warnings); | |
| 22 DECLARE_FLAG(bool, warning_as_error); | |
| 21 | 23 |
| 22 void ClassFinalizer::AddPendingClasses( | 24 void ClassFinalizer::AddPendingClasses( |
| 23 const GrowableArray<const Class*>& classes) { | 25 const GrowableArray<const Class*>& classes) { |
| 24 if (!classes.is_empty()) { | 26 if (!classes.is_empty()) { |
| 25 ObjectStore* object_store = Isolate::Current()->object_store(); | 27 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 26 const Array& old_array = Array::Handle(object_store->pending_classes()); | 28 const Array& old_array = Array::Handle(object_store->pending_classes()); |
| 27 const intptr_t old_length = old_array.Length(); | 29 const intptr_t old_length = old_array.Length(); |
| 28 const int new_length = old_length + classes.length(); | 30 const int new_length = old_length + classes.length(); |
| 29 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); | 31 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); |
| 30 // Add new classes. | 32 // Add new classes. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 61 if (setjmp(*jump.Set()) == 0) { | 63 if (setjmp(*jump.Set()) == 0) { |
| 62 const Array& class_array = Array::Handle(object_store->pending_classes()); | 64 const Array& class_array = Array::Handle(object_store->pending_classes()); |
| 63 ASSERT(!class_array.IsNull()); | 65 ASSERT(!class_array.IsNull()); |
| 64 Class& cls = Class::Handle(); | 66 Class& cls = Class::Handle(); |
| 65 // First resolve all superclasses. | 67 // First resolve all superclasses. |
| 66 for (intptr_t i = 0; i < class_array.Length(); i++) { | 68 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 67 cls ^= class_array.At(i); | 69 cls ^= class_array.At(i); |
| 68 if (FLAG_trace_class_finalization) { | 70 if (FLAG_trace_class_finalization) { |
| 69 OS::Print("Resolving super and default: %s\n", cls.ToCString()); | 71 OS::Print("Resolving super and default: %s\n", cls.ToCString()); |
| 70 } | 72 } |
| 71 ResolveSuperClass(cls); | 73 ResolveSuperType(cls); |
| 72 if (cls.is_interface()) { | 74 if (cls.is_interface()) { |
| 73 ResolveDefaultClass(cls); | 75 ResolveFactoryClass(cls); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 // Finalize all classes. | 78 // Finalize all classes. |
| 77 for (intptr_t i = 0; i < class_array.Length(); i++) { | 79 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 78 cls ^= class_array.At(i); | 80 cls ^= class_array.At(i); |
| 79 FinalizeClass(cls); | 81 FinalizeClass(cls); |
| 80 } | 82 } |
| 81 if (FLAG_print_classes) { | 83 if (FLAG_print_classes) { |
| 82 for (intptr_t i = 0; i < class_array.Length(); i++) { | 84 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 83 cls ^= class_array.At(i); | 85 cls ^= class_array.At(i); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 const Script& script = Script::Handle(cls.script()); | 271 const Script& script = Script::Handle(cls.script()); |
| 270 ReportError(script, unresolved_class.token_index(), | 272 ReportError(script, unresolved_class.token_index(), |
| 271 "cannot resolve class name '%s' from '%s'.\n", | 273 "cannot resolve class name '%s' from '%s'.\n", |
| 272 String::Handle(unresolved_class.Name()).ToCString(), | 274 String::Handle(unresolved_class.Name()).ToCString(), |
| 273 String::Handle(cls.Name()).ToCString()); | 275 String::Handle(cls.Name()).ToCString()); |
| 274 } | 276 } |
| 275 return resolved_class.raw(); | 277 return resolved_class.raw(); |
| 276 } | 278 } |
| 277 | 279 |
| 278 | 280 |
| 279 // Resolve unresolved superclasses (String -> Class). | 281 // Resolve unresolved supertype (String -> Class). |
| 280 void ClassFinalizer::ResolveSuperClass(const Class& cls) { | 282 void ClassFinalizer::ResolveSuperType(const Class& cls) { |
| 281 if (cls.is_finalized()) { | 283 if (cls.is_finalized()) { |
| 282 return; | 284 return; |
| 283 } | 285 } |
| 284 Type& super_type = Type::Handle(cls.super_type()); | 286 Type& super_type = Type::Handle(cls.super_type()); |
| 285 if (super_type.IsNull()) { | 287 if (super_type.IsNull()) { |
| 286 return; | 288 return; |
| 287 } | 289 } |
| 288 // Resolve failures lead to a longjmp. | 290 // Resolve failures lead to a longjmp. |
| 289 super_type = ResolveType(cls, super_type); | 291 super_type = ResolveType(cls, super_type); |
| 290 if (super_type.IsTypeParameter()) { | 292 if (super_type.IsTypeParameter()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 (super_class.raw() == object_store->four_byte_string_class())) { | 337 (super_class.raw() == object_store->four_byte_string_class())) { |
| 336 ReportError("'%s' is not allowed to extend '%s'\n", | 338 ReportError("'%s' is not allowed to extend '%s'\n", |
| 337 String::Handle(cls.Name()).ToCString(), | 339 String::Handle(cls.Name()).ToCString(), |
| 338 String::Handle(super_class.Name()).ToCString()); | 340 String::Handle(super_class.Name()).ToCString()); |
| 339 } | 341 } |
| 340 } | 342 } |
| 341 return; | 343 return; |
| 342 } | 344 } |
| 343 | 345 |
| 344 | 346 |
| 345 void ClassFinalizer::ResolveDefaultClass(const Class& interface) { | 347 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { |
| 346 ASSERT(interface.is_interface()); | 348 ASSERT(interface.is_interface()); |
| 347 if (interface.is_finalized()) { | 349 if (interface.is_finalized() || |
| 350 !interface.HasFactoryClass() || | |
| 351 interface.HasResolvedFactoryClass()) { | |
| 348 return; | 352 return; |
| 349 } | 353 } |
| 350 Type& factory_type = Type::Handle(interface.factory_type()); | 354 const UnresolvedClass& unresolved_factory_class = |
| 351 if (factory_type.IsNull()) { | 355 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); |
| 352 // No resolving needed. | 356 |
| 357 // Lookup the factory class. | |
| 358 const Class& factory_class = | |
| 359 Class::Handle(ResolveClass(interface, unresolved_factory_class)); | |
|
srdjan
2011/11/16 23:02:26
Can the factory_class be null (i.e., non-existing)
regis
2011/11/16 23:38:08
Cannot be null. Added assert.
| |
| 360 if (factory_class.is_interface()) { | |
| 361 const String& interface_name = String::Handle(interface.Name()); | |
| 362 const String& factory_name = String::Handle(factory_class.Name()); | |
| 363 ReportError("factory clause of interface '%s' names non-class '%s'.\n", | |
| 364 interface_name.ToCString(), | |
| 365 factory_name.ToCString()); | |
| 366 } | |
| 367 interface.set_factory_class(factory_class); | |
| 368 // Check that the type parameter lists are identical. | |
| 369 const Class& factory_signature_class = Class::Handle( | |
| 370 unresolved_factory_class.factory_signature_class()); | |
| 371 ASSERT(!factory_signature_class.IsNull()); | |
| 372 const intptr_t num_type_params = factory_signature_class.NumTypeParameters(); | |
| 373 if (num_type_params == 0) { | |
|
srdjan
2011/11/16 23:02:26
Do we report warning in correct cases when interfa
regis
2011/11/16 23:38:08
Good catch! I added the warning at a later stage a
| |
| 374 // TODO(regis): For now, and until the core lib is fixed, we accept a | |
| 375 // factory clause with a class missing its list of type parameters. | |
| 376 // See bug 5408808. | |
| 377 const String& interface_name = String::Handle(interface.Name()); | |
| 378 const String& factory_name = String::Handle(factory_class.Name()); | |
| 379 ReportWarning("Warning: class '%s' in factory clause of interface '%s' is " | |
| 380 "missing its type parameter list.\n", | |
| 381 factory_name.ToCString(), | |
| 382 interface_name.ToCString()); | |
| 353 return; | 383 return; |
| 354 } | 384 } |
| 355 // Resolve failures lead to a longjmp. | 385 ResolveAndFinalizeUpperBounds(factory_class); |
| 356 factory_type = ResolveType(interface, factory_type); | 386 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 357 interface.set_factory_type(factory_type); | 387 bool mismatch = factory_class.NumTypeParameters() != num_type_params; |
| 358 if (factory_type.IsInterfaceType()) { | 388 String& expected_type_name = String::Handle(); |
| 389 String& actual_type_name = String::Handle(); | |
| 390 Type& expected_type_extends = Type::Handle(); | |
| 391 Type& actual_type_extends = Type::Handle(); | |
| 392 const Array& expected_type_names = | |
| 393 Array::Handle(factory_signature_class.type_parameters()); | |
| 394 const Array& actual_type_names = | |
| 395 Array::Handle(factory_class.type_parameters()); | |
| 396 const TypeArray& expected_extends_array = | |
| 397 TypeArray::Handle(factory_signature_class.type_parameter_extends()); | |
| 398 const TypeArray& actual_extends_array = | |
| 399 TypeArray::Handle(factory_class.type_parameter_extends()); | |
| 400 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { | |
| 401 expected_type_name ^= expected_type_names.At(i); | |
| 402 actual_type_name ^= actual_type_names.At(i); | |
| 403 expected_type_extends = expected_extends_array.TypeAt(i); | |
| 404 actual_type_extends = actual_extends_array.TypeAt(i); | |
| 405 if (!expected_type_name.Equals(actual_type_name) || | |
| 406 !expected_type_extends.Equals(actual_type_extends)) { | |
| 407 mismatch = true; | |
| 408 } | |
| 409 } | |
| 410 if (mismatch) { | |
| 359 const String& interface_name = String::Handle(interface.Name()); | 411 const String& interface_name = String::Handle(interface.Name()); |
| 360 ReportError("default clause of interface '%s' does not name a class\n", | 412 const String& factory_name = String::Handle(factory_class.Name()); |
| 361 interface_name.ToCString()); | 413 ReportError("mismatch in number or names of type parameters between " |
| 414 "factory clause of interface '%s' and actual factory " | |
| 415 "class '%s'.\n", | |
| 416 interface_name.ToCString(), | |
| 417 factory_name.ToCString()); | |
| 362 } | 418 } |
| 363 } | 419 } |
| 364 | 420 |
| 365 | 421 |
| 422 // TODO(regis): Now that we do not resolve type parameters anymore, we could | |
| 423 // make this function void and resolve the type in place. | |
| 366 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { | 424 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { |
| 367 if (type.IsResolved()) { | 425 if (type.IsResolved()) { |
| 368 return type.raw(); | 426 return type.raw(); |
| 369 } | 427 } |
| 370 if (FLAG_trace_type_finalization) { | 428 if (FLAG_trace_type_finalization) { |
| 371 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 429 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 372 } | 430 } |
| 373 | 431 |
| 374 // Resolve the type class. | 432 // Resolve the type class. |
| 375 if (!type.HasResolvedTypeClass()) { | 433 if (!type.HasResolvedTypeClass()) { |
| 434 // Type parameters are always resolved in the parser in the correct | |
| 435 // non-static scope or factory scope. That resolution scope is unknown here. | |
| 436 // Being able to resolve a type parameter from class cls here would indicate | |
| 437 // that the type parameter appeared in a static scope. Leaving the type as | |
| 438 // unresolved is the correct thing to do. | |
| 439 | |
| 440 // Lookup the type class. | |
| 376 const UnresolvedClass& unresolved_class = | 441 const UnresolvedClass& unresolved_class = |
| 377 UnresolvedClass::Handle(type.unresolved_class()); | 442 UnresolvedClass::Handle(type.unresolved_class()); |
| 378 const String& type_class_name = String::Handle(unresolved_class.ident()); | |
| 379 | |
| 380 // The type class name may be a type parameter of cls that was not resolved | |
| 381 // by the parser because it appeared as part of the declaration | |
| 382 // as T1 in B<T1, T2 extends A<T1>> or | |
| 383 // as T2 in B<T1 extends A<T2>, T2>>. | |
| 384 const TypeParameter& type_parameter = TypeParameter::Handle( | |
| 385 cls.LookupTypeParameter(type_class_name)); | |
| 386 if (!type_parameter.IsNull()) { | |
| 387 // No need to check for proper instance scoping, since another type | |
| 388 // parameter must be involved for the type to still be unresolved. | |
| 389 // The scope checking was performed for the other type parameter already. | |
| 390 | |
| 391 // A type parameter cannot be parameterized, so report an error if type | |
| 392 // arguments have previously been parsed. | |
| 393 if (type.arguments() != TypeArguments::null()) { | |
| 394 ReportError("type parameter '%s' cannot be parameterized", | |
| 395 type_class_name.ToCString()); | |
| 396 } | |
| 397 return type_parameter.raw(); | |
| 398 } | |
| 399 | |
| 400 // Lookup the type class. | |
| 401 const Class& type_class = | 443 const Class& type_class = |
| 402 Class::Handle(ResolveClass(cls, unresolved_class)); | 444 Class::Handle(ResolveClass(cls, unresolved_class)); |
| 403 | 445 |
| 404 // Replace unresolved class with resolved type class. | 446 // Replace unresolved class with resolved type class. |
| 405 ASSERT(type.IsParameterizedType()); | 447 ASSERT(type.IsParameterizedType()); |
| 406 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 448 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 407 parameterized_type ^= type.raw(); | 449 parameterized_type ^= type.raw(); |
| 408 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 450 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 409 } | 451 } |
| 410 | 452 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 type_extends = extends_array.TypeAt(i); | 524 type_extends = extends_array.TypeAt(i); |
| 483 if (!type_extends.IsDynamicType()) { | 525 if (!type_extends.IsDynamicType()) { |
| 484 type = arguments.TypeAt(offset + i); | 526 type = arguments.TypeAt(offset + i); |
| 485 if (type.IsInstantiated()) { | 527 if (type.IsInstantiated()) { |
| 486 if (!type_extends.IsInstantiated()) { | 528 if (!type_extends.IsInstantiated()) { |
| 487 type_extends = type_extends.InstantiateFrom(arguments, offset); | 529 type_extends = type_extends.InstantiateFrom(arguments, offset); |
| 488 } | 530 } |
| 489 // TODO(regis): Where do we check the constraints when the type is | 531 // TODO(regis): Where do we check the constraints when the type is |
| 490 // generic? | 532 // generic? |
| 491 if (!type.IsSubtypeOf(type_extends)) { | 533 if (!type.IsSubtypeOf(type_extends)) { |
| 492 const String& type_name = String::Handle(type.Name()); | 534 const String& type_argument_name = String::Handle(type.Name()); |
| 535 const String& class_name = String::Handle(cls.Name()); | |
| 493 const String& extends_name = String::Handle(type_extends.Name()); | 536 const String& extends_name = String::Handle(type_extends.Name()); |
| 494 ReportError("type argument '%s' of class '%s' " | 537 ReportError("type argument '%s' of class '%s' " |
| 495 "does not extend type '%s'\n", | 538 "does not extend type '%s'\n", |
| 496 type_name.ToCString(), | 539 type_argument_name.ToCString(), |
| 540 class_name.ToCString(), | |
| 497 extends_name.ToCString()); | 541 extends_name.ToCString()); |
| 498 } | 542 } |
| 499 } | 543 } |
| 500 } | 544 } |
| 501 } | 545 } |
| 502 Type& super_type = Type::Handle(cls.super_type()); | 546 Type& super_type = Type::Handle(cls.super_type()); |
| 503 if (!super_type.IsNull()) { | 547 if (!super_type.IsNull()) { |
| 504 ASSERT(super_type.IsFinalized()); | 548 ASSERT(super_type.IsFinalized()); |
| 505 const Class& super_class = Class::Handle(super_type.type_class()); | 549 const Class& super_class = Class::Handle(super_type.type_class()); |
| 506 VerifyUpperBounds(super_class, arguments); | 550 VerifyUpperBounds(super_class, arguments); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 } | 683 } |
| 640 UNREACHABLE(); | 684 UNREACHABLE(); |
| 641 return Type::null(); | 685 return Type::null(); |
| 642 } | 686 } |
| 643 | 687 |
| 644 | 688 |
| 645 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 689 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 646 const Function& function) { | 690 const Function& function) { |
| 647 // Resolve result type. | 691 // Resolve result type. |
| 648 Type& type = Type::Handle(function.result_type()); | 692 Type& type = Type::Handle(function.result_type()); |
| 649 type = ResolveType(cls, type); | 693 if (!type.IsResolved()) { |
| 650 function.set_result_type(type); | 694 if (function.IsFactory()) { |
| 695 // The signature class of the factory for a generic class holds the type | |
| 696 // parameters and their upper bounds. Copy the signature class from the | |
| 697 // result before it gets resolved. | |
| 698 const UnresolvedClass& unresolved_type_class = | |
| 699 UnresolvedClass::Handle(type.unresolved_class()); | |
| 700 const Class& factory_signature_class = | |
| 701 Class::Handle(unresolved_type_class.factory_signature_class()); | |
| 702 ASSERT(!factory_signature_class.IsNull()); | |
| 703 function.set_signature_class(factory_signature_class); | |
| 704 } | |
|
srdjan
2011/11/16 23:02:26
Why don't you merge the two function.IsFactory() i
regis
2011/11/16 23:38:08
Done.
| |
| 705 type = ResolveType(cls, type); | |
| 706 function.set_result_type(type); | |
| 707 if (function.IsFactory()) { | |
| 708 const Class& type_class = Class::Handle(type.type_class()); | |
| 709 // Verify that the factory signature declares the same number of type | |
| 710 // parameters as the return type class or interface. | |
| 711 const Class& factory_signature_class = | |
| 712 Class::Handle(function.signature_class()); | |
| 713 ResolveAndFinalizeUpperBounds(factory_signature_class); | |
| 714 if (factory_signature_class.NumTypeParameters() != | |
| 715 type_class.NumTypeParameters()) { | |
| 716 const String& function_name = String::Handle(function.name()); | |
| 717 if (factory_signature_class.NumTypeParameters() == 0) { | |
| 718 // TODO(regis): For now, and until the core lib is fixed, we accept a | |
| 719 // factory method with missing list of type parameters and use the | |
| 720 // list of the enclosing class. | |
| 721 // See bug 5408808. | |
| 722 const Class& enclosing_class = Class::Handle(function.owner()); | |
| 723 function.set_signature_class(enclosing_class); | |
| 724 ReportWarning("Warning: factory method '%s' should declare a list of " | |
| 725 "%d type parameter%s.\n", | |
| 726 function_name.ToCString(), | |
| 727 type_class.NumTypeParameters(), | |
| 728 type_class.NumTypeParameters() > 1 ? "s" : ""); | |
| 729 } else { | |
| 730 ReportError("factory method '%s' must declare %d type parameter%s.\n", | |
| 731 function_name.ToCString(), | |
| 732 type_class.NumTypeParameters(), | |
| 733 type_class.NumTypeParameters() > 1 ? "s" : ""); | |
| 734 } | |
| 735 } | |
| 736 } | |
| 737 } | |
| 651 type = FinalizeType(type); | 738 type = FinalizeType(type); |
| 652 function.set_result_type(type); | 739 function.set_result_type(type); |
| 653 // Resolve formal parameter types. | 740 // Resolve formal parameter types. |
| 654 const intptr_t num_parameters = function.NumberOfParameters(); | 741 const intptr_t num_parameters = function.NumberOfParameters(); |
| 655 for (intptr_t i = 0; i < num_parameters; i++) { | 742 for (intptr_t i = 0; i < num_parameters; i++) { |
| 656 type = function.ParameterTypeAt(i); | 743 type = function.ParameterTypeAt(i); |
| 657 type = ResolveType(cls, type); | 744 type = ResolveType(cls, type); |
| 658 function.SetParameterTypeAt(i, type); | 745 function.SetParameterTypeAt(i, type); |
| 659 type = FinalizeType(type); | 746 type = FinalizeType(type); |
| 660 function.SetParameterTypeAt(i, type); | 747 function.SetParameterTypeAt(i, type); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 873 ResolveInterfaces(cls, &visited); | 960 ResolveInterfaces(cls, &visited); |
| 874 Type& super_type = Type::Handle(cls.super_type()); | 961 Type& super_type = Type::Handle(cls.super_type()); |
| 875 if (!super_type.IsNull()) { | 962 if (!super_type.IsNull()) { |
| 876 const Class& super_class = Class::Handle(super_type.type_class()); | 963 const Class& super_class = Class::Handle(super_type.type_class()); |
| 877 // Finalize super class and super type. | 964 // Finalize super class and super type. |
| 878 FinalizeClass(super_class); | 965 FinalizeClass(super_class); |
| 879 super_type = FinalizeType(super_type); | 966 super_type = FinalizeType(super_type); |
| 880 cls.set_super_type(super_type); | 967 cls.set_super_type(super_type); |
| 881 } | 968 } |
| 882 if (cls.is_interface()) { | 969 if (cls.is_interface()) { |
| 883 Type& factory_type = Type::Handle(cls.factory_type()); | 970 if (cls.HasFactoryClass()) { |
| 884 if (!factory_type.IsNull()) { | 971 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 885 const Class& factory_class = Class::Handle(factory_type.type_class()); | 972 // Finalize factory class. |
| 886 // Finalize factory class and factory type. | |
| 887 if (!factory_class.is_finalized()) { | 973 if (!factory_class.is_finalized()) { |
| 888 FinalizeClass(factory_class); | 974 FinalizeClass(factory_class); |
| 889 // Finalizing the factory class may indirectly finalize this interface. | 975 // Finalizing the factory class may indirectly finalize this interface. |
| 890 if (cls.is_finalized()) { | 976 if (cls.is_finalized()) { |
| 891 return; | 977 return; |
| 892 } | 978 } |
| 893 } | 979 } |
| 894 factory_type = FinalizeType(factory_type); | |
| 895 cls.set_factory_type(factory_type); | |
| 896 } | 980 } |
| 897 } | 981 } |
| 898 // Finalize interface types (but not necessarily interface classes). | 982 // Finalize interface types (but not necessarily interface classes). |
| 899 Array& interface_types = Array::Handle(cls.interfaces()); | 983 Array& interface_types = Array::Handle(cls.interfaces()); |
| 900 Type& interface_type = Type::Handle(); | 984 Type& interface_type = Type::Handle(); |
| 901 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 985 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 902 interface_type ^= interface_types.At(i); | 986 interface_type ^= interface_types.At(i); |
| 903 interface_type = FinalizeType(interface_type); | 987 interface_type = FinalizeType(interface_type); |
| 904 interface_types.SetAt(i, interface_type); | 988 interface_types.SetAt(i, interface_type); |
| 905 } | 989 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1153 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | 1237 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); |
| 1154 ASSERT(msg_buffer != NULL); | 1238 ASSERT(msg_buffer != NULL); |
| 1155 va_list args; | 1239 va_list args; |
| 1156 va_start(args, format); | 1240 va_start(args, format); |
| 1157 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1241 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1158 va_end(args); | 1242 va_end(args); |
| 1159 isolate->long_jump_base()->Jump(1, msg_buffer); | 1243 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1160 UNREACHABLE(); | 1244 UNREACHABLE(); |
| 1161 } | 1245 } |
| 1162 | 1246 |
| 1247 void ClassFinalizer::ReportWarning(const char* format, ...) { | |
| 1248 if (FLAG_silent_warnings) return; | |
| 1249 static const int kBufferLength = 1024; | |
| 1250 Isolate* isolate = Isolate::Current(); | |
| 1251 ASSERT(isolate != NULL); | |
| 1252 Zone* zone = isolate->current_zone(); | |
| 1253 ASSERT(zone != NULL); | |
| 1254 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | |
| 1255 ASSERT(msg_buffer != NULL); | |
| 1256 va_list args; | |
| 1257 va_start(args, format); | |
| 1258 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | |
| 1259 va_end(args); | |
| 1260 if (FLAG_warning_as_error) { | |
| 1261 isolate->long_jump_base()->Jump(1, msg_buffer); | |
| 1262 UNREACHABLE(); | |
| 1263 } else { | |
| 1264 OS::Print(msg_buffer); | |
| 1265 } | |
| 1266 } | |
| 1267 | |
| 1163 } // namespace dart | 1268 } // namespace dart |
| OLD | NEW |