Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 if (factory_signature_class.NumTypeParameters() > 0) { | 379 if (factory_signature_class.NumTypeParameters() > 0) { |
| 380 ResolveAndFinalizeUpperBounds(factory_signature_class); | 380 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 381 const TypeArguments& expected_type_parameters = | 381 const TypeArguments& expected_type_parameters = |
| 382 TypeArguments::Handle(factory_signature_class.type_parameters()); | 382 TypeArguments::Handle(factory_signature_class.type_parameters()); |
| 383 const TypeArguments& actual_type_parameters = | 383 const TypeArguments& actual_type_parameters = |
| 384 TypeArguments::Handle(factory_class.type_parameters()); | 384 TypeArguments::Handle(factory_class.type_parameters()); |
| 385 const TypeArguments& expected_type_parameter_bounds = | 385 const TypeArguments& expected_type_parameter_bounds = |
| 386 TypeArguments::Handle(factory_signature_class.type_parameter_bounds()); | 386 TypeArguments::Handle(factory_signature_class.type_parameter_bounds()); |
| 387 const TypeArguments& actual_type_parameter_bounds = | 387 const TypeArguments& actual_type_parameter_bounds = |
| 388 TypeArguments::Handle(factory_class.type_parameter_bounds()); | 388 TypeArguments::Handle(factory_class.type_parameter_bounds()); |
| 389 if (!AbstractTypeArguments::AreEqual(expected_type_parameters, | 389 if (!TypeArguments::AreIdenticalTypeParameters(expected_type_parameters, |
| 390 actual_type_parameters) || | 390 actual_type_parameters) || |
| 391 !AbstractTypeArguments::AreEqual(expected_type_parameter_bounds, | 391 !AbstractTypeArguments::AreEqual(expected_type_parameter_bounds, |
| 392 actual_type_parameter_bounds)) { | 392 actual_type_parameter_bounds)) { |
| 393 const String& interface_name = String::Handle(interface.Name()); | 393 const String& interface_name = String::Handle(interface.Name()); |
| 394 const String& factory_name = String::Handle(factory_class.Name()); | 394 const String& factory_name = String::Handle(factory_class.Name()); |
| 395 const Script& script = Script::Handle(interface.script()); | 395 const Script& script = Script::Handle(interface.script()); |
| 396 ReportError(script, unresolved_factory_class.token_index(), | 396 ReportError(script, unresolved_factory_class.token_index(), |
| 397 "mismatch in number, names, or bounds of type parameters " | 397 "mismatch in number, names, or bounds of type parameters " |
| 398 "between default clause of interface '%s' and actual factory " | 398 "between default clause of interface '%s' and actual factory " |
| 399 "class '%s'", | 399 "class '%s'", |
| 400 interface_name.ToCString(), | 400 interface_name.ToCString(), |
| 401 factory_name.ToCString()); | 401 factory_name.ToCString()); |
| 402 } | 402 } |
| 403 } | 403 } |
| 404 // Verify that the type parameters of the factory class and of the interface | 404 // Verify that the type parameters of the factory class and of the interface |
| 405 // have identical names. | 405 // have identical names. |
| 406 const TypeArguments& interface_type_parameters = | 406 const TypeArguments& interface_type_parameters = |
| 407 TypeArguments::Handle(interface.type_parameters()); | 407 TypeArguments::Handle(interface.type_parameters()); |
| 408 const TypeArguments& factory_type_parameters = | 408 const TypeArguments& factory_type_parameters = |
| 409 TypeArguments::Handle(factory_class.type_parameters()); | 409 TypeArguments::Handle(factory_class.type_parameters()); |
| 410 if (!AbstractTypeArguments::AreEqual(interface_type_parameters, | 410 if (!TypeArguments::AreIdenticalTypeParameters(interface_type_parameters, |
| 411 factory_type_parameters)) { | 411 factory_type_parameters)) { |
| 412 const String& interface_name = String::Handle(interface.Name()); | 412 const String& interface_name = String::Handle(interface.Name()); |
| 413 const String& factory_name = String::Handle(factory_class.Name()); | 413 const String& factory_name = String::Handle(factory_class.Name()); |
| 414 const Script& script = Script::Handle(interface.script()); | 414 const Script& script = Script::Handle(interface.script()); |
| 415 ReportError(script, unresolved_factory_class.token_index(), | 415 ReportError(script, unresolved_factory_class.token_index(), |
| 416 "mismatch in number or names of type parameters between " | 416 "mismatch in number or names of type parameters between " |
| 417 "interface '%s' and default factory class '%s'", | 417 "interface '%s' and default factory class '%s'", |
| 418 interface_name.ToCString(), | 418 interface_name.ToCString(), |
| 419 factory_name.ToCString()); | 419 factory_name.ToCString()); |
| 420 } | 420 } |
| 421 } | 421 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 intptr_t num_arguments = arguments.Length(); | 469 intptr_t num_arguments = arguments.Length(); |
| 470 AbstractType& type_argument = AbstractType::Handle(); | 470 AbstractType& type_argument = AbstractType::Handle(); |
| 471 for (intptr_t i = 0; i < num_arguments; i++) { | 471 for (intptr_t i = 0; i < num_arguments; i++) { |
| 472 type_argument = arguments.TypeAt(i); | 472 type_argument = arguments.TypeAt(i); |
| 473 ResolveType(cls, type_argument, finalization); | 473 ResolveType(cls, type_argument, finalization); |
| 474 } | 474 } |
| 475 } | 475 } |
| 476 } | 476 } |
| 477 | 477 |
| 478 | 478 |
| 479 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { | |
| 480 const TypeArguments& type_parameters = | |
| 481 TypeArguments::Handle(cls.type_parameters()); | |
| 482 if (!type_parameters.IsNull()) { | |
| 483 TypeParameter& type_parameter = TypeParameter::Handle(); | |
| 484 intptr_t num_types = type_parameters.Length(); | |
|
srdjan
2012/03/30 21:46:52
const
regis
2012/03/30 22:01:43
Done.
| |
| 485 for (intptr_t i = 0; i < num_types; i++) { | |
| 486 type_parameter ^= type_parameters.TypeAt(i); | |
| 487 type_parameter ^= FinalizeType(cls, type_parameter, kFinalizeWellFormed); | |
| 488 type_parameters.SetTypeAt(i, type_parameter); | |
| 489 } | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 | |
| 479 // Finalize the type argument vector 'arguments' of the type defined by the | 494 // Finalize the type argument vector 'arguments' of the type defined by the |
| 480 // class 'cls' parameterized with the type arguments 'cls_args'. | 495 // class 'cls' parameterized with the type arguments 'cls_args'. |
| 481 // The vector 'cls_args' is already initialized as a subvector at the correct | 496 // The vector 'cls_args' is already initialized as a subvector at the correct |
| 482 // position in the passed in 'arguments' vector. | 497 // position in the passed in 'arguments' vector. |
| 483 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 498 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
| 484 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 499 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
| 485 // vector. | 500 // vector. |
| 486 // Example: | 501 // Example: |
| 487 // Declared: class C<K, V> extends B<V> { ... } | 502 // Declared: class C<K, V> extends B<V> { ... } |
| 488 // class B<T> extends A<int> { ... } | 503 // class B<T> extends A<int> { ... } |
| 489 // Input: C<String, double> expressed as | 504 // Input: C<String, double> expressed as |
| 490 // cls = C, arguments = [null, null, String, double], | 505 // cls = C, arguments = [null, null, String, double], |
| 491 // i.e. cls_args = [String, double], offset = 2, length = 2. | 506 // i.e. cls_args = [String, double], offset = 2, length = 2. |
| 492 // Output: arguments = [int, double, String, double] | 507 // Output: arguments = [int, double, String, double] |
| 493 void ClassFinalizer::FinalizeTypeArguments( | 508 void ClassFinalizer::FinalizeTypeArguments( |
| 494 const Class& cls, | 509 const Class& cls, |
| 495 const AbstractTypeArguments& arguments, | 510 const AbstractTypeArguments& arguments, |
| 496 FinalizationKind finalization) { | 511 FinalizationKind finalization) { |
| 497 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 512 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 513 if (!cls.is_finalized()) { | |
| 514 FinalizeTypeParameters(cls); | |
| 515 } | |
| 498 Type& super_type = Type::Handle(cls.super_type()); | 516 Type& super_type = Type::Handle(cls.super_type()); |
| 499 if (!super_type.IsNull()) { | 517 if (!super_type.IsNull()) { |
| 500 super_type ^= FinalizeType(cls, super_type, finalization); | 518 super_type ^= FinalizeType(cls, super_type, finalization); |
| 501 cls.set_super_type(super_type); | 519 cls.set_super_type(super_type); |
| 502 const Class& super_class = Class::Handle(super_type.type_class()); | 520 const Class& super_class = Class::Handle(super_type.type_class()); |
| 503 const AbstractTypeArguments& super_type_args = | 521 const AbstractTypeArguments& super_type_args = |
| 504 AbstractTypeArguments::Handle(super_type.arguments()); | 522 AbstractTypeArguments::Handle(super_type.arguments()); |
| 505 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 523 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 506 const intptr_t offset = super_class.NumTypeArguments(); | 524 const intptr_t offset = super_class.NumTypeArguments(); |
| 507 const intptr_t super_offset = offset - num_super_type_params; | 525 const intptr_t super_offset = offset - num_super_type_params; |
| 508 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 526 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); |
| 509 AbstractType& super_type_arg = AbstractType::Handle(); | 527 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
| 510 for (intptr_t i = 0; i < num_super_type_params; i++) { | 528 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 511 super_type_arg = super_type_args.TypeAt(super_offset + i); | 529 if (!super_type_args.IsNull()) { |
| 512 if (!super_type_arg.IsInstantiated()) { | 530 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 513 super_type_arg = super_type_arg.InstantiateFrom(arguments); | 531 if (!super_type_arg.IsInstantiated()) { |
| 532 super_type_arg = super_type_arg.InstantiateFrom(arguments); | |
| 533 } | |
| 534 super_type_arg = super_type_arg.Canonicalize(); | |
| 514 } | 535 } |
| 515 super_type_arg = super_type_arg.Canonicalize(); | |
| 516 arguments.SetTypeAt(super_offset + i, super_type_arg); | 536 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 517 } | 537 } |
| 518 FinalizeTypeArguments(super_class, arguments, finalization); | 538 FinalizeTypeArguments(super_class, arguments, finalization); |
| 519 } | 539 } |
| 520 } | 540 } |
| 521 | 541 |
| 522 | 542 |
| 523 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 543 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
| 524 const AbstractType& type, | 544 const AbstractType& type, |
| 525 FinalizationKind finalization) { | 545 FinalizationKind finalization) { |
| 526 if (type.IsFinalized()) { | 546 if (type.IsFinalized()) { |
| 527 return type.raw(); | 547 return type.raw(); |
| 528 } | 548 } |
| 529 ASSERT(type.IsResolved()); | 549 ASSERT(type.IsResolved()); |
| 530 ASSERT((finalization == kFinalize) || (finalization == kFinalizeWellFormed)); | 550 ASSERT((finalization == kFinalize) || (finalization == kFinalizeWellFormed)); |
| 531 | 551 |
| 532 if (FLAG_trace_type_finalization) { | 552 if (FLAG_trace_type_finalization) { |
| 533 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); | 553 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 534 } | 554 } |
| 535 | 555 |
| 536 if (type.IsTypeParameter()) { | 556 if (type.IsTypeParameter()) { |
| 537 ASSERT(!cls.IsNull()); | |
| 538 TypeParameter& type_parameter = TypeParameter::Handle(); | 557 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 539 type_parameter ^= type.raw(); | 558 type_parameter ^= type.raw(); |
| 559 const Class& parameterized_class = | |
| 560 Class::Handle(type_parameter.parameterized_class()); | |
| 561 ASSERT(!parameterized_class.IsNull()); | |
| 540 // The index must reflect the position of this type parameter in the type | 562 // The index must reflect the position of this type parameter in the type |
| 541 // arguments vector of the enclosing class. The offset to add is the number | 563 // arguments vector of its parameterized class. The offset to add is the |
| 542 // of type arguments in the super type, which is equal to the difference in | 564 // number of type arguments in the super type, which is equal to the |
| 543 // number of type arguments and type parameters of the enclosing class. | 565 // difference in number of type arguments and type parameters of the |
| 544 const intptr_t offset = cls.NumTypeArguments() - cls.NumTypeParameters(); | 566 // parameterized class. |
| 567 const intptr_t offset = parameterized_class.NumTypeArguments() - | |
| 568 parameterized_class.NumTypeParameters(); | |
| 545 type_parameter.set_index(type_parameter.Index() + offset); | 569 type_parameter.set_index(type_parameter.Index() + offset); |
| 546 type_parameter.set_is_finalized(); | 570 type_parameter.set_is_finalized(); |
| 547 // We do not canonicalize type parameters. | 571 // We do not canonicalize type parameters. |
| 548 return type_parameter.raw(); | 572 return type_parameter.raw(); |
| 549 } | 573 } |
| 550 | 574 |
| 551 // At this point, we can only have a parameterized_type. | 575 // At this point, we can only have a parameterized_type. |
| 552 Type& parameterized_type = Type::Handle(); | 576 Type& parameterized_type = Type::Handle(); |
| 553 parameterized_type ^= type.raw(); | 577 parameterized_type ^= type.raw(); |
| 554 | 578 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 576 type_argument = FinalizeType(cls, type_argument, finalization); | 600 type_argument = FinalizeType(cls, type_argument, finalization); |
| 577 arguments.SetTypeAt(i, type_argument); | 601 arguments.SetTypeAt(i, type_argument); |
| 578 } | 602 } |
| 579 } | 603 } |
| 580 | 604 |
| 581 // The type class does not need to be finalized in order to finalize the type, | 605 // The type class does not need to be finalized in order to finalize the type, |
| 582 // however, it must at least be resolved (this was done as part of resolving | 606 // however, it must at least be resolved (this was done as part of resolving |
| 583 // the type itself, a precondition to calling FinalizeType) and the upper | 607 // the type itself, a precondition to calling FinalizeType) and the upper |
| 584 // bounds of its type parameters must be finalized (done here). | 608 // bounds of its type parameters must be finalized (done here). |
| 585 Class& type_class = Class::Handle(parameterized_type.type_class()); | 609 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 610 if (!type_class.is_finalized()) { | |
| 611 FinalizeTypeParameters(type_class); | |
| 612 } | |
| 586 | 613 |
| 587 // If the type class is a signature class, we are finalizing its signature | 614 // If the type class is a signature class, we are finalizing its signature |
| 588 // type, thereby finalizing the result type and parameter types of its | 615 // type, thereby finalizing the result type and parameter types of its |
| 589 // signature function. | 616 // signature function. |
| 590 // Do this before marking this type as finalized in order to detect cycles. | 617 // Do this before marking this type as finalized in order to detect cycles. |
| 591 if (type_class.IsSignatureClass()) { | 618 if (type_class.IsSignatureClass()) { |
| 592 // Signature classes are finalized upon creation. | 619 // Signature classes are finalized upon creation. |
| 593 ASSERT(type_class.is_finalized()); | 620 ASSERT(type_class.is_finalized()); |
| 594 // Resolve and finalize the result and parameter types of the signature | 621 // Resolve and finalize the result and parameter types of the signature |
| 595 // function of this signature class. | 622 // function of this signature class. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 618 Error::Handle(), // No previous error. | 645 Error::Handle(), // No previous error. |
| 619 cls, parameterized_type, finalization, | 646 cls, parameterized_type, finalization, |
| 620 "wrong number of type arguments in type '%s'", | 647 "wrong number of type arguments in type '%s'", |
| 621 String::Handle(parameterized_type.Name()).ToCString()); | 648 String::Handle(parameterized_type.Name()).ToCString()); |
| 622 return parameterized_type.raw(); | 649 return parameterized_type.raw(); |
| 623 } | 650 } |
| 624 // The full type argument vector consists of the type arguments of the | 651 // The full type argument vector consists of the type arguments of the |
| 625 // super types of type_class, which may be initialized from the parsed | 652 // super types of type_class, which may be initialized from the parsed |
| 626 // type arguments, followed by the parsed type arguments. | 653 // type arguments, followed by the parsed type arguments. |
| 627 if (num_type_arguments > 0) { | 654 if (num_type_arguments > 0) { |
| 628 TypeArguments& full_arguments = TypeArguments::Handle( | 655 TypeArguments& full_arguments = TypeArguments::Handle(); |
| 629 TypeArguments::New(num_type_arguments)); | 656 // If no type arguments were parsed and if the super types do not prepend |
| 630 // Copy the parsed type arguments at the correct offset in the full type | 657 // type arguments to the vector, we can leave the vector as null. |
| 631 // argument vector. | 658 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 632 const intptr_t offset = num_type_arguments - num_type_parameters; | 659 full_arguments = TypeArguments::New(num_type_arguments); |
| 633 AbstractType& type = AbstractType::Handle(Type::DynamicType()); | 660 // Copy the parsed type arguments at the correct offset in the full type |
| 634 for (intptr_t i = 0; i < num_type_parameters; i++) { | 661 // argument vector. |
| 635 // If no type parameters were provided, a raw type is desired, so we | 662 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 636 // create a vector of DynamicType. | 663 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); |
| 637 if (!arguments.IsNull()) { | 664 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 638 type = arguments.TypeAt(i); | 665 // If no type parameters were provided, a raw type is desired, so we |
| 666 // create a vector of DynamicType. | |
| 667 if (!arguments.IsNull()) { | |
| 668 type_arg = arguments.TypeAt(i); | |
| 669 } | |
| 670 ASSERT(type_arg.IsFinalized()); // Index of type parameter is adjusted. | |
| 671 full_arguments.SetTypeAt(offset + i, type_arg); | |
| 639 } | 672 } |
| 640 full_arguments.SetTypeAt(offset + i, type); | 673 if (type_class.IsSignatureClass()) { |
| 674 const Function& signature_fun = | |
| 675 Function::Handle(type_class.signature_function()); | |
| 676 ASSERT(!signature_fun.is_static()); | |
| 677 const Class& sig_fun_owner = Class::Handle(signature_fun.owner()); | |
| 678 FinalizeTypeArguments(sig_fun_owner, full_arguments, finalization); | |
| 679 } else { | |
| 680 FinalizeTypeArguments(type_class, full_arguments, finalization); | |
| 681 } | |
| 682 if (full_arguments.IsRaw(num_type_arguments)) { | |
| 683 // The parameterized_type is raw. Set its argument vector to null, which | |
| 684 // is more efficient in type tests. | |
| 685 full_arguments = TypeArguments::null(); | |
| 686 } else { | |
| 687 // FinalizeTypeArguments can modify 'full_arguments', | |
| 688 // canonicalize afterwards. | |
| 689 full_arguments ^= full_arguments.Canonicalize(); | |
| 690 } | |
| 691 parameterized_type.set_arguments(full_arguments); | |
| 692 } else { | |
| 693 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | |
| 641 } | 694 } |
| 642 if (type_class.IsSignatureClass()) { | |
| 643 const Function& signature_fun = | |
| 644 Function::Handle(type_class.signature_function()); | |
| 645 ASSERT(!signature_fun.is_static()); | |
| 646 const Class& signature_fun_owner = Class::Handle(signature_fun.owner()); | |
| 647 FinalizeTypeArguments(signature_fun_owner, full_arguments, finalization); | |
| 648 } else { | |
| 649 FinalizeTypeArguments(type_class, full_arguments, finalization); | |
| 650 } | |
| 651 // FinalizeTypeArguments can modify 'full_arguments', | |
| 652 // canonicalize afterwards. | |
| 653 full_arguments ^= full_arguments.Canonicalize(); | |
| 654 parameterized_type.set_arguments(full_arguments); | |
| 655 | |
| 656 // Mark the type as finalized. | 695 // Mark the type as finalized. |
| 657 parameterized_type.set_is_finalized(); | 696 parameterized_type.set_is_finalized(); |
| 658 | 697 |
| 659 // Upper bounds of the finalized type arguments are only verified in checked | 698 // Upper bounds of the finalized type arguments are only verified in checked |
| 660 // mode, since bound errors are never reported by the vm in production mode. | 699 // mode, since bound errors are never reported by the vm in production mode. |
| 661 if (FLAG_enable_type_checks && full_arguments.IsInstantiated()) { | 700 if (FLAG_enable_type_checks && |
| 701 !full_arguments.IsNull() && | |
| 702 full_arguments.IsInstantiated()) { | |
| 662 ResolveAndFinalizeUpperBounds(type_class); | 703 ResolveAndFinalizeUpperBounds(type_class); |
| 663 Error& malformed_error = Error::Handle(); | 704 Error& malformed_error = Error::Handle(); |
| 664 // Pass the full type argument vector as the bounds instantiator. | 705 // Pass the full type argument vector as the bounds instantiator. |
| 665 if (!full_arguments.IsWithinBoundsOf(type_class, | 706 if (!full_arguments.IsWithinBoundsOf(type_class, |
| 666 full_arguments, | 707 full_arguments, |
| 667 &malformed_error)) { | 708 &malformed_error)) { |
| 668 ASSERT(!malformed_error.IsNull()); | 709 ASSERT(!malformed_error.IsNull()); |
| 669 // The type argument vector of the type is not within bounds. The type | 710 // The type argument vector of the type is not within bounds. The type |
| 670 // is malformed. Prepend malformed_error to new malformed type error in | 711 // is malformed. Prepend malformed_error to new malformed type error in |
| 671 // order to report both locations. | 712 // order to report both locations. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 if (!IsSuperCycleFree(cls)) { | 975 if (!IsSuperCycleFree(cls)) { |
| 935 const String& name = String::Handle(cls.Name()); | 976 const String& name = String::Handle(cls.Name()); |
| 936 const Script& script = Script::Handle(cls.script()); | 977 const Script& script = Script::Handle(cls.script()); |
| 937 ReportError(script, cls.token_index(), | 978 ReportError(script, cls.token_index(), |
| 938 "class '%s' has a cycle in its superclass relationship", | 979 "class '%s' has a cycle in its superclass relationship", |
| 939 name.ToCString()); | 980 name.ToCString()); |
| 940 } | 981 } |
| 941 const GrowableObjectArray& visited = | 982 const GrowableObjectArray& visited = |
| 942 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 983 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 943 ResolveInterfaces(cls, visited); | 984 ResolveInterfaces(cls, visited); |
| 985 // Finalize super class. | |
| 986 const Class& super_class = Class::Handle(cls.SuperClass()); | |
| 987 if (!super_class.IsNull()) { | |
| 988 FinalizeClass(super_class, generating_snapshot); | |
| 989 } | |
| 990 // Finalize type parameters before finalizing the super type. | |
| 991 FinalizeTypeParameters(cls); | |
| 992 // Finalize super type. | |
| 944 Type& super_type = Type::Handle(cls.super_type()); | 993 Type& super_type = Type::Handle(cls.super_type()); |
| 945 if (!super_type.IsNull()) { | 994 if (!super_type.IsNull()) { |
| 946 const Class& super_class = Class::Handle(super_type.type_class()); | |
| 947 // Finalize super class and super type. | |
| 948 FinalizeClass(super_class, generating_snapshot); | |
| 949 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); | 995 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); |
| 950 cls.set_super_type(super_type); | 996 cls.set_super_type(super_type); |
| 951 } | 997 } |
| 998 // Finalize factory class, if any. | |
| 952 if (cls.is_interface()) { | 999 if (cls.is_interface()) { |
| 953 if (cls.HasFactoryClass()) { | 1000 if (cls.HasFactoryClass()) { |
| 954 const Class& factory_class = Class::Handle(cls.FactoryClass()); | 1001 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 955 // Finalize factory class. | |
| 956 if (!factory_class.is_finalized()) { | 1002 if (!factory_class.is_finalized()) { |
| 957 FinalizeClass(factory_class, generating_snapshot); | 1003 FinalizeClass(factory_class, generating_snapshot); |
| 958 // Finalizing the factory class may indirectly finalize this interface. | 1004 // Finalizing the factory class may indirectly finalize this interface. |
| 959 if (cls.is_finalized()) { | 1005 if (cls.is_finalized()) { |
| 960 return; | 1006 return; |
| 961 } | 1007 } |
| 962 } | 1008 } |
| 963 } | 1009 } |
| 964 } | 1010 } |
| 965 // Finalize interface types (but not necessarily interface classes). | 1011 // Finalize interface types (but not necessarily interface classes). |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1258 void ClassFinalizer::ReportError(const char* format, ...) { | 1304 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1259 va_list args; | 1305 va_list args; |
| 1260 va_start(args, format); | 1306 va_start(args, format); |
| 1261 const Error& error = Error::Handle( | 1307 const Error& error = Error::Handle( |
| 1262 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1308 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1263 va_end(args); | 1309 va_end(args); |
| 1264 ReportError(error); | 1310 ReportError(error); |
| 1265 } | 1311 } |
| 1266 | 1312 |
| 1267 } // namespace dart | 1313 } // namespace dart |
| OLD | NEW |