| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 "cannot resolve redirecting factory"); | 449 "cannot resolve redirecting factory"); |
| 450 target_target = Function::null(); | 450 target_target = Function::null(); |
| 451 } | 451 } |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 factory.SetRedirectionType(target_type); | 454 factory.SetRedirectionType(target_type); |
| 455 factory.SetRedirectionTarget(target_target); | 455 factory.SetRedirectionTarget(target_target); |
| 456 } | 456 } |
| 457 | 457 |
| 458 | 458 |
| 459 RawAbstractType* ClassFinalizer::ResolveTypeClass(const Class& cls, | 459 void ClassFinalizer::ResolveTypeClass(const Class& cls, const Type& type) { |
| 460 const Type& type) { | |
| 461 if (type.IsFinalized()) { | 460 if (type.IsFinalized()) { |
| 462 return type.raw(); | 461 return; |
| 463 } | 462 } |
| 464 if (FLAG_trace_type_finalization) { | 463 if (FLAG_trace_type_finalization) { |
| 465 THR_Print("Resolve type class of '%s'\n", | 464 THR_Print("Resolve type class of '%s'\n", |
| 466 String::Handle(type.Name()).ToCString()); | 465 String::Handle(type.Name()).ToCString()); |
| 467 } | 466 } |
| 468 | 467 |
| 469 // Type parameters are always resolved in the parser in the correct | 468 // Type parameters are always resolved in the parser in the correct |
| 470 // non-static scope or factory scope. That resolution scope is unknown here. | 469 // non-static scope or factory scope. That resolution scope is unknown here. |
| 471 // Being able to resolve a type parameter from class cls here would indicate | 470 // Being able to resolve a type parameter from class cls here would indicate |
| 472 // that the type parameter appeared in a static scope. Leaving the type as | 471 // that the type parameter appeared in a static scope. Leaving the type as |
| 473 // unresolved is the correct thing to do. | 472 // unresolved is the correct thing to do. |
| 474 | 473 |
| 475 // Lookup the type class if necessary. | 474 // Lookup the type class if necessary. |
| 476 Class& type_class = Class::Handle(); | 475 Class& type_class = Class::Handle(); |
| 477 if (type.HasResolvedTypeClass()) { | 476 if (type.HasResolvedTypeClass()) { |
| 478 type_class = type.type_class(); | 477 type_class = type.type_class(); |
| 479 } else { | 478 } else { |
| 480 const UnresolvedClass& unresolved_class = | 479 const UnresolvedClass& unresolved_class = |
| 481 UnresolvedClass::Handle(type.unresolved_class()); | 480 UnresolvedClass::Handle(type.unresolved_class()); |
| 482 type_class = ResolveClass(cls, unresolved_class); | 481 type_class = ResolveClass(cls, unresolved_class); |
| 483 if (type_class.IsNull()) { | 482 if (type_class.IsNull()) { |
| 484 // The type class could not be resolved. The type is malformed. | 483 // The type class could not be resolved. The type is malformed. |
| 485 FinalizeMalformedType( | 484 FinalizeMalformedType( |
| 486 Error::Handle(), // No previous error. | 485 Error::Handle(), // No previous error. |
| 487 Script::Handle(cls.script()), | 486 Script::Handle(cls.script()), |
| 488 type, | 487 type, |
| 489 "cannot resolve class '%s' from '%s'", | 488 "cannot resolve class '%s' from '%s'", |
| 490 String::Handle(unresolved_class.Name()).ToCString(), | 489 String::Handle(unresolved_class.Name()).ToCString(), |
| 491 String::Handle(cls.Name()).ToCString()); | 490 String::Handle(cls.Name()).ToCString()); |
| 492 return type.raw(); | 491 return; |
| 493 } | 492 } |
| 493 // Replace unresolved class with resolved type class. |
| 494 type.set_type_class(type_class); |
| 494 } | 495 } |
| 495 // Promote the Type to a FunctionType in case its type class is a typedef. | 496 // Promote the type to a function type in case its type class is a typedef. |
| 496 if (type_class.IsTypedefClass()) { | 497 // Note that the type may already be a function type if it was parsed as a |
| 497 return FunctionType::New(type_class, | 498 // formal parameter function type. |
| 498 TypeArguments::Handle(type.arguments()), | 499 if (!type.IsFunctionType() && |
| 499 Function::Handle(type_class.signature_function()), | 500 type_class.IsTypedefClass() && |
| 500 type.token_pos()); | 501 !type.IsMalformedOrMalbounded()) { |
| 502 type.set_signature(Function::Handle(type_class.signature_function())); |
| 501 } | 503 } |
| 502 // Replace unresolved class with resolved type class. | 504 ASSERT(!type_class.IsTypedefClass() || |
| 503 type.set_type_class(type_class); | 505 (type.signature() != Function::null())); |
| 504 return type.raw(); | |
| 505 } | 506 } |
| 506 | 507 |
| 507 | 508 |
| 508 RawAbstractType* ClassFinalizer::ResolveType(const Class& cls, | 509 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
| 509 const AbstractType& type) { | |
| 510 if (type.IsResolved()) { | 510 if (type.IsResolved()) { |
| 511 return type.raw(); | 511 return; |
| 512 } | 512 } |
| 513 if (FLAG_trace_type_finalization) { | 513 if (FLAG_trace_type_finalization) { |
| 514 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 514 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 515 } | 515 } |
| 516 AbstractType& resolved_type = AbstractType::Handle(); | |
| 517 if (type.IsType()) { | 516 if (type.IsType()) { |
| 518 resolved_type = ResolveTypeClass(cls, Type::Cast(type)); | 517 ResolveTypeClass(cls, Type::Cast(type)); |
| 519 if (resolved_type.IsMalformed()) { | 518 if (type.IsMalformed()) { |
| 520 ASSERT(resolved_type.IsResolved()); | 519 ASSERT(type.IsResolved()); |
| 521 return resolved_type.raw(); | 520 return; |
| 522 } | 521 } |
| 523 } else { | 522 } |
| 524 ASSERT(type.IsFunctionType()); | 523 // Mark type as resolved before resolving its type arguments and, in case of a |
| 525 const Function& signature = | 524 // function type, its signature, in order to avoid cycles. |
| 526 Function::Handle(FunctionType::Cast(type).signature()); | 525 type.SetIsResolved(); |
| 527 const Class& scope_class = | 526 // Resolve type arguments, if any. |
| 528 Class::Handle(FunctionType::Cast(type).scope_class()); | 527 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
| 528 if (!arguments.IsNull()) { |
| 529 const intptr_t num_arguments = arguments.Length(); |
| 530 AbstractType& type_argument = AbstractType::Handle(); |
| 531 for (intptr_t i = 0; i < num_arguments; i++) { |
| 532 type_argument = arguments.TypeAt(i); |
| 533 ResolveType(cls, type_argument); |
| 534 } |
| 535 } |
| 536 // Resolve signature if function type. |
| 537 if (type.IsFunctionType()) { |
| 538 const Function& signature = Function::Handle(Type::Cast(type).signature()); |
| 539 const Class& scope_class = Class::Handle(type.type_class()); |
| 529 if (scope_class.IsTypedefClass()) { | 540 if (scope_class.IsTypedefClass()) { |
| 530 ResolveSignature(scope_class, signature); | 541 ResolveSignature(scope_class, signature); |
| 531 } else { | 542 } else { |
| 532 ResolveSignature(cls, signature); | 543 ResolveSignature(cls, signature); |
| 533 } | 544 } |
| 534 resolved_type = type.raw(); | |
| 535 } | 545 } |
| 536 // Mark type as resolved before resolving its type arguments in order to avoid | |
| 537 // repeating resolution of recursive types. | |
| 538 resolved_type.SetIsResolved(); | |
| 539 // Resolve type arguments, if any. | |
| 540 const TypeArguments& arguments = | |
| 541 TypeArguments::Handle(resolved_type.arguments()); | |
| 542 if (!arguments.IsNull()) { | |
| 543 const intptr_t num_arguments = arguments.Length(); | |
| 544 AbstractType& type_argument = AbstractType::Handle(); | |
| 545 for (intptr_t i = 0; i < num_arguments; i++) { | |
| 546 type_argument = arguments.TypeAt(i); | |
| 547 type_argument = ResolveType(cls, type_argument); | |
| 548 arguments.SetTypeAt(i, type_argument); | |
| 549 } | |
| 550 } | |
| 551 return resolved_type.raw(); | |
| 552 } | 546 } |
| 553 | 547 |
| 554 | 548 |
| 555 void ClassFinalizer::FinalizeTypeParameters( | 549 void ClassFinalizer::FinalizeTypeParameters( |
| 556 const Class& cls, | 550 const Class& cls, |
| 557 PendingTypes* pending_types) { | 551 PendingTypes* pending_types) { |
| 558 if (FLAG_trace_type_finalization) { | 552 if (FLAG_trace_type_finalization) { |
| 559 THR_Print("Finalizing type parameters of '%s'\n", | 553 THR_Print("Finalizing type parameters of '%s'\n", |
| 560 String::Handle(cls.Name()).ToCString()); | 554 String::Handle(cls.Name()).ToCString()); |
| 561 } | 555 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 } | 641 } |
| 648 } | 642 } |
| 649 | 643 |
| 650 | 644 |
| 651 // Expand the type arguments of the given type and finalize its full type | 645 // Expand the type arguments of the given type and finalize its full type |
| 652 // argument vector. Return the number of type arguments (0 for a raw type). | 646 // argument vector. Return the number of type arguments (0 for a raw type). |
| 653 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( | 647 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
| 654 const Class& cls, | 648 const Class& cls, |
| 655 const AbstractType& type, | 649 const AbstractType& type, |
| 656 PendingTypes* pending_types) { | 650 PendingTypes* pending_types) { |
| 657 Zone* Z = Thread::Current()->zone(); | 651 Zone* zone = Thread::Current()->zone(); |
| 658 // The type class does not need to be finalized in order to finalize the type, | 652 // The type class does not need to be finalized in order to finalize the type, |
| 659 // however, it must at least be resolved (this was done as part of resolving | 653 // however, it must at least be resolved (this was done as part of resolving |
| 660 // the type itself, a precondition to calling FinalizeType). | 654 // the type itself, a precondition to calling FinalizeType). |
| 661 // Also, the interfaces of the type class must be resolved and the type | 655 // Also, the interfaces of the type class must be resolved and the type |
| 662 // parameters of the type class must be finalized. | 656 // parameters of the type class must be finalized. |
| 663 Class& type_class = Class::Handle(Z, type.type_class()); | 657 Class& type_class = Class::Handle(zone, type.type_class()); |
| 664 if (!type_class.is_type_finalized()) { | 658 if (!type_class.is_type_finalized()) { |
| 665 FinalizeTypeParameters(type_class, pending_types); | 659 FinalizeTypeParameters(type_class, pending_types); |
| 666 ResolveUpperBounds(type_class); | 660 ResolveUpperBounds(type_class); |
| 667 } | 661 } |
| 668 | 662 |
| 669 // The finalized type argument vector needs num_type_arguments types. | 663 // The finalized type argument vector needs num_type_arguments types. |
| 670 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 664 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 671 // The class has num_type_parameters type parameters. | 665 // The class has num_type_parameters type parameters. |
| 672 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 666 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 673 | 667 |
| 674 // If we are not reifying types, drop type arguments. | 668 // If we are not reifying types, drop type arguments. |
| 675 if (!FLAG_reify) { | 669 if (!FLAG_reify) { |
| 676 type.set_arguments(TypeArguments::Handle(Z, TypeArguments::null())); | 670 type.set_arguments(TypeArguments::Handle(zone, TypeArguments::null())); |
| 677 } | 671 } |
| 678 | 672 |
| 679 // Initialize the type argument vector. | 673 // Initialize the type argument vector. |
| 680 // Check the number of parsed type arguments, if any. | 674 // Check the number of parsed type arguments, if any. |
| 681 // Specifying no type arguments indicates a raw type, which is not an error. | 675 // Specifying no type arguments indicates a raw type, which is not an error. |
| 682 // However, type parameter bounds are checked below, even for a raw type. | 676 // However, type parameter bounds are checked below, even for a raw type. |
| 683 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); | 677 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); |
| 684 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 678 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 685 // Wrong number of type arguments. The type is mapped to the raw type. | 679 // Wrong number of type arguments. The type is mapped to the raw type. |
| 686 if (Isolate::Current()->error_on_bad_type()) { | 680 if (Isolate::Current()->error_on_bad_type()) { |
| 687 const String& type_class_name = String::Handle(Z, type_class.Name()); | 681 const String& type_class_name = String::Handle(zone, type_class.Name()); |
| 688 ReportError(cls, type.token_pos(), | 682 ReportError(cls, type.token_pos(), |
| 689 "wrong number of type arguments for class '%s'", | 683 "wrong number of type arguments for class '%s'", |
| 690 type_class_name.ToCString()); | 684 type_class_name.ToCString()); |
| 691 } | 685 } |
| 692 // Make the type raw and continue without reporting any error. | 686 // Make the type raw and continue without reporting any error. |
| 693 // A static warning should have been reported. | 687 // A static warning should have been reported. |
| 694 arguments = TypeArguments::null(); | 688 arguments = TypeArguments::null(); |
| 695 type.set_arguments(arguments); | 689 type.set_arguments(arguments); |
| 696 } | 690 } |
| 697 | 691 |
| 698 // Mark the type as being finalized in order to detect self reference and | 692 // Mark the type as being finalized in order to detect self reference and |
| 699 // postpone bound checking until after all types in the graph of | 693 // postpone bound checking until after all types in the graph of |
| 700 // mutually recursive types are finalized. | 694 // mutually recursive types are finalized. |
| 701 type.SetIsBeingFinalized(); | 695 type.SetIsBeingFinalized(); |
| 702 pending_types->Add(type); | 696 pending_types->Add(type); |
| 703 | 697 |
| 704 // The full type argument vector consists of the type arguments of the | 698 // The full type argument vector consists of the type arguments of the |
| 705 // super types of type_class, which are initialized from the parsed | 699 // super types of type_class, which are initialized from the parsed |
| 706 // type arguments, followed by the parsed type arguments. | 700 // type arguments, followed by the parsed type arguments. |
| 707 TypeArguments& full_arguments = TypeArguments::Handle(Z); | 701 TypeArguments& full_arguments = TypeArguments::Handle(zone); |
| 708 if (FLAG_reify && (num_type_arguments > 0)) { | 702 if (FLAG_reify && (num_type_arguments > 0)) { |
| 709 // If no type arguments were parsed and if the super types do not prepend | 703 // If no type arguments were parsed and if the super types do not prepend |
| 710 // type arguments to the vector, we can leave the vector as null. | 704 // type arguments to the vector, we can leave the vector as null. |
| 711 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 705 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 712 full_arguments = TypeArguments::New(num_type_arguments); | 706 full_arguments = TypeArguments::New(num_type_arguments); |
| 713 // Copy the parsed type arguments at the correct offset in the full type | 707 // Copy the parsed type arguments at the correct offset in the full type |
| 714 // argument vector. | 708 // argument vector. |
| 715 const intptr_t offset = num_type_arguments - num_type_parameters; | 709 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 716 AbstractType& type_arg = | 710 AbstractType& type_arg = |
| 717 AbstractType::Handle(Z, Type::DynamicType()); | 711 AbstractType::Handle(zone, Type::DynamicType()); |
| 718 // Leave the temporary type arguments at indices [0..offset[ as null. | 712 // Leave the temporary type arguments at indices [0..offset[ as null. |
| 719 for (intptr_t i = 0; i < num_type_parameters; i++) { | 713 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 720 // If no type parameters were provided, a raw type is desired, so we | 714 // If no type parameters were provided, a raw type is desired, so we |
| 721 // create a vector of dynamic. | 715 // create a vector of dynamic. |
| 722 if (!arguments.IsNull()) { | 716 if (!arguments.IsNull()) { |
| 723 type_arg = arguments.TypeAt(i); | 717 type_arg = arguments.TypeAt(i); |
| 724 // The parsed type_arg may or may not be finalized. | 718 // The parsed type_arg may or may not be finalized. |
| 725 } | 719 } |
| 726 full_arguments.SetTypeAt(offset + i, type_arg); | 720 full_arguments.SetTypeAt(offset + i, type_arg); |
| 727 } | 721 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 739 ASSERT(!type_arg.IsBeingFinalized()); | 733 ASSERT(!type_arg.IsBeingFinalized()); |
| 740 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); | 734 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
| 741 if (type_arg.IsMalformed()) { | 735 if (type_arg.IsMalformed()) { |
| 742 // Malformed type arguments are mapped to dynamic. | 736 // Malformed type arguments are mapped to dynamic. |
| 743 type_arg = Type::DynamicType(); | 737 type_arg = Type::DynamicType(); |
| 744 } | 738 } |
| 745 full_arguments.SetTypeAt(offset + i, type_arg); | 739 full_arguments.SetTypeAt(offset + i, type_arg); |
| 746 } | 740 } |
| 747 } | 741 } |
| 748 if (offset > 0) { | 742 if (offset > 0) { |
| 749 TrailPtr instantiation_trail = new Trail(Z, 4); | 743 TrailPtr instantiation_trail = new Trail(zone, 4); |
| 750 Error& bound_error = Error::Handle(Z); | 744 Error& bound_error = Error::Handle(zone); |
| 751 FinalizeTypeArguments(type_class, full_arguments, offset, | 745 FinalizeTypeArguments(type_class, full_arguments, offset, |
| 752 &bound_error, pending_types, instantiation_trail); | 746 &bound_error, pending_types, instantiation_trail); |
| 753 } | 747 } |
| 754 if (full_arguments.IsRaw(0, num_type_arguments)) { | 748 if (full_arguments.IsRaw(0, num_type_arguments)) { |
| 755 // The parameterized_type is raw. Set its argument vector to null, which | 749 // The parameterized_type is raw. Set its argument vector to null, which |
| 756 // is more efficient in type tests. | 750 // is more efficient in type tests. |
| 757 full_arguments = TypeArguments::null(); | 751 full_arguments = TypeArguments::null(); |
| 758 } | 752 } |
| 759 type.set_arguments(full_arguments); | 753 type.set_arguments(full_arguments); |
| 760 } else { | 754 } else { |
| 761 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 755 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
| 762 } | 756 } |
| 763 } | 757 } |
| 764 | 758 |
| 765 // Self referencing types may get finalized indirectly. | 759 // Self referencing types may get finalized indirectly. |
| 766 if (!type.IsFinalized()) { | 760 if (!type.IsFinalized()) { |
| 767 ASSERT(full_arguments.IsNull() || | 761 ASSERT(full_arguments.IsNull() || |
| 768 !full_arguments.IsRaw(0, num_type_arguments)); | 762 !full_arguments.IsRaw(0, num_type_arguments)); |
| 769 if (FLAG_trace_type_finalization) { | 763 if (FLAG_trace_type_finalization) { |
| 770 THR_Print("Marking type '%s' as finalized for class '%s'\n", | 764 THR_Print("Marking type '%s' as finalized for class '%s'\n", |
| 771 String::Handle(Z, type.Name()).ToCString(), | 765 String::Handle(zone, type.Name()).ToCString(), |
| 772 String::Handle(Z, cls.Name()).ToCString()); | 766 String::Handle(zone, cls.Name()).ToCString()); |
| 773 } | 767 } |
| 774 // Mark the type as finalized. | 768 // Mark the type as finalized. |
| 775 type.SetIsFinalized(); | 769 type.SetIsFinalized(); |
| 776 // Do not yet remove the type from the pending_types array. | 770 // Do not yet remove the type from the pending_types array. |
| 777 } | 771 } |
| 778 return full_arguments.IsNull() ? 0 : full_arguments.Length(); | 772 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
| 779 } | 773 } |
| 780 | 774 |
| 781 | 775 |
| 782 // Finalize the type argument vector 'arguments' of the type defined by the | 776 // Finalize the type argument vector 'arguments' of the type defined by the |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 TypeArguments& super_type_args = TypeArguments::Handle( | 833 TypeArguments& super_type_args = TypeArguments::Handle( |
| 840 super_type.arguments()); | 834 super_type.arguments()); |
| 841 // Offset of super type's type parameters in cls' type argument vector. | 835 // Offset of super type's type parameters in cls' type argument vector. |
| 842 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 836 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
| 843 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 837 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
| 844 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 838 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
| 845 if (!super_type_args.IsNull()) { | 839 if (!super_type_args.IsNull()) { |
| 846 super_type_arg = super_type_args.TypeAt(i); | 840 super_type_arg = super_type_args.TypeAt(i); |
| 847 if (!super_type_arg.IsTypeRef()) { | 841 if (!super_type_arg.IsTypeRef()) { |
| 848 if (super_type_arg.IsBeingFinalized()) { | 842 if (super_type_arg.IsBeingFinalized()) { |
| 849 ASSERT(super_type_arg.IsType() || super_type_arg.IsFunctionType()); | 843 ASSERT(super_type_arg.IsType()); |
| 850 CheckRecursiveType(cls, super_type_arg, pending_types); | 844 CheckRecursiveType(cls, super_type_arg, pending_types); |
| 851 if (FLAG_trace_type_finalization) { | 845 if (FLAG_trace_type_finalization) { |
| 852 THR_Print("Creating TypeRef '%s': '%s'\n", | 846 THR_Print("Creating TypeRef '%s': '%s'\n", |
| 853 String::Handle(super_type_arg.Name()).ToCString(), | 847 String::Handle(super_type_arg.Name()).ToCString(), |
| 854 super_type_arg.ToCString()); | 848 super_type_arg.ToCString()); |
| 855 } | 849 } |
| 856 super_type_arg = TypeRef::New(super_type_arg); | 850 super_type_arg = TypeRef::New(super_type_arg); |
| 857 super_type_args.SetTypeAt(i, super_type_arg); | 851 super_type_args.SetTypeAt(i, super_type_arg); |
| 858 } else { | 852 } else { |
| 859 if (!super_type_arg.IsFinalized()) { | 853 if (!super_type_arg.IsFinalized()) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 if (error.IsNull() && | 992 if (error.IsNull() && |
| 999 !(type_arg.Equals(type_param) && | 993 !(type_arg.Equals(type_param) && |
| 1000 instantiated_bound.Equals(declared_bound))) { | 994 instantiated_bound.Equals(declared_bound))) { |
| 1001 // If type_arg is a type parameter, its declared bound may not be | 995 // If type_arg is a type parameter, its declared bound may not be |
| 1002 // resolved yet. | 996 // resolved yet. |
| 1003 if (type_arg.IsTypeParameter()) { | 997 if (type_arg.IsTypeParameter()) { |
| 1004 const Class& type_arg_cls = Class::Handle( | 998 const Class& type_arg_cls = Class::Handle( |
| 1005 TypeParameter::Cast(type_arg).parameterized_class()); | 999 TypeParameter::Cast(type_arg).parameterized_class()); |
| 1006 AbstractType& bound = AbstractType::Handle( | 1000 AbstractType& bound = AbstractType::Handle( |
| 1007 TypeParameter::Cast(type_arg).bound()); | 1001 TypeParameter::Cast(type_arg).bound()); |
| 1008 bound = ResolveType(type_arg_cls, bound); | 1002 ResolveType(type_arg_cls, bound); |
| 1009 TypeParameter::Cast(type_arg).set_bound(bound); | |
| 1010 } | 1003 } |
| 1011 // This may be called only if type needs to be finalized, therefore | 1004 // This may be called only if type needs to be finalized, therefore |
| 1012 // seems OK to allocate finalized types in old space. | 1005 // seems OK to allocate finalized types in old space. |
| 1013 if (!type_param.CheckBound(type_arg, instantiated_bound, | 1006 if (!type_param.CheckBound(type_arg, instantiated_bound, |
| 1014 &error, NULL, Heap::kOld) && | 1007 &error, NULL, Heap::kOld) && |
| 1015 error.IsNull()) { | 1008 error.IsNull()) { |
| 1016 // The bound cannot be checked at compile time; postpone to run time. | 1009 // The bound cannot be checked at compile time; postpone to run time. |
| 1017 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1010 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
| 1018 arguments.SetTypeAt(offset + i, type_arg); | 1011 arguments.SetTypeAt(offset + i, type_arg); |
| 1019 } | 1012 } |
| 1020 } | 1013 } |
| 1021 if (!error.IsNull() && bound_error->IsNull()) { | 1014 if (!error.IsNull() && bound_error->IsNull()) { |
| 1022 *bound_error = error.raw(); | 1015 *bound_error = error.raw(); |
| 1023 } | 1016 } |
| 1024 } | 1017 } |
| 1025 } | 1018 } |
| 1026 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1019 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 1027 if (!super_type.IsNull()) { | 1020 if (!super_type.IsNull()) { |
| 1028 const Class& super_class = Class::Handle(super_type.type_class()); | 1021 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1029 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 1022 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
| 1030 } | 1023 } |
| 1031 } | 1024 } |
| 1032 | 1025 |
| 1033 | 1026 |
| 1034 void ClassFinalizer::CheckTypeBounds(const Class& cls, | 1027 void ClassFinalizer::CheckTypeBounds(const Class& cls, |
| 1035 const AbstractType& type) { | 1028 const AbstractType& type) { |
| 1036 Zone* Z = Thread::Current()->zone(); | 1029 Zone* zone = Thread::Current()->zone(); |
| 1037 ASSERT(type.IsType() || type.IsFunctionType()); | 1030 ASSERT(type.IsType()); |
| 1038 ASSERT(type.IsFinalized()); | 1031 ASSERT(type.IsFinalized()); |
| 1039 ASSERT(!type.IsCanonical()); | 1032 ASSERT(!type.IsCanonical()); |
| 1040 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); | 1033 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); |
| 1041 if (arguments.IsNull()) { | 1034 if (arguments.IsNull()) { |
| 1042 return; | 1035 return; |
| 1043 } | 1036 } |
| 1044 if (FLAG_trace_type_finalization) { | 1037 if (FLAG_trace_type_finalization) { |
| 1045 THR_Print("Checking bounds of type '%s' for class '%s'\n", | 1038 THR_Print("Checking bounds of type '%s' for class '%s'\n", |
| 1046 String::Handle(Z, type.Name()).ToCString(), | 1039 String::Handle(zone, type.Name()).ToCString(), |
| 1047 String::Handle(Z, cls.Name()).ToCString()); | 1040 String::Handle(zone, cls.Name()).ToCString()); |
| 1048 } | 1041 } |
| 1049 const Class& type_class = Class::Handle(Z, type.type_class()); | 1042 const Class& type_class = Class::Handle(zone, type.type_class()); |
| 1050 Error& bound_error = Error::Handle(Z); | 1043 Error& bound_error = Error::Handle(zone); |
| 1051 CheckTypeArgumentBounds(type_class, arguments, &bound_error); | 1044 CheckTypeArgumentBounds(type_class, arguments, &bound_error); |
| 1052 // CheckTypeArgumentBounds may have indirectly canonicalized this type. | 1045 // CheckTypeArgumentBounds may have indirectly canonicalized this type. |
| 1053 if (!type.IsCanonical()) { | 1046 if (!type.IsCanonical()) { |
| 1054 type.set_arguments(arguments); | 1047 type.set_arguments(arguments); |
| 1055 // If a bound error occurred, mark the type as malbounded. | 1048 // If a bound error occurred, mark the type as malbounded. |
| 1056 // The bound error will be ignored in production mode. | 1049 // The bound error will be ignored in production mode. |
| 1057 if (!bound_error.IsNull()) { | 1050 if (!bound_error.IsNull()) { |
| 1058 // No compile-time error during finalization. | 1051 // No compile-time error during finalization. |
| 1059 const String& type_name = String::Handle(Z, type.UserVisibleName()); | 1052 const String& type_name = String::Handle(zone, type.UserVisibleName()); |
| 1060 FinalizeMalboundedType(bound_error, | 1053 FinalizeMalboundedType(bound_error, |
| 1061 Script::Handle(Z, cls.script()), | 1054 Script::Handle(zone, cls.script()), |
| 1062 type, | 1055 type, |
| 1063 "type '%s' has an out of bound type argument", | 1056 "type '%s' has an out of bound type argument", |
| 1064 type_name.ToCString()); | 1057 type_name.ToCString()); |
| 1065 if (FLAG_trace_type_finalization) { | 1058 if (FLAG_trace_type_finalization) { |
| 1066 THR_Print("Marking type '%s' as malbounded: %s\n", | 1059 THR_Print("Marking type '%s' as malbounded: %s\n", |
| 1067 String::Handle(Z, type.Name()).ToCString(), | 1060 String::Handle(zone, type.Name()).ToCString(), |
| 1068 bound_error.ToErrorCString()); | 1061 bound_error.ToErrorCString()); |
| 1069 } | 1062 } |
| 1070 } | 1063 } |
| 1071 } | 1064 } |
| 1072 if (FLAG_trace_type_finalization) { | 1065 if (FLAG_trace_type_finalization) { |
| 1073 THR_Print("Done checking bounds of type '%s': %s\n", | 1066 THR_Print("Done checking bounds of type '%s': %s\n", |
| 1074 String::Handle(Z, type.Name()).ToCString(), | 1067 String::Handle(zone, type.Name()).ToCString(), |
| 1075 type.ToCString()); | 1068 type.ToCString()); |
| 1076 } | 1069 } |
| 1077 } | 1070 } |
| 1078 | 1071 |
| 1079 | 1072 |
| 1080 RawAbstractType* ClassFinalizer::FinalizeType( | 1073 RawAbstractType* ClassFinalizer::FinalizeType( |
| 1081 const Class& cls, | 1074 const Class& cls, |
| 1082 const AbstractType& type, | 1075 const AbstractType& type, |
| 1083 FinalizationKind finalization, | 1076 FinalizationKind finalization, |
| 1084 PendingTypes* pending_types) { | 1077 PendingTypes* pending_types) { |
| 1085 // Only the 'root' type of the graph can be canonicalized, after all depending | 1078 // Only the 'root' type of the graph can be canonicalized, after all depending |
| 1086 // types have been bound checked. | 1079 // types have been bound checked. |
| 1087 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 1080 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
| 1088 if (type.IsFinalized()) { | 1081 if (type.IsFinalized()) { |
| 1089 // Ensure type is canonical if canonicalization is requested, unless type is | 1082 // Ensure type is canonical if canonicalization is requested, unless type is |
| 1090 // malformed. | 1083 // malformed. |
| 1091 if ((finalization >= kCanonicalize) && | 1084 if ((finalization >= kCanonicalize) && |
| 1092 !type.IsMalformed() && | 1085 !type.IsMalformed() && |
| 1093 !type.IsCanonical() && | 1086 !type.IsCanonical() && |
| 1094 (type.IsType() || type.IsFunctionType())) { | 1087 type.IsType()) { |
| 1095 CheckTypeBounds(cls, type); | 1088 CheckTypeBounds(cls, type); |
| 1096 return type.Canonicalize(); | 1089 return type.Canonicalize(); |
| 1097 } | 1090 } |
| 1098 return type.raw(); | 1091 return type.raw(); |
| 1099 } | 1092 } |
| 1100 ASSERT(finalization >= kFinalize); | 1093 ASSERT(finalization >= kFinalize); |
| 1101 | 1094 |
| 1102 if (type.IsTypeRef()) { | 1095 if (type.IsTypeRef()) { |
| 1103 // The referenced type will be finalized later by the code that set the | 1096 // The referenced type will be finalized later by the code that set the |
| 1104 // is_being_finalized mark bit. | 1097 // is_being_finalized mark bit. |
| 1105 return type.raw(); | 1098 return type.raw(); |
| 1106 } | 1099 } |
| 1107 | 1100 |
| 1108 // Recursive types must be processed in FinalizeTypeArguments() and cannot be | 1101 // Recursive types must be processed in FinalizeTypeArguments() and cannot be |
| 1109 // encountered here. | 1102 // encountered here. |
| 1110 ASSERT(!type.IsBeingFinalized()); | 1103 ASSERT(!type.IsBeingFinalized()); |
| 1111 | 1104 |
| 1112 Zone* Z = Thread::Current()->zone(); | 1105 Zone* zone = Thread::Current()->zone(); |
| 1113 const AbstractType& resolved_type = | 1106 ResolveType(cls, type); |
| 1114 AbstractType::Handle(Z, ResolveType(cls, type)); | |
| 1115 // A malformed type gets mapped to a finalized type. | 1107 // A malformed type gets mapped to a finalized type. |
| 1116 if (resolved_type.IsMalformed()) { | 1108 if (type.IsMalformed()) { |
| 1117 ASSERT(resolved_type.IsFinalized()); | 1109 ASSERT(type.IsFinalized()); |
| 1118 return resolved_type.raw(); | 1110 return type.raw(); |
| 1119 } | 1111 } |
| 1120 | 1112 |
| 1121 if (FLAG_trace_type_finalization) { | 1113 if (FLAG_trace_type_finalization) { |
| 1122 THR_Print("Finalizing type '%s' for class '%s'\n", | 1114 THR_Print("Finalizing type '%s' for class '%s'\n", |
| 1123 String::Handle(Z, resolved_type.Name()).ToCString(), | 1115 String::Handle(zone, type.Name()).ToCString(), |
| 1124 String::Handle(Z, cls.Name()).ToCString()); | 1116 String::Handle(zone, cls.Name()).ToCString()); |
| 1125 } | 1117 } |
| 1126 | 1118 |
| 1127 if (resolved_type.IsTypeParameter()) { | 1119 if (type.IsTypeParameter()) { |
| 1128 const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type); | 1120 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
| 1129 const Class& parameterized_class = | 1121 const Class& parameterized_class = |
| 1130 Class::Handle(Z, type_parameter.parameterized_class()); | 1122 Class::Handle(zone, type_parameter.parameterized_class()); |
| 1131 ASSERT(!parameterized_class.IsNull()); | 1123 ASSERT(!parameterized_class.IsNull()); |
| 1132 // The index must reflect the position of this type parameter in the type | 1124 // The index must reflect the position of this type parameter in the type |
| 1133 // arguments vector of its parameterized class. The offset to add is the | 1125 // arguments vector of its parameterized class. The offset to add is the |
| 1134 // number of type arguments in the super type, which is equal to the | 1126 // number of type arguments in the super type, which is equal to the |
| 1135 // difference in number of type arguments and type parameters of the | 1127 // difference in number of type arguments and type parameters of the |
| 1136 // parameterized class. | 1128 // parameterized class. |
| 1137 const intptr_t offset = parameterized_class.NumTypeArguments() - | 1129 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 1138 parameterized_class.NumTypeParameters(); | 1130 parameterized_class.NumTypeParameters(); |
| 1139 // Calling NumTypeParameters() may finalize this type parameter if it | 1131 // Calling NumTypeParameters() may finalize this type parameter if it |
| 1140 // belongs to a mixin application class. | 1132 // belongs to a mixin application class. |
| 1141 if (!type_parameter.IsFinalized()) { | 1133 if (!type_parameter.IsFinalized()) { |
| 1142 type_parameter.set_index(type_parameter.index() + offset); | 1134 type_parameter.set_index(type_parameter.index() + offset); |
| 1143 type_parameter.SetIsFinalized(); | 1135 type_parameter.SetIsFinalized(); |
| 1144 } else { | 1136 } else { |
| 1145 ASSERT(cls.IsMixinApplication()); | 1137 ASSERT(cls.IsMixinApplication()); |
| 1146 } | 1138 } |
| 1147 | 1139 |
| 1148 if (FLAG_trace_type_finalization) { | 1140 if (FLAG_trace_type_finalization) { |
| 1149 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 1141 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
| 1150 String::Handle(Z, type_parameter.name()).ToCString(), | 1142 String::Handle(zone, type_parameter.name()).ToCString(), |
| 1151 type_parameter.index()); | 1143 type_parameter.index()); |
| 1152 } | 1144 } |
| 1153 | 1145 |
| 1154 // We do not canonicalize type parameters. | 1146 // We do not canonicalize type parameters. |
| 1155 return type_parameter.raw(); | 1147 return type_parameter.raw(); |
| 1156 } | 1148 } |
| 1157 | 1149 |
| 1158 // At this point, we can only have a Type or a FunctionType. | 1150 // At this point, we can only have a Type. |
| 1159 ASSERT(resolved_type.IsType() || resolved_type.IsFunctionType()); | 1151 ASSERT(type.IsType()); |
| 1160 | 1152 |
| 1161 // This type is the root type of the type graph if no pending types queue is | 1153 // This type is the root type of the type graph if no pending types queue is |
| 1162 // allocated yet. | 1154 // allocated yet. |
| 1163 const bool is_root_type = (pending_types == NULL); | 1155 const bool is_root_type = (pending_types == NULL); |
| 1164 if (is_root_type) { | 1156 if (is_root_type) { |
| 1165 pending_types = new PendingTypes(Z, 4); | 1157 pending_types = new PendingTypes(zone, 4); |
| 1166 } | 1158 } |
| 1167 | 1159 |
| 1168 const intptr_t num_expanded_type_arguments = | 1160 const intptr_t num_expanded_type_arguments = |
| 1169 ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types); | 1161 ExpandAndFinalizeTypeArguments(cls, type, pending_types); |
| 1170 | 1162 |
| 1171 // If we are done finalizing a graph of mutually recursive types, check their | 1163 // If we are done finalizing a graph of mutually recursive types, check their |
| 1172 // bounds. | 1164 // bounds. |
| 1173 if (is_root_type) { | 1165 if (is_root_type) { |
| 1174 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { | 1166 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
| 1175 const AbstractType& type = pending_types->At(i); | 1167 const AbstractType& type = pending_types->At(i); |
| 1176 if (!type.IsMalformed() && !type.IsCanonical()) { | 1168 if (!type.IsMalformed() && !type.IsCanonical()) { |
| 1177 CheckTypeBounds(cls, type); | 1169 CheckTypeBounds(cls, type); |
| 1178 } | 1170 } |
| 1179 } | 1171 } |
| 1180 } | 1172 } |
| 1181 | 1173 |
| 1182 // If the type is a FunctionType, we also need to finalize the types in its | 1174 // If the type is a function type, we also need to finalize the types in its |
| 1183 // signature, i.e. finalize the result type and parameter types of the | 1175 // signature, i.e. finalize the result type and parameter types of the |
| 1184 // signature function of this function type. | 1176 // signature function of this function type. |
| 1185 // We do this after marking this type as finalized in order to allow a | 1177 // We do this after marking this type as finalized in order to allow a |
| 1186 // function type to refer to itself via its parameter types and result type. | 1178 // function type to refer to itself via its parameter types and result type. |
| 1187 // Note that we do not instantiate these types according to the type | 1179 // Note that we do not instantiate these types according to the type |
| 1188 // arguments. This will happen on demand when executing a type test. | 1180 // arguments. This will happen on demand when executing a type test. |
| 1189 if (resolved_type.IsFunctionType()) { | 1181 if (type.IsFunctionType()) { |
| 1190 const Function& signature = | 1182 const Function& signature = |
| 1191 Function::Handle(Z, FunctionType::Cast(resolved_type).signature()); | 1183 Function::Handle(zone, Type::Cast(type).signature()); |
| 1192 const Class& scope_class = | 1184 const Class& scope_class = |
| 1193 Class::Handle(Z, FunctionType::Cast(resolved_type).scope_class()); | 1185 Class::Handle(zone, Type::Cast(type).type_class()); |
| 1194 if (scope_class.IsTypedefClass()) { | 1186 if (scope_class.IsTypedefClass()) { |
| 1195 FinalizeSignature(scope_class, signature); | 1187 FinalizeSignature(scope_class, signature); |
| 1196 } else { | 1188 } else { |
| 1197 FinalizeSignature(cls, signature); | 1189 FinalizeSignature(cls, signature); |
| 1198 } | 1190 } |
| 1199 } | 1191 } |
| 1200 | 1192 |
| 1201 if (FLAG_trace_type_finalization) { | 1193 if (FLAG_trace_type_finalization) { |
| 1202 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1194 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
| 1203 String::Handle(Z, resolved_type.Name()).ToCString(), | 1195 String::Handle(zone, type.Name()).ToCString(), |
| 1204 num_expanded_type_arguments, | 1196 num_expanded_type_arguments, |
| 1205 resolved_type.ToCString()); | 1197 type.ToCString()); |
| 1206 } | 1198 } |
| 1207 | 1199 |
| 1208 if (finalization >= kCanonicalize) { | 1200 if (finalization >= kCanonicalize) { |
| 1209 if (FLAG_trace_type_finalization) { | 1201 if (FLAG_trace_type_finalization) { |
| 1210 THR_Print("Canonicalizing type '%s'\n", | 1202 THR_Print("Canonicalizing type '%s'\n", |
| 1211 String::Handle(Z, resolved_type.Name()).ToCString()); | 1203 String::Handle(zone, type.Name()).ToCString()); |
| 1212 AbstractType& canonical_type = | 1204 AbstractType& canonical_type = |
| 1213 AbstractType::Handle(Z, resolved_type.Canonicalize()); | 1205 AbstractType::Handle(zone, type.Canonicalize()); |
| 1214 THR_Print("Done canonicalizing type '%s'\n", | 1206 THR_Print("Done canonicalizing type '%s'\n", |
| 1215 String::Handle(Z, canonical_type.Name()).ToCString()); | 1207 String::Handle(zone, canonical_type.Name()).ToCString()); |
| 1216 return canonical_type.raw(); | 1208 return canonical_type.raw(); |
| 1217 } | 1209 } |
| 1218 return resolved_type.Canonicalize(); | 1210 return type.Canonicalize(); |
| 1219 } else { | 1211 } else { |
| 1220 return resolved_type.raw(); | 1212 return type.raw(); |
| 1221 } | 1213 } |
| 1222 } | 1214 } |
| 1223 | 1215 |
| 1224 | 1216 |
| 1225 void ClassFinalizer::ResolveSignature(const Class& cls, | 1217 void ClassFinalizer::ResolveSignature(const Class& cls, |
| 1226 const Function& function) { | 1218 const Function& function) { |
| 1227 // Resolve result type. | 1219 // Resolve result type. |
| 1228 AbstractType& type = AbstractType::Handle(function.result_type()); | 1220 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 1229 // It is not a compile time error if this name does not resolve to a class or | 1221 // It is not a compile time error if this name does not resolve to a class or |
| 1230 // interface. | 1222 // interface. |
| 1231 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); | 1223 ResolveType(cls, type); |
| 1232 if (resolved_type.raw() != type.raw()) { | |
| 1233 function.set_result_type(resolved_type); | |
| 1234 } | |
| 1235 // Resolve formal parameter types. | 1224 // Resolve formal parameter types. |
| 1236 const intptr_t num_parameters = function.NumParameters(); | 1225 const intptr_t num_parameters = function.NumParameters(); |
| 1237 for (intptr_t i = 0; i < num_parameters; i++) { | 1226 for (intptr_t i = 0; i < num_parameters; i++) { |
| 1238 type = function.ParameterTypeAt(i); | 1227 type = function.ParameterTypeAt(i); |
| 1239 resolved_type = ResolveType(cls, type); | 1228 ResolveType(cls, type); |
| 1240 if (resolved_type.raw() != type.raw()) { | |
| 1241 function.SetParameterTypeAt(i, resolved_type); | |
| 1242 } | |
| 1243 } | 1229 } |
| 1244 } | 1230 } |
| 1245 | 1231 |
| 1246 | 1232 |
| 1247 void ClassFinalizer::FinalizeSignature(const Class& cls, | 1233 void ClassFinalizer::FinalizeSignature(const Class& cls, |
| 1248 const Function& function) { | 1234 const Function& function) { |
| 1249 // Finalize result type. | 1235 // Finalize result type. |
| 1250 AbstractType& type = AbstractType::Handle(function.result_type()); | 1236 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 1251 // It is not a compile time error if this name does not resolve to a class or | 1237 // It is not a compile time error if this name does not resolve to a class or |
| 1252 // interface. | 1238 // interface. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 AbstractType& bound = AbstractType::Handle(); | 1309 AbstractType& bound = AbstractType::Handle(); |
| 1324 const TypeArguments& type_params = | 1310 const TypeArguments& type_params = |
| 1325 TypeArguments::Handle(cls.type_parameters()); | 1311 TypeArguments::Handle(cls.type_parameters()); |
| 1326 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1312 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
| 1327 (type_params.Length() == num_type_params)); | 1313 (type_params.Length() == num_type_params)); |
| 1328 // In a first pass, resolve all bounds. This guarantees that finalization | 1314 // In a first pass, resolve all bounds. This guarantees that finalization |
| 1329 // of mutually referencing bounds will not encounter an unresolved bound. | 1315 // of mutually referencing bounds will not encounter an unresolved bound. |
| 1330 for (intptr_t i = 0; i < num_type_params; i++) { | 1316 for (intptr_t i = 0; i < num_type_params; i++) { |
| 1331 type_param ^= type_params.TypeAt(i); | 1317 type_param ^= type_params.TypeAt(i); |
| 1332 bound = type_param.bound(); | 1318 bound = type_param.bound(); |
| 1333 bound = ResolveType(cls, bound); | 1319 ResolveType(cls, bound); |
| 1334 type_param.set_bound(bound); | |
| 1335 } | 1320 } |
| 1336 } | 1321 } |
| 1337 | 1322 |
| 1338 | 1323 |
| 1339 // Finalize the upper bounds of the type parameters of class cls. | 1324 // Finalize the upper bounds of the type parameters of class cls. |
| 1340 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, | 1325 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, |
| 1341 FinalizationKind finalization) { | 1326 FinalizationKind finalization) { |
| 1342 const intptr_t num_type_params = cls.NumTypeParameters(); | 1327 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 1343 TypeParameter& type_param = TypeParameter::Handle(); | 1328 TypeParameter& type_param = TypeParameter::Handle(); |
| 1344 AbstractType& bound = AbstractType::Handle(); | 1329 AbstractType& bound = AbstractType::Handle(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1375 // conflict with an accessible static setter 'v=' of a super class). | 1360 // conflict with an accessible static setter 'v=' of a super class). |
| 1376 // The compile-time errors we report are: | 1361 // The compile-time errors we report are: |
| 1377 // - a static member 'v' conflicting with an inherited instance member 'v'. | 1362 // - a static member 'v' conflicting with an inherited instance member 'v'. |
| 1378 // - a static setter 'v=' conflicting with an inherited instance setter 'v='. | 1363 // - a static setter 'v=' conflicting with an inherited instance setter 'v='. |
| 1379 // - an instance method conflicting with an inherited instance field or | 1364 // - an instance method conflicting with an inherited instance field or |
| 1380 // instance getter. | 1365 // instance getter. |
| 1381 // - an instance field or instance getter conflicting with an inherited | 1366 // - an instance field or instance getter conflicting with an inherited |
| 1382 // instance method. | 1367 // instance method. |
| 1383 | 1368 |
| 1384 // Resolve type of fields and check for conflicts in super classes. | 1369 // Resolve type of fields and check for conflicts in super classes. |
| 1385 Zone* Z = Thread::Current()->zone(); | 1370 Zone* zone = Thread::Current()->zone(); |
| 1386 Array& array = Array::Handle(Z, cls.fields()); | 1371 Array& array = Array::Handle(zone, cls.fields()); |
| 1387 Field& field = Field::Handle(Z); | 1372 Field& field = Field::Handle(zone); |
| 1388 AbstractType& type = AbstractType::Handle(Z); | 1373 AbstractType& type = AbstractType::Handle(zone); |
| 1389 String& name = String::Handle(Z); | 1374 String& name = String::Handle(zone); |
| 1390 String& getter_name = String::Handle(Z); | 1375 String& getter_name = String::Handle(zone); |
| 1391 String& setter_name = String::Handle(Z); | 1376 String& setter_name = String::Handle(zone); |
| 1392 Class& super_class = Class::Handle(Z); | 1377 Class& super_class = Class::Handle(zone); |
| 1393 const intptr_t num_fields = array.Length(); | 1378 const intptr_t num_fields = array.Length(); |
| 1394 for (intptr_t i = 0; i < num_fields; i++) { | 1379 for (intptr_t i = 0; i < num_fields; i++) { |
| 1395 field ^= array.At(i); | 1380 field ^= array.At(i); |
| 1396 type = field.type(); | 1381 type = field.type(); |
| 1397 type = FinalizeType(cls, type, kCanonicalize); | 1382 type = FinalizeType(cls, type, kCanonicalize); |
| 1398 field.SetFieldType(type); | 1383 field.SetFieldType(type); |
| 1399 name = field.name(); | 1384 name = field.name(); |
| 1400 if (field.is_static()) { | 1385 if (field.is_static()) { |
| 1401 getter_name = Field::GetterSymbol(name); | 1386 getter_name = Field::GetterSymbol(name); |
| 1402 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1387 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
| 1403 if (!super_class.IsNull()) { | 1388 if (!super_class.IsNull()) { |
| 1404 const String& class_name = String::Handle(Z, cls.Name()); | 1389 const String& class_name = String::Handle(zone, cls.Name()); |
| 1405 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1390 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1406 ReportError(cls, field.token_pos(), | 1391 ReportError(cls, field.token_pos(), |
| 1407 "static field '%s' of class '%s' conflicts with " | 1392 "static field '%s' of class '%s' conflicts with " |
| 1408 "instance member '%s' of super class '%s'", | 1393 "instance member '%s' of super class '%s'", |
| 1409 name.ToCString(), | 1394 name.ToCString(), |
| 1410 class_name.ToCString(), | 1395 class_name.ToCString(), |
| 1411 name.ToCString(), | 1396 name.ToCString(), |
| 1412 super_class_name.ToCString()); | 1397 super_cls_name.ToCString()); |
| 1413 } | 1398 } |
| 1414 // An implicit setter is not generated for a static field, therefore, we | 1399 // An implicit setter is not generated for a static field, therefore, we |
| 1415 // cannot rely on the code below handling the static setter case to report | 1400 // cannot rely on the code below handling the static setter case to report |
| 1416 // a conflict with an instance setter. So we check explicitly here. | 1401 // a conflict with an instance setter. So we check explicitly here. |
| 1417 setter_name = Field::SetterSymbol(name); | 1402 setter_name = Field::SetterSymbol(name); |
| 1418 super_class = FindSuperOwnerOfFunction(cls, setter_name); | 1403 super_class = FindSuperOwnerOfFunction(cls, setter_name); |
| 1419 if (!super_class.IsNull()) { | 1404 if (!super_class.IsNull()) { |
| 1420 const String& class_name = String::Handle(Z, cls.Name()); | 1405 const String& class_name = String::Handle(zone, cls.Name()); |
| 1421 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1406 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1422 ReportError(cls, field.token_pos(), | 1407 ReportError(cls, field.token_pos(), |
| 1423 "static field '%s' of class '%s' conflicts with " | 1408 "static field '%s' of class '%s' conflicts with " |
| 1424 "instance setter '%s=' of super class '%s'", | 1409 "instance setter '%s=' of super class '%s'", |
| 1425 name.ToCString(), | 1410 name.ToCString(), |
| 1426 class_name.ToCString(), | 1411 class_name.ToCString(), |
| 1427 name.ToCString(), | 1412 name.ToCString(), |
| 1428 super_class_name.ToCString()); | 1413 super_cls_name.ToCString()); |
| 1429 } | 1414 } |
| 1430 | 1415 |
| 1431 } else { | 1416 } else { |
| 1432 // Instance field. Check whether the field overrides a method | 1417 // Instance field. Check whether the field overrides a method |
| 1433 // (but not getter). | 1418 // (but not getter). |
| 1434 super_class = FindSuperOwnerOfFunction(cls, name); | 1419 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1435 if (!super_class.IsNull()) { | 1420 if (!super_class.IsNull()) { |
| 1436 const String& class_name = String::Handle(Z, cls.Name()); | 1421 const String& class_name = String::Handle(zone, cls.Name()); |
| 1437 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1422 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1438 ReportError(cls, field.token_pos(), | 1423 ReportError(cls, field.token_pos(), |
| 1439 "field '%s' of class '%s' conflicts with method '%s' " | 1424 "field '%s' of class '%s' conflicts with method '%s' " |
| 1440 "of super class '%s'", | 1425 "of super class '%s'", |
| 1441 name.ToCString(), | 1426 name.ToCString(), |
| 1442 class_name.ToCString(), | 1427 class_name.ToCString(), |
| 1443 name.ToCString(), | 1428 name.ToCString(), |
| 1444 super_class_name.ToCString()); | 1429 super_cls_name.ToCString()); |
| 1445 } | 1430 } |
| 1446 } | 1431 } |
| 1447 if (field.is_static() && | 1432 if (field.is_static() && |
| 1448 (field.StaticValue() != Object::null()) && | 1433 (field.StaticValue() != Object::null()) && |
| 1449 (field.StaticValue() != Object::sentinel().raw())) { | 1434 (field.StaticValue() != Object::sentinel().raw())) { |
| 1450 // The parser does not preset the value if the type is a type parameter or | 1435 // The parser does not preset the value if the type is a type parameter or |
| 1451 // is parameterized unless the value is null. | 1436 // is parameterized unless the value is null. |
| 1452 Error& error = Error::Handle(Z); | 1437 Error& error = Error::Handle(zone); |
| 1453 if (type.IsMalformedOrMalbounded()) { | 1438 if (type.IsMalformedOrMalbounded()) { |
| 1454 error = type.error(); | 1439 error = type.error(); |
| 1455 } else { | 1440 } else { |
| 1456 ASSERT(type.IsInstantiated()); | 1441 ASSERT(type.IsInstantiated()); |
| 1457 } | 1442 } |
| 1458 const Instance& const_value = | 1443 const Instance& const_value = |
| 1459 Instance::Handle(Z, field.StaticValue()); | 1444 Instance::Handle(zone, field.StaticValue()); |
| 1460 if (!error.IsNull() || | 1445 if (!error.IsNull() || |
| 1461 (!type.IsDynamicType() && | 1446 (!type.IsDynamicType() && |
| 1462 !const_value.IsInstanceOf(type, | 1447 !const_value.IsInstanceOf(type, |
| 1463 Object::null_type_arguments(), | 1448 Object::null_type_arguments(), |
| 1464 &error))) { | 1449 &error))) { |
| 1465 if (Isolate::Current()->error_on_bad_type()) { | 1450 if (Isolate::Current()->error_on_bad_type()) { |
| 1466 const AbstractType& const_value_type = AbstractType::Handle( | 1451 const AbstractType& const_value_type = AbstractType::Handle( |
| 1467 Z, const_value.GetType()); | 1452 zone, const_value.GetType()); |
| 1468 const String& const_value_type_name = String::Handle( | 1453 const String& const_value_type_name = String::Handle( |
| 1469 Z, const_value_type.UserVisibleName()); | 1454 zone, const_value_type.UserVisibleName()); |
| 1470 const String& type_name = String::Handle(Z, type.UserVisibleName()); | 1455 const String& type_name = String::Handle( |
| 1456 zone, type.UserVisibleName()); |
| 1471 ReportErrors(error, cls, field.token_pos(), | 1457 ReportErrors(error, cls, field.token_pos(), |
| 1472 "error initializing static %s field '%s': " | 1458 "error initializing static %s field '%s': " |
| 1473 "type '%s' is not a subtype of type '%s'", | 1459 "type '%s' is not a subtype of type '%s'", |
| 1474 field.is_const() ? "const" : "final", | 1460 field.is_const() ? "const" : "final", |
| 1475 name.ToCString(), | 1461 name.ToCString(), |
| 1476 const_value_type_name.ToCString(), | 1462 const_value_type_name.ToCString(), |
| 1477 type_name.ToCString()); | 1463 type_name.ToCString()); |
| 1478 } else { | 1464 } else { |
| 1479 // Do not report an error yet, even in checked mode, since the field | 1465 // Do not report an error yet, even in checked mode, since the field |
| 1480 // may not actually be used. | 1466 // may not actually be used. |
| 1481 // Also, we may be generating a snapshot in production mode that will | 1467 // Also, we may be generating a snapshot in production mode that will |
| 1482 // later be executed in checked mode, in which case an error needs to | 1468 // later be executed in checked mode, in which case an error needs to |
| 1483 // be reported, should the field be accessed. | 1469 // be reported, should the field be accessed. |
| 1484 // Therefore, we undo the optimization performed by the parser, i.e. | 1470 // Therefore, we undo the optimization performed by the parser, i.e. |
| 1485 // we create an implicit static final getter and reset the field value | 1471 // we create an implicit static final getter and reset the field value |
| 1486 // to the sentinel value. | 1472 // to the sentinel value. |
| 1487 const Function& getter = Function::Handle( | 1473 const Function& getter = Function::Handle( |
| 1488 Z, | 1474 zone, |
| 1489 Function::New(getter_name, | 1475 Function::New(getter_name, |
| 1490 RawFunction::kImplicitStaticFinalGetter, | 1476 RawFunction::kImplicitStaticFinalGetter, |
| 1491 /* is_static = */ true, | 1477 /* is_static = */ true, |
| 1492 /* is_const = */ field.is_const(), | 1478 /* is_const = */ field.is_const(), |
| 1493 /* is_abstract = */ false, | 1479 /* is_abstract = */ false, |
| 1494 /* is_external = */ false, | 1480 /* is_external = */ false, |
| 1495 /* is_native = */ false, | 1481 /* is_native = */ false, |
| 1496 cls, | 1482 cls, |
| 1497 field.token_pos())); | 1483 field.token_pos())); |
| 1498 getter.set_result_type(type); | 1484 getter.set_result_type(type); |
| 1499 getter.set_is_debuggable(false); | 1485 getter.set_is_debuggable(false); |
| 1500 cls.AddFunction(getter); | 1486 cls.AddFunction(getter); |
| 1501 field.SetStaticValue(Object::sentinel(), true); | 1487 field.SetStaticValue(Object::sentinel(), true); |
| 1502 } | 1488 } |
| 1503 } | 1489 } |
| 1504 } | 1490 } |
| 1505 } | 1491 } |
| 1506 // Collect interfaces, super interfaces, and super classes of this class. | 1492 // Collect interfaces, super interfaces, and super classes of this class. |
| 1507 GrowableArray<const Class*> interfaces(Z, 4); | 1493 GrowableArray<const Class*> interfaces(zone, 4); |
| 1508 CollectInterfaces(cls, &interfaces); | 1494 CollectInterfaces(cls, &interfaces); |
| 1509 // Include superclasses in list of interfaces and super interfaces. | 1495 // Include superclasses in list of interfaces and super interfaces. |
| 1510 super_class = cls.SuperClass(); | 1496 super_class = cls.SuperClass(); |
| 1511 while (!super_class.IsNull()) { | 1497 while (!super_class.IsNull()) { |
| 1512 interfaces.Add(&Class::ZoneHandle(Z, super_class.raw())); | 1498 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw())); |
| 1513 CollectInterfaces(super_class, &interfaces); | 1499 CollectInterfaces(super_class, &interfaces); |
| 1514 super_class = super_class.SuperClass(); | 1500 super_class = super_class.SuperClass(); |
| 1515 } | 1501 } |
| 1516 // Resolve function signatures and check for conflicts in super classes and | 1502 // Resolve function signatures and check for conflicts in super classes and |
| 1517 // interfaces. | 1503 // interfaces. |
| 1518 array = cls.functions(); | 1504 array = cls.functions(); |
| 1519 Function& function = Function::Handle(Z); | 1505 Function& function = Function::Handle(zone); |
| 1520 Function& overridden_function = Function::Handle(Z); | 1506 Function& overridden_function = Function::Handle(zone); |
| 1521 const intptr_t num_functions = array.Length(); | 1507 const intptr_t num_functions = array.Length(); |
| 1522 Error& error = Error::Handle(Z); | 1508 Error& error = Error::Handle(zone); |
| 1523 for (intptr_t i = 0; i < num_functions; i++) { | 1509 for (intptr_t i = 0; i < num_functions; i++) { |
| 1524 function ^= array.At(i); | 1510 function ^= array.At(i); |
| 1525 FinalizeSignature(cls, function); | 1511 FinalizeSignature(cls, function); |
| 1526 name = function.name(); | 1512 name = function.name(); |
| 1527 // Report signature conflicts only. | 1513 // Report signature conflicts only. |
| 1528 if (Isolate::Current()->error_on_bad_override() && | 1514 if (Isolate::Current()->error_on_bad_override() && |
| 1529 !function.is_static() && !function.IsGenerativeConstructor()) { | 1515 !function.is_static() && !function.IsGenerativeConstructor()) { |
| 1530 // A constructor cannot override anything. | 1516 // A constructor cannot override anything. |
| 1531 for (intptr_t i = 0; i < interfaces.length(); i++) { | 1517 for (intptr_t i = 0; i < interfaces.length(); i++) { |
| 1532 const Class* super_class = interfaces.At(i); | 1518 const Class* super_class = interfaces.At(i); |
| 1533 // Finalize superclass since overrides check relies on all members | 1519 // Finalize superclass since overrides check relies on all members |
| 1534 // of the superclass to be finalized. | 1520 // of the superclass to be finalized. |
| 1535 FinalizeClass(*super_class); | 1521 FinalizeClass(*super_class); |
| 1536 overridden_function = super_class->LookupDynamicFunction(name); | 1522 overridden_function = super_class->LookupDynamicFunction(name); |
| 1537 if (!overridden_function.IsNull() && | 1523 if (!overridden_function.IsNull() && |
| 1538 !function.HasCompatibleParametersWith(overridden_function, | 1524 !function.HasCompatibleParametersWith(overridden_function, |
| 1539 &error)) { | 1525 &error)) { |
| 1540 const String& class_name = String::Handle(Z, cls.Name()); | 1526 const String& class_name = String::Handle(zone, cls.Name()); |
| 1541 const String& super_class_name = | 1527 const String& super_cls_name = |
| 1542 String::Handle(Z, super_class->Name()); | 1528 String::Handle(zone, super_class->Name()); |
| 1543 ReportErrors(error, cls, function.token_pos(), | 1529 ReportErrors(error, cls, function.token_pos(), |
| 1544 "class '%s' overrides method '%s' of super " | 1530 "class '%s' overrides method '%s' of super " |
| 1545 "class '%s' with incompatible parameters", | 1531 "class '%s' with incompatible parameters", |
| 1546 class_name.ToCString(), | 1532 class_name.ToCString(), |
| 1547 name.ToCString(), | 1533 name.ToCString(), |
| 1548 super_class_name.ToCString()); | 1534 super_cls_name.ToCString()); |
| 1549 } | 1535 } |
| 1550 } | 1536 } |
| 1551 } | 1537 } |
| 1552 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { | 1538 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { |
| 1553 if (function.is_static()) { | 1539 if (function.is_static()) { |
| 1554 super_class = FindSuperOwnerOfFunction(cls, name); | 1540 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1555 if (!super_class.IsNull()) { | 1541 if (!super_class.IsNull()) { |
| 1556 const String& class_name = String::Handle(Z, cls.Name()); | 1542 const String& class_name = String::Handle(zone, cls.Name()); |
| 1557 const String& super_class_name = | 1543 const String& super_cls_name = |
| 1558 String::Handle(Z, super_class.Name()); | 1544 String::Handle(zone, super_class.Name()); |
| 1559 ReportError(cls, function.token_pos(), | 1545 ReportError(cls, function.token_pos(), |
| 1560 "static setter '%s=' of class '%s' conflicts with " | 1546 "static setter '%s=' of class '%s' conflicts with " |
| 1561 "instance setter '%s=' of super class '%s'", | 1547 "instance setter '%s=' of super class '%s'", |
| 1562 name.ToCString(), | 1548 name.ToCString(), |
| 1563 class_name.ToCString(), | 1549 class_name.ToCString(), |
| 1564 name.ToCString(), | 1550 name.ToCString(), |
| 1565 super_class_name.ToCString()); | 1551 super_cls_name.ToCString()); |
| 1566 } | 1552 } |
| 1567 } | 1553 } |
| 1568 continue; | 1554 continue; |
| 1569 } | 1555 } |
| 1570 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { | 1556 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { |
| 1571 getter_name = name.raw(); | 1557 getter_name = name.raw(); |
| 1572 name = Field::NameFromGetter(getter_name); | 1558 name = Field::NameFromGetter(getter_name); |
| 1573 } else { | 1559 } else { |
| 1574 getter_name = Field::GetterSymbol(name); | 1560 getter_name = Field::GetterSymbol(name); |
| 1575 } | 1561 } |
| 1576 if (function.is_static()) { | 1562 if (function.is_static()) { |
| 1577 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1563 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
| 1578 if (!super_class.IsNull()) { | 1564 if (!super_class.IsNull()) { |
| 1579 const String& class_name = String::Handle(Z, cls.Name()); | 1565 const String& class_name = String::Handle(zone, cls.Name()); |
| 1580 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1566 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1581 ReportError(cls, function.token_pos(), | 1567 ReportError(cls, function.token_pos(), |
| 1582 "static %s '%s' of class '%s' conflicts with " | 1568 "static %s '%s' of class '%s' conflicts with " |
| 1583 "instance member '%s' of super class '%s'", | 1569 "instance member '%s' of super class '%s'", |
| 1584 (function.IsGetterFunction() || | 1570 (function.IsGetterFunction() || |
| 1585 function.IsImplicitGetterFunction()) ? "getter" : "method", | 1571 function.IsImplicitGetterFunction()) ? "getter" : "method", |
| 1586 name.ToCString(), | 1572 name.ToCString(), |
| 1587 class_name.ToCString(), | 1573 class_name.ToCString(), |
| 1588 name.ToCString(), | 1574 name.ToCString(), |
| 1589 super_class_name.ToCString()); | 1575 super_cls_name.ToCString()); |
| 1590 } | 1576 } |
| 1591 if (function.IsRedirectingFactory()) { | 1577 if (function.IsRedirectingFactory()) { |
| 1592 // The function may be a still unresolved redirecting factory. Do not | 1578 // The function may be a still unresolved redirecting factory. Do not |
| 1593 // yet try to resolve it in order to avoid cycles in class finalization. | 1579 // yet try to resolve it in order to avoid cycles in class finalization. |
| 1594 // However, the redirection type should be finalized. | 1580 // However, the redirection type should be finalized. |
| 1595 // If the redirection type is from a deferred library and is not | 1581 // If the redirection type is from a deferred library and is not |
| 1596 // yet loaded, do not attempt to resolve. | 1582 // yet loaded, do not attempt to resolve. |
| 1597 Type& type = Type::Handle(Z, function.RedirectionType()); | 1583 Type& type = Type::Handle(zone, function.RedirectionType()); |
| 1598 if (IsLoaded(type)) { | 1584 if (IsLoaded(type)) { |
| 1599 type ^= FinalizeType(cls, type, kCanonicalize); | 1585 type ^= FinalizeType(cls, type, kCanonicalize); |
| 1600 function.SetRedirectionType(type); | 1586 function.SetRedirectionType(type); |
| 1601 } | 1587 } |
| 1602 } | 1588 } |
| 1603 } else if (function.IsGetterFunction() || | 1589 } else if (function.IsGetterFunction() || |
| 1604 function.IsImplicitGetterFunction()) { | 1590 function.IsImplicitGetterFunction()) { |
| 1605 super_class = FindSuperOwnerOfFunction(cls, name); | 1591 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1606 if (!super_class.IsNull()) { | 1592 if (!super_class.IsNull()) { |
| 1607 const String& class_name = String::Handle(Z, cls.Name()); | 1593 const String& class_name = String::Handle(zone, cls.Name()); |
| 1608 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1594 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1609 ReportError(cls, function.token_pos(), | 1595 ReportError(cls, function.token_pos(), |
| 1610 "getter '%s' of class '%s' conflicts with " | 1596 "getter '%s' of class '%s' conflicts with " |
| 1611 "method '%s' of super class '%s'", | 1597 "method '%s' of super class '%s'", |
| 1612 name.ToCString(), | 1598 name.ToCString(), |
| 1613 class_name.ToCString(), | 1599 class_name.ToCString(), |
| 1614 name.ToCString(), | 1600 name.ToCString(), |
| 1615 super_class_name.ToCString()); | 1601 super_cls_name.ToCString()); |
| 1616 } | 1602 } |
| 1617 } else if (!function.IsSetterFunction() && | 1603 } else if (!function.IsSetterFunction() && |
| 1618 !function.IsImplicitSetterFunction()) { | 1604 !function.IsImplicitSetterFunction()) { |
| 1619 // A function cannot conflict with a setter, since they cannot | 1605 // A function cannot conflict with a setter, since they cannot |
| 1620 // have the same name. Thus, we do not need to check setters. | 1606 // have the same name. Thus, we do not need to check setters. |
| 1621 super_class = FindSuperOwnerOfFunction(cls, getter_name); | 1607 super_class = FindSuperOwnerOfFunction(cls, getter_name); |
| 1622 if (!super_class.IsNull()) { | 1608 if (!super_class.IsNull()) { |
| 1623 const String& class_name = String::Handle(Z, cls.Name()); | 1609 const String& class_name = String::Handle(zone, cls.Name()); |
| 1624 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1610 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
| 1625 ReportError(cls, function.token_pos(), | 1611 ReportError(cls, function.token_pos(), |
| 1626 "method '%s' of class '%s' conflicts with " | 1612 "method '%s' of class '%s' conflicts with " |
| 1627 "getter '%s' of super class '%s'", | 1613 "getter '%s' of super class '%s'", |
| 1628 name.ToCString(), | 1614 name.ToCString(), |
| 1629 class_name.ToCString(), | 1615 class_name.ToCString(), |
| 1630 name.ToCString(), | 1616 name.ToCString(), |
| 1631 super_class_name.ToCString()); | 1617 super_cls_name.ToCString()); |
| 1632 } | 1618 } |
| 1633 } | 1619 } |
| 1634 } | 1620 } |
| 1635 } | 1621 } |
| 1636 | 1622 |
| 1637 | 1623 |
| 1638 // Clone the type parameters of the super class and of the mixin class of this | 1624 // Clone the type parameters of the super class and of the mixin class of this |
| 1639 // mixin application class and use them as the type parameters of this mixin | 1625 // mixin application class and use them as the type parameters of this mixin |
| 1640 // application class. Set the type arguments of the super type, of the mixin | 1626 // application class. Set the type arguments of the super type, of the mixin |
| 1641 // type (as well as of the interface type, which is identical to the mixin type) | 1627 // type (as well as of the interface type, which is identical to the mixin type) |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2355 cls.set_super_type(super_type); | 2341 cls.set_super_type(super_type); |
| 2356 } | 2342 } |
| 2357 // Finalize mixin type. | 2343 // Finalize mixin type. |
| 2358 Type& mixin_type = Type::Handle(cls.mixin()); | 2344 Type& mixin_type = Type::Handle(cls.mixin()); |
| 2359 if (!mixin_type.IsNull()) { | 2345 if (!mixin_type.IsNull()) { |
| 2360 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); | 2346 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); |
| 2361 cls.set_mixin(mixin_type); | 2347 cls.set_mixin(mixin_type); |
| 2362 } | 2348 } |
| 2363 if (cls.IsTypedefClass()) { | 2349 if (cls.IsTypedefClass()) { |
| 2364 const Function& signature = Function::Handle(cls.signature_function()); | 2350 const Function& signature = Function::Handle(cls.signature_function()); |
| 2365 FunctionType& type = FunctionType::Handle(signature.SignatureType()); | 2351 Type& type = Type::Handle(signature.SignatureType()); |
| 2366 | 2352 |
| 2367 // Check for illegal self references. | 2353 // Check for illegal self references. |
| 2368 GrowableArray<intptr_t> visited_aliases; | 2354 GrowableArray<intptr_t> visited_aliases; |
| 2369 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { | 2355 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { |
| 2370 const String& name = String::Handle(cls.Name()); | 2356 const String& name = String::Handle(cls.Name()); |
| 2371 ReportError(cls, cls.token_pos(), | 2357 ReportError(cls, cls.token_pos(), |
| 2372 "typedef '%s' illegally refers to itself", | 2358 "typedef '%s' illegally refers to itself", |
| 2373 name.ToCString()); | 2359 name.ToCString()); |
| 2374 } | 2360 } |
| 2375 cls.set_is_type_finalized(); | 2361 cls.set_is_type_finalized(); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2583 // No cycles. | 2569 // No cycles. |
| 2584 return true; | 2570 return true; |
| 2585 } | 2571 } |
| 2586 | 2572 |
| 2587 | 2573 |
| 2588 // Returns false if a function type alias illegally refers to itself. | 2574 // Returns false if a function type alias illegally refers to itself. |
| 2589 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, | 2575 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, |
| 2590 const AbstractType& type, | 2576 const AbstractType& type, |
| 2591 GrowableArray<intptr_t>* visited) { | 2577 GrowableArray<intptr_t>* visited) { |
| 2592 ASSERT(visited != NULL); | 2578 ASSERT(visited != NULL); |
| 2593 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); | 2579 ResolveType(cls, type); |
| 2594 bool checking_typedef = false; | 2580 bool checking_typedef = false; |
| 2595 if ((resolved_type.IsType() || resolved_type.IsFunctionType()) && | 2581 if (type.IsType() && !type.IsMalformed()) { |
| 2596 !resolved_type.IsMalformed()) { | |
| 2597 AbstractType& other_type = AbstractType::Handle(); | 2582 AbstractType& other_type = AbstractType::Handle(); |
| 2598 if (resolved_type.IsFunctionType()) { | 2583 if (type.IsFunctionType()) { |
| 2599 const Class& scope_class = Class::Handle(resolved_type.type_class()); | 2584 const Class& scope_class = Class::Handle(type.type_class()); |
| 2600 const Function& signature_function = | 2585 const Function& signature_function = |
| 2601 Function::Handle(FunctionType::Cast(resolved_type).signature()); | 2586 Function::Handle(Type::Cast(type).signature()); |
| 2602 // The signature function of this function type may be a local signature | 2587 // The signature function of this function type may be a local signature |
| 2603 // function used in a formal parameter type of the typedef signature, but | 2588 // function used in a formal parameter type of the typedef signature, but |
| 2604 // not the typedef signature function itself, thus not qualifying as an | 2589 // not the typedef signature function itself, thus not qualifying as an |
| 2605 // illegal self reference. | 2590 // illegal self reference. |
| 2606 if (!scope_class.is_type_finalized() && | 2591 if (!scope_class.is_type_finalized() && |
| 2607 scope_class.IsTypedefClass() && | 2592 scope_class.IsTypedefClass() && |
| 2608 (scope_class.signature_function() == signature_function.raw())) { | 2593 (scope_class.signature_function() == signature_function.raw())) { |
| 2609 checking_typedef = true; | 2594 checking_typedef = true; |
| 2610 const intptr_t scope_class_id = scope_class.id(); | 2595 const intptr_t scope_class_id = scope_class.id(); |
| 2611 ASSERT(visited != NULL); | 2596 ASSERT(visited != NULL); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2638 } | 2623 } |
| 2639 // Check the parameter types of the signature of this function type. | 2624 // Check the parameter types of the signature of this function type. |
| 2640 const intptr_t num_parameters = signature_function.NumParameters(); | 2625 const intptr_t num_parameters = signature_function.NumParameters(); |
| 2641 for (intptr_t i = 0; i < num_parameters; i++) { | 2626 for (intptr_t i = 0; i < num_parameters; i++) { |
| 2642 other_type = signature_function.ParameterTypeAt(i); | 2627 other_type = signature_function.ParameterTypeAt(i); |
| 2643 if (!IsTypedefCycleFree(cls, other_type, visited)) { | 2628 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
| 2644 return false; | 2629 return false; |
| 2645 } | 2630 } |
| 2646 } | 2631 } |
| 2647 } | 2632 } |
| 2648 const TypeArguments& type_args = | 2633 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
| 2649 TypeArguments::Handle(resolved_type.arguments()); | |
| 2650 if (!type_args.IsNull()) { | 2634 if (!type_args.IsNull()) { |
| 2651 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2635 for (intptr_t i = 0; i < type_args.Length(); i++) { |
| 2652 other_type = type_args.TypeAt(i); | 2636 other_type = type_args.TypeAt(i); |
| 2653 if (!IsTypedefCycleFree(cls, other_type, visited)) { | 2637 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
| 2654 return false; | 2638 return false; |
| 2655 } | 2639 } |
| 2656 } | 2640 } |
| 2657 } | 2641 } |
| 2658 if (checking_typedef) { | 2642 if (checking_typedef) { |
| 2659 visited->RemoveLast(); | 2643 visited->RemoveLast(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2739 // and resolve super type and mixin types. | 2723 // and resolve super type and mixin types. |
| 2740 Zone* zone = Thread::Current()->zone(); | 2724 Zone* zone = Thread::Current()->zone(); |
| 2741 const Library& library = Library::Handle(zone, cls.library()); | 2725 const Library& library = Library::Handle(zone, cls.library()); |
| 2742 ASSERT(!library.IsNull()); | 2726 ASSERT(!library.IsNull()); |
| 2743 const Script& script = Script::Handle(zone, cls.script()); | 2727 const Script& script = Script::Handle(zone, cls.script()); |
| 2744 ASSERT(!script.IsNull()); | 2728 ASSERT(!script.IsNull()); |
| 2745 const GrowableObjectArray& type_args = | 2729 const GrowableObjectArray& type_args = |
| 2746 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2730 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| 2747 AbstractType& mixin_super_type = | 2731 AbstractType& mixin_super_type = |
| 2748 AbstractType::Handle(zone, mixin_app_type.super_type()); | 2732 AbstractType::Handle(zone, mixin_app_type.super_type()); |
| 2749 mixin_super_type = ResolveType(cls, mixin_super_type); | 2733 ResolveType(cls, mixin_super_type); |
| 2750 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2734 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
| 2751 if (mixin_super_type.IsMalformedOrMalbounded()) { | 2735 if (mixin_super_type.IsMalformedOrMalbounded()) { |
| 2752 ReportError(Error::Handle(zone, mixin_super_type.error())); | 2736 ReportError(Error::Handle(zone, mixin_super_type.error())); |
| 2753 } | 2737 } |
| 2754 if (mixin_super_type.IsDynamicType()) { | 2738 if (mixin_super_type.IsDynamicType()) { |
| 2755 ReportError(cls, cls.token_pos(), | 2739 ReportError(cls, cls.token_pos(), |
| 2756 "class '%s' may not extend 'dynamic'", | 2740 "class '%s' may not extend 'dynamic'", |
| 2757 String::Handle(zone, cls.Name()).ToCString()); | 2741 String::Handle(zone, cls.Name()).ToCString()); |
| 2758 } | 2742 } |
| 2759 // The super type may have a BoundedType as type argument, but cannot be | 2743 // The super type may have a BoundedType as type argument, but cannot be |
| 2760 // a BoundedType itself. | 2744 // a BoundedType itself. |
| 2761 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2745 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
| 2762 AbstractType& mixin_type = AbstractType::Handle(zone); | 2746 AbstractType& mixin_type = AbstractType::Handle(zone); |
| 2763 Class& mixin_type_class = Class::Handle(zone); | 2747 Class& mixin_type_class = Class::Handle(zone); |
| 2764 Class& mixin_app_class = Class::Handle(zone); | 2748 Class& mixin_app_class = Class::Handle(zone); |
| 2765 String& mixin_app_class_name = String::Handle(zone); | 2749 String& mixin_app_class_name = String::Handle(zone); |
| 2766 String& mixin_type_class_name = String::Handle(zone); | 2750 String& mixin_type_class_name = String::Handle(zone); |
| 2767 AbstractType& super_type_arg = AbstractType::Handle(zone); | 2751 AbstractType& super_type_arg = AbstractType::Handle(zone); |
| 2768 AbstractType& mixin_type_arg = AbstractType::Handle(zone); | 2752 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
| 2769 const intptr_t depth = mixin_app_type.Depth(); | 2753 const intptr_t depth = mixin_app_type.Depth(); |
| 2770 for (intptr_t i = 0; i < depth; i++) { | 2754 for (intptr_t i = 0; i < depth; i++) { |
| 2771 mixin_type = mixin_app_type.MixinTypeAt(i); | 2755 mixin_type = mixin_app_type.MixinTypeAt(i); |
| 2772 ASSERT(!mixin_type.IsNull()); | 2756 ASSERT(!mixin_type.IsNull()); |
| 2773 mixin_type = ResolveType(cls, mixin_type); | 2757 ResolveType(cls, mixin_type); |
| 2774 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2758 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
| 2775 ASSERT(mixin_type.IsType()); | 2759 ASSERT(mixin_type.IsType()); |
| 2776 const intptr_t num_super_type_args = type_args.Length(); | 2760 const intptr_t num_super_type_args = type_args.Length(); |
| 2777 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2761 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
| 2778 | 2762 |
| 2779 // If the mixin type has identical type arguments as the super type, they | 2763 // If the mixin type has identical type arguments as the super type, they |
| 2780 // can share the same type parameters of the mixin application class, | 2764 // can share the same type parameters of the mixin application class, |
| 2781 // thereby allowing for further optimizations, such as instantiator vector | 2765 // thereby allowing for further optimizations, such as instantiator vector |
| 2782 // reuse or sharing of type arguments with the super class. | 2766 // reuse or sharing of type arguments with the super class. |
| 2783 bool share_type_params = (num_super_type_args > 0) && | 2767 bool share_type_params = (num_super_type_args > 0) && |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2924 // If cls belongs to core lib, restrictions about allowed interfaces | 2908 // If cls belongs to core lib, restrictions about allowed interfaces |
| 2925 // are lifted. | 2909 // are lifted. |
| 2926 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 2910 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
| 2927 | 2911 |
| 2928 // Resolve and check the super type and interfaces of cls. | 2912 // Resolve and check the super type and interfaces of cls. |
| 2929 visited->Add(cls_index); | 2913 visited->Add(cls_index); |
| 2930 AbstractType& interface = AbstractType::Handle(zone); | 2914 AbstractType& interface = AbstractType::Handle(zone); |
| 2931 Class& interface_class = Class::Handle(zone); | 2915 Class& interface_class = Class::Handle(zone); |
| 2932 | 2916 |
| 2933 // Resolve super type. Failures lead to a longjmp. | 2917 // Resolve super type. Failures lead to a longjmp. |
| 2934 super_type = ResolveType(cls, super_type); | 2918 ResolveType(cls, super_type); |
| 2935 if (super_type.IsMalformedOrMalbounded()) { | 2919 if (super_type.IsMalformedOrMalbounded()) { |
| 2936 ReportError(Error::Handle(zone, super_type.error())); | 2920 ReportError(Error::Handle(zone, super_type.error())); |
| 2937 } | 2921 } |
| 2938 if (super_type.IsDynamicType()) { | 2922 if (super_type.IsDynamicType()) { |
| 2939 ReportError(cls, cls.token_pos(), | 2923 ReportError(cls, cls.token_pos(), |
| 2940 "class '%s' may not extend 'dynamic'", | 2924 "class '%s' may not extend 'dynamic'", |
| 2941 String::Handle(zone, cls.Name()).ToCString()); | 2925 String::Handle(zone, cls.Name()).ToCString()); |
| 2942 } | 2926 } |
| 2943 interface_class = super_type.type_class(); | 2927 interface_class = super_type.type_class(); |
| 2944 if (interface_class.IsTypedefClass()) { | 2928 if (interface_class.IsTypedefClass()) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3004 String::Handle(zone, cls.Name()).ToCString(), | 2988 String::Handle(zone, cls.Name()).ToCString(), |
| 3005 interface_name.ToCString()); | 2989 interface_name.ToCString()); |
| 3006 } | 2990 } |
| 3007 } | 2991 } |
| 3008 // Now resolve the super interfaces of the super type. | 2992 // Now resolve the super interfaces of the super type. |
| 3009 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2993 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 3010 | 2994 |
| 3011 // Resolve interfaces. Failures lead to a longjmp. | 2995 // Resolve interfaces. Failures lead to a longjmp. |
| 3012 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2996 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 3013 interface ^= super_interfaces.At(i); | 2997 interface ^= super_interfaces.At(i); |
| 3014 interface = ResolveType(cls, interface); | 2998 ResolveType(cls, interface); |
| 3015 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2999 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| 3016 // A malbounded interface is only reported when involved in a type test. | 3000 // A malbounded interface is only reported when involved in a type test. |
| 3017 if (interface.IsMalformed()) { | 3001 if (interface.IsMalformed()) { |
| 3018 ReportError(Error::Handle(zone, interface.error())); | 3002 ReportError(Error::Handle(zone, interface.error())); |
| 3019 } | 3003 } |
| 3020 if (interface.IsDynamicType()) { | 3004 if (interface.IsDynamicType()) { |
| 3021 ReportError(cls, cls.token_pos(), | 3005 ReportError(cls, cls.token_pos(), |
| 3022 "'dynamic' may not be used as interface"); | 3006 "'dynamic' may not be used as interface"); |
| 3023 } | 3007 } |
| 3024 interface_class = interface.type_class(); | 3008 interface_class = interface.type_class(); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3321 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3305 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3322 field ^= fields_array.At(0); | 3306 field ^= fields_array.At(0); |
| 3323 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3307 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3324 name ^= field.name(); | 3308 name ^= field.name(); |
| 3325 expected_name ^= String::New("_data"); | 3309 expected_name ^= String::New("_data"); |
| 3326 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3310 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3327 #endif | 3311 #endif |
| 3328 } | 3312 } |
| 3329 | 3313 |
| 3330 } // namespace dart | 3314 } // namespace dart |
| OLD | NEW |