| 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/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 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 527 } |
| 528 | 528 |
| 529 | 529 |
| 530 // Finalize the type argument vector 'arguments' of the type defined by the | 530 // Finalize the type argument vector 'arguments' of the type defined by the |
| 531 // class 'cls' parameterized with the type arguments 'cls_args'. | 531 // class 'cls' parameterized with the type arguments 'cls_args'. |
| 532 // The vector 'cls_args' is already initialized as a subvector at the correct | 532 // The vector 'cls_args' is already initialized as a subvector at the correct |
| 533 // position in the passed in 'arguments' vector. | 533 // position in the passed in 'arguments' vector. |
| 534 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 534 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
| 535 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 535 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
| 536 // vector. | 536 // vector. |
| 537 // Example: | 537 // The type argument vector of cls may overlap the type argument vector of its |
| 538 // super class. In case of an overlap, the overlapped type arguments of the |
| 539 // super class are already initialized. The still uninitialized ones have an |
| 540 // offset smaller than 'num_uninitialized_arguments'. |
| 541 // Example 1 (without overlap): |
| 538 // Declared: class C<K, V> extends B<V> { ... } | 542 // Declared: class C<K, V> extends B<V> { ... } |
| 539 // class B<T> extends A<int> { ... } | 543 // class B<T> extends A<int> { ... } |
| 540 // Input: C<String, double> expressed as | 544 // Input: C<String, double> expressed as |
| 541 // cls = C, arguments = [null, null, String, double], | 545 // cls = C, arguments = [dynamic, dynamic, String, double], |
| 546 // num_uninitialized_arguments = 2, |
| 542 // i.e. cls_args = [String, double], offset = 2, length = 2. | 547 // i.e. cls_args = [String, double], offset = 2, length = 2. |
| 543 // Output: arguments = [int, double, String, double] | 548 // Output: arguments = [int, double, String, double] |
| 549 // Example 2 (with overlap): |
| 550 // Declared: class C<K, V> extends B<K> { ... } |
| 551 // class B<T> extends A<int> { ... } |
| 552 // Input: C<String, double> expressed as |
| 553 // cls = C, arguments = [dynamic, String, double], |
| 554 // num_uninitialized_arguments = 1, |
| 555 // i.e. cls_args = [String, double], offset = 1, length = 2. |
| 556 // Output: arguments = [int, String, double] |
| 544 void ClassFinalizer::FinalizeTypeArguments( | 557 void ClassFinalizer::FinalizeTypeArguments( |
| 545 const Class& cls, | 558 const Class& cls, |
| 546 const AbstractTypeArguments& arguments, | 559 const AbstractTypeArguments& arguments, |
| 560 intptr_t num_uninitialized_arguments, |
| 547 FinalizationKind finalization, | 561 FinalizationKind finalization, |
| 548 Error* bound_error) { | 562 Error* bound_error) { |
| 549 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 563 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 550 if (!cls.is_type_finalized()) { | 564 if (!cls.is_type_finalized()) { |
| 551 FinalizeTypeParameters(cls); | 565 FinalizeTypeParameters(cls); |
| 552 ResolveUpperBounds(cls); | 566 ResolveUpperBounds(cls); |
| 553 } | 567 } |
| 554 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 568 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 555 if (!super_type.IsNull()) { | 569 if (!super_type.IsNull()) { |
| 556 const Class& super_class = Class::Handle(super_type.type_class()); | 570 const Class& super_class = Class::Handle(super_type.type_class()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 572 // Derived[Base[Derived[dynamic]], T]. | 586 // Derived[Base[Derived[dynamic]], T]. |
| 573 ASSERT(super_type_args.IsNull()); // Same as a vector of dynamic. | 587 ASSERT(super_type_args.IsNull()); // Same as a vector of dynamic. |
| 574 } else { | 588 } else { |
| 575 super_type ^= FinalizeType(cls, super_type, finalization); | 589 super_type ^= FinalizeType(cls, super_type, finalization); |
| 576 cls.set_super_type(super_type); | 590 cls.set_super_type(super_type); |
| 577 super_type_args = super_type.arguments(); | 591 super_type_args = super_type.arguments(); |
| 578 } | 592 } |
| 579 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 593 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 580 const intptr_t offset = super_class.NumTypeArguments(); | 594 const intptr_t offset = super_class.NumTypeArguments(); |
| 581 const intptr_t super_offset = offset - num_super_type_params; | 595 const intptr_t super_offset = offset - num_super_type_params; |
| 582 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 596 ASSERT(offset == (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
| 583 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 597 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
| 584 for (intptr_t i = 0; i < num_super_type_params; i++) { | 598 for (intptr_t i = 0; super_offset + i < num_uninitialized_arguments; i++) { |
| 585 if (!super_type_args.IsNull()) { | 599 if (!super_type_args.IsNull()) { |
| 586 super_type_arg = super_type_args.TypeAt(super_offset + i); | 600 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 587 if (!super_type_arg.IsInstantiated()) { | 601 if (!super_type_arg.IsInstantiated()) { |
| 588 Error& malformed_error = Error::Handle(); | 602 Error& malformed_error = Error::Handle(); |
| 589 super_type_arg = super_type_arg.InstantiateFrom(arguments, | 603 super_type_arg = super_type_arg.InstantiateFrom(arguments, |
| 590 &malformed_error); | 604 &malformed_error); |
| 591 if (!malformed_error.IsNull()) { | 605 if (!malformed_error.IsNull()) { |
| 592 if (!super_type_arg.IsInstantiated()) { | 606 if (!super_type_arg.IsInstantiated()) { |
| 593 // CheckTypeArgumentBounds will insert a BoundedType. | 607 // CheckTypeArgumentBounds will insert a BoundedType. |
| 594 } else if (bound_error->IsNull()) { | 608 } else if (bound_error->IsNull()) { |
| 595 *bound_error = malformed_error.raw(); | 609 *bound_error = malformed_error.raw(); |
| 596 } | 610 } |
| 597 } | 611 } |
| 598 } | 612 } |
| 599 if (finalization >= kCanonicalize) { | 613 if (finalization >= kCanonicalize) { |
| 600 super_type_arg = super_type_arg.Canonicalize(); | 614 super_type_arg = super_type_arg.Canonicalize(); |
| 601 } | 615 } |
| 602 } | 616 } |
| 603 arguments.SetTypeAt(super_offset + i, super_type_arg); | 617 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 604 } | 618 } |
| 605 FinalizeTypeArguments(super_class, arguments, finalization, bound_error); | 619 FinalizeTypeArguments(super_class, arguments, super_offset, |
| 620 finalization, bound_error); |
| 606 } | 621 } |
| 607 } | 622 } |
| 608 | 623 |
| 609 | 624 |
| 610 // Check the type argument vector 'arguments' against the corresponding bounds | 625 // Check the type argument vector 'arguments' against the corresponding bounds |
| 611 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 626 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
| 612 // Replace a type argument that cannot be checked at compile time by a | 627 // Replace a type argument that cannot be checked at compile time by a |
| 613 // BoundedType, thereby postponing the bound check to run time. | 628 // BoundedType, thereby postponing the bound check to run time. |
| 614 // Return a bound error if a type argument is not within bound at compile time. | 629 // Return a bound error if a type argument is not within bound at compile time. |
| 615 void ClassFinalizer::CheckTypeArgumentBounds( | 630 void ClassFinalizer::CheckTypeArgumentBounds( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 629 const intptr_t num_type_params = cls.NumTypeParameters(); | 644 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 630 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | 645 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
| 631 AbstractType& type_arg = AbstractType::Handle(); | 646 AbstractType& type_arg = AbstractType::Handle(); |
| 632 AbstractType& cls_type_param = AbstractType::Handle(); | 647 AbstractType& cls_type_param = AbstractType::Handle(); |
| 633 AbstractType& declared_bound = AbstractType::Handle(); | 648 AbstractType& declared_bound = AbstractType::Handle(); |
| 634 AbstractType& instantiated_bound = AbstractType::Handle(); | 649 AbstractType& instantiated_bound = AbstractType::Handle(); |
| 635 const TypeArguments& cls_type_params = | 650 const TypeArguments& cls_type_params = |
| 636 TypeArguments::Handle(cls.type_parameters()); | 651 TypeArguments::Handle(cls.type_parameters()); |
| 637 ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) || | 652 ASSERT((cls_type_params.IsNull() && (num_type_params == 0)) || |
| 638 (cls_type_params.Length() == num_type_params)); | 653 (cls_type_params.Length() == num_type_params)); |
| 654 // In case of overlapping type argument vectors, the same type argument may |
| 655 // get checked against different bounds. |
| 639 for (intptr_t i = 0; i < num_type_params; i++) { | 656 for (intptr_t i = 0; i < num_type_params; i++) { |
| 640 type_arg = arguments.TypeAt(offset + i); | 657 type_arg = arguments.TypeAt(offset + i); |
| 641 if (type_arg.IsDynamicType()) { | 658 if (type_arg.IsDynamicType()) { |
| 642 continue; | 659 continue; |
| 643 } | 660 } |
| 644 cls_type_param = cls_type_params.TypeAt(i); | 661 cls_type_param = cls_type_params.TypeAt(i); |
| 645 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); | 662 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); |
| 646 ASSERT(type_param.IsFinalized()); | 663 ASSERT(type_param.IsFinalized()); |
| 647 declared_bound = type_param.bound(); | 664 declared_bound = type_param.bound(); |
| 648 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { | 665 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 // malformed. | 734 // malformed. |
| 718 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { | 735 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { |
| 719 return type.Canonicalize(); | 736 return type.Canonicalize(); |
| 720 } | 737 } |
| 721 return type.raw(); | 738 return type.raw(); |
| 722 } | 739 } |
| 723 ASSERT(type.IsResolved()); | 740 ASSERT(type.IsResolved()); |
| 724 ASSERT(finalization >= kFinalize); | 741 ASSERT(finalization >= kFinalize); |
| 725 | 742 |
| 726 if (FLAG_trace_type_finalization) { | 743 if (FLAG_trace_type_finalization) { |
| 727 OS::Print("Finalize type '%s' for class '%s'\n", | 744 OS::Print("Finalizing type '%s' for class '%s'\n", |
| 728 String::Handle(type.Name()).ToCString(), | 745 String::Handle(type.Name()).ToCString(), |
| 729 cls.ToCString()); | 746 cls.ToCString()); |
| 730 } | 747 } |
| 731 | 748 |
| 732 if (type.IsTypeParameter()) { | 749 if (type.IsTypeParameter()) { |
| 733 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 750 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
| 734 const Class& parameterized_class = | 751 const Class& parameterized_class = |
| 735 Class::Handle(type_parameter.parameterized_class()); | 752 Class::Handle(type_parameter.parameterized_class()); |
| 736 ASSERT(!parameterized_class.IsNull()); | 753 ASSERT(!parameterized_class.IsNull()); |
| 737 // The index must reflect the position of this type parameter in the type | 754 // The index must reflect the position of this type parameter in the type |
| 738 // arguments vector of its parameterized class. The offset to add is the | 755 // arguments vector of its parameterized class. The offset to add is the |
| 739 // number of type arguments in the super type, which is equal to the | 756 // number of type arguments in the super type, which is equal to the |
| 740 // difference in number of type arguments and type parameters of the | 757 // difference in number of type arguments and type parameters of the |
| 741 // parameterized class. | 758 // parameterized class. |
| 742 const intptr_t offset = parameterized_class.NumTypeArguments() - | 759 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 743 parameterized_class.NumTypeParameters(); | 760 parameterized_class.NumTypeParameters(); |
| 744 // Calling NumTypeParameters() may finalize this type parameter if it | 761 // Calling NumTypeParameters() may finalize this type parameter if it |
| 745 // belongs to a mixin application class. | 762 // belongs to a mixin application class. |
| 746 if (!type_parameter.IsFinalized()) { | 763 if (!type_parameter.IsFinalized()) { |
| 747 type_parameter.set_index(type_parameter.index() + offset); | 764 type_parameter.set_index(type_parameter.index() + offset); |
| 748 type_parameter.set_is_finalized(); | 765 type_parameter.set_is_finalized(); |
| 749 } else { | 766 } else { |
| 750 ASSERT(cls.IsMixinApplication()); | 767 ASSERT(cls.IsMixinApplication()); |
| 751 } | 768 } |
| 769 |
| 770 if (FLAG_trace_type_finalization) { |
| 771 OS::Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
| 772 String::Handle(type_parameter.name()).ToCString(), |
| 773 type_parameter.index()); |
| 774 } |
| 775 |
| 752 // We do not canonicalize type parameters. | 776 // We do not canonicalize type parameters. |
| 753 return type_parameter.raw(); | 777 return type_parameter.raw(); |
| 754 } | 778 } |
| 755 | 779 |
| 756 // At this point, we can only have a parameterized_type. | 780 // At this point, we can only have a parameterized_type. |
| 757 const Type& parameterized_type = Type::Cast(type); | 781 const Type& parameterized_type = Type::Cast(type); |
| 758 | 782 |
| 759 // Types illegally referring to themselves should have been detected earlier. | 783 // Types illegally referring to themselves should have been detected earlier. |
| 760 ASSERT(!parameterized_type.IsBeingFinalized()); | 784 ASSERT(!parameterized_type.IsBeingFinalized()); |
| 761 | 785 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 script, parameterized_type.token_pos(), | 833 script, parameterized_type.token_pos(), |
| 810 "wrong number of type arguments for class '%s'", | 834 "wrong number of type arguments for class '%s'", |
| 811 type_class_name.ToCString()); | 835 type_class_name.ToCString()); |
| 812 } | 836 } |
| 813 // Make the type raw and continue without reporting any error. | 837 // Make the type raw and continue without reporting any error. |
| 814 // A static warning should have been reported. | 838 // A static warning should have been reported. |
| 815 arguments = AbstractTypeArguments::null(); | 839 arguments = AbstractTypeArguments::null(); |
| 816 parameterized_type.set_arguments(arguments); | 840 parameterized_type.set_arguments(arguments); |
| 817 } | 841 } |
| 818 // The full type argument vector consists of the type arguments of the | 842 // The full type argument vector consists of the type arguments of the |
| 819 // super types of type_class, which may be initialized from the parsed | 843 // super types of type_class, which are initialized from the parsed |
| 820 // type arguments, followed by the parsed type arguments. | 844 // type arguments, followed by the parsed type arguments. |
| 821 TypeArguments& full_arguments = TypeArguments::Handle(); | 845 TypeArguments& full_arguments = TypeArguments::Handle(); |
| 822 Error& bound_error = Error::Handle(); | 846 Error& bound_error = Error::Handle(); |
| 823 if (num_type_arguments > 0) { | 847 if (num_type_arguments > 0) { |
| 824 // If no type arguments were parsed and if the super types do not prepend | 848 // If no type arguments were parsed and if the super types do not prepend |
| 825 // type arguments to the vector, we can leave the vector as null. | 849 // type arguments to the vector, we can leave the vector as null. |
| 826 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 850 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 827 full_arguments = TypeArguments::New(num_type_arguments); | 851 full_arguments = TypeArguments::New(num_type_arguments); |
| 828 // Copy the parsed type arguments at the correct offset in the full type | 852 // Copy the parsed type arguments at the correct offset in the full type |
| 829 // argument vector. | 853 // argument vector. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 855 // of its signature function and no super type is involved. | 879 // of its signature function and no super type is involved. |
| 856 // If the signature class is canonical (not an alias), the owner of its | 880 // If the signature class is canonical (not an alias), the owner of its |
| 857 // signature function may either be an alias or the enclosing class of a | 881 // signature function may either be an alias or the enclosing class of a |
| 858 // local function, in which case the super type of the enclosing class is | 882 // local function, in which case the super type of the enclosing class is |
| 859 // also considered when filling up the argument vector. | 883 // also considered when filling up the argument vector. |
| 860 if (type_class.IsSignatureClass()) { | 884 if (type_class.IsSignatureClass()) { |
| 861 const Function& signature_fun = | 885 const Function& signature_fun = |
| 862 Function::Handle(type_class.signature_function()); | 886 Function::Handle(type_class.signature_function()); |
| 863 ASSERT(!signature_fun.is_static()); | 887 ASSERT(!signature_fun.is_static()); |
| 864 const Class& sig_fun_owner = Class::Handle(signature_fun.Owner()); | 888 const Class& sig_fun_owner = Class::Handle(signature_fun.Owner()); |
| 865 FinalizeTypeArguments( | 889 if (offset > 0) { |
| 866 sig_fun_owner, full_arguments, finalization, &bound_error); | 890 FinalizeTypeArguments(sig_fun_owner, full_arguments, offset, |
| 891 finalization, &bound_error); |
| 892 } |
| 867 CheckTypeArgumentBounds(sig_fun_owner, full_arguments, &bound_error); | 893 CheckTypeArgumentBounds(sig_fun_owner, full_arguments, &bound_error); |
| 868 } else { | 894 } else { |
| 869 FinalizeTypeArguments( | 895 if (offset > 0) { |
| 870 type_class, full_arguments, finalization, &bound_error); | 896 FinalizeTypeArguments(type_class, full_arguments, offset, |
| 897 finalization, &bound_error); |
| 898 } |
| 871 CheckTypeArgumentBounds(type_class, full_arguments, &bound_error); | 899 CheckTypeArgumentBounds(type_class, full_arguments, &bound_error); |
| 872 } | 900 } |
| 873 if (full_arguments.IsRaw(num_type_arguments)) { | 901 if (full_arguments.IsRaw(num_type_arguments)) { |
| 874 // The parameterized_type is raw. Set its argument vector to null, which | 902 // The parameterized_type is raw. Set its argument vector to null, which |
| 875 // is more efficient in type tests. | 903 // is more efficient in type tests. |
| 876 full_arguments = TypeArguments::null(); | 904 full_arguments = TypeArguments::null(); |
| 877 } else if (finalization >= kCanonicalize) { | 905 } else if (finalization >= kCanonicalize) { |
| 878 // FinalizeTypeArguments can modify 'full_arguments', | 906 // FinalizeTypeArguments can modify 'full_arguments', |
| 879 // canonicalize afterwards. | 907 // canonicalize afterwards. |
| 880 full_arguments ^= full_arguments.Canonicalize(); | 908 full_arguments ^= full_arguments.Canonicalize(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 907 if (!bound_error.IsNull()) { | 935 if (!bound_error.IsNull()) { |
| 908 // No compile-time error during finalization. | 936 // No compile-time error during finalization. |
| 909 const String& parameterized_type_name = String::Handle( | 937 const String& parameterized_type_name = String::Handle( |
| 910 parameterized_type.UserVisibleName()); | 938 parameterized_type.UserVisibleName()); |
| 911 const Type& malformed_bound = Type::Handle( | 939 const Type& malformed_bound = Type::Handle( |
| 912 NewFinalizedMalformedType(bound_error, | 940 NewFinalizedMalformedType(bound_error, |
| 913 Script::Handle(cls.script()), | 941 Script::Handle(cls.script()), |
| 914 parameterized_type.token_pos(), | 942 parameterized_type.token_pos(), |
| 915 "type '%s' has an out of bound type argument", | 943 "type '%s' has an out of bound type argument", |
| 916 parameterized_type_name.ToCString())); | 944 parameterized_type_name.ToCString())); |
| 945 |
| 946 if (FLAG_trace_type_finalization) { |
| 947 OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n", |
| 948 String::Handle(parameterized_type.Name()).ToCString(), |
| 949 bound_error.ToCString()); |
| 950 } |
| 951 |
| 917 return BoundedType::New(parameterized_type, | 952 return BoundedType::New(parameterized_type, |
| 918 malformed_bound, | 953 malformed_bound, |
| 919 TypeParameter::Handle()); | 954 TypeParameter::Handle()); |
| 920 } | 955 } |
| 921 | 956 |
| 957 if (FLAG_trace_type_finalization) { |
| 958 OS::Print("Done finalizing type '%s' with %" Pd " type args\n", |
| 959 String::Handle(parameterized_type.Name()).ToCString(), |
| 960 parameterized_type.arguments() == AbstractTypeArguments::null() ? |
| 961 0 : num_type_arguments); |
| 962 } |
| 963 |
| 922 if (finalization >= kCanonicalize) { | 964 if (finalization >= kCanonicalize) { |
| 923 return parameterized_type.Canonicalize(); | 965 return parameterized_type.Canonicalize(); |
| 924 } else { | 966 } else { |
| 925 return parameterized_type.raw(); | 967 return parameterized_type.raw(); |
| 926 } | 968 } |
| 927 } | 969 } |
| 928 | 970 |
| 929 | 971 |
| 930 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 972 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 931 const Function& function) { | 973 const Function& function) { |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 as the superclass of S&A. The class S&A` declares a type argument T: | 1521 as the superclass of S&A. The class S&A` declares a type argument T: |
| 1480 | 1522 |
| 1481 Instead of | 1523 Instead of |
| 1482 S&A<T`, U, V> extends S<T`> implements A<U, V> { } | 1524 S&A<T`, U, V> extends S<T`> implements A<U, V> { } |
| 1483 | 1525 |
| 1484 We now have: | 1526 We now have: |
| 1485 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } | 1527 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } |
| 1486 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } | 1528 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } |
| 1487 | 1529 |
| 1488 The main implementation difficulty resides in the fact that the type parameters | 1530 The main implementation difficulty resides in the fact that the type parameters |
| 1489 U and V in the super type S&A`<T`, Map<U, V>> of S&A refer to the type | 1531 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type |
| 1490 parameters U and V of S&A, not to U and V of A. An instantiation step with | 1532 parameters U and V of S&A. However, Map<U, V> is copied from the super type |
| 1491 a properly crafted instantiator vector takes care of the required type parameter | 1533 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation |
| 1492 substitution. | 1534 step with a properly crafted instantiator vector takes care of the required type |
| 1535 parameter substitution. |
| 1536 |
| 1537 The instantiator vector must end with the type parameters U and V of S&A. |
| 1538 The offset of the first type parameter U of S&A must be at the finalized index |
| 1539 of type parameter U of A. |
| 1493 */ | 1540 */ |
| 1494 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { | 1541 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { |
| 1495 // If this mixin typedef is aliasing another mixin typedef, another class | 1542 // If this mixin typedef is aliasing another mixin typedef, another class |
| 1496 // will be inserted via recursion. No need to check here. | 1543 // will be inserted via recursion. No need to check here. |
| 1544 // The mixin type may or may not be finalized yet. |
| 1497 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1545 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1498 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1546 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1499 ASSERT(mixin_class.is_mixin_typedef()); | 1547 ASSERT(mixin_class.is_mixin_typedef()); |
| 1500 const Class& aliased_mixin_app_class = Class::Handle( | 1548 const Class& aliased_mixin_app_class = Class::Handle( |
| 1501 mixin_class.SuperClass()); | 1549 mixin_class.SuperClass()); |
| 1502 const Type& aliased_mixin_type = Type::Handle( | 1550 const Type& aliased_mixin_type = Type::Handle( |
| 1503 aliased_mixin_app_class.mixin()); | 1551 aliased_mixin_app_class.mixin()); |
| 1504 // The name of the inserted mixin application class is the name of mixin | 1552 // The name of the inserted mixin application class is the name of mixin |
| 1505 // class name with a backtick added. | 1553 // class name with a backtick added. |
| 1506 String& inserted_class_name = String::Handle(mixin_app_class.Name()); | 1554 String& inserted_class_name = String::Handle(mixin_app_class.Name()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 // It is important that the type parameters of the mixin application class | 1590 // It is important that the type parameters of the mixin application class |
| 1543 // are not finalized yet, because new type parameters may have been added | 1591 // are not finalized yet, because new type parameters may have been added |
| 1544 // to the super class. | 1592 // to the super class. |
| 1545 Class& super_class = Class::Handle(super_type.type_class()); | 1593 Class& super_class = Class::Handle(super_type.type_class()); |
| 1546 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); | 1594 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); |
| 1547 while (super_class.IsMixinApplication()) { | 1595 while (super_class.IsMixinApplication()) { |
| 1548 super_class = super_class.SuperClass(); | 1596 super_class = super_class.SuperClass(); |
| 1549 } | 1597 } |
| 1550 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1598 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1551 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1599 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1552 intptr_t offset = aliased_mixin_app_class.NumTypeArguments(); | 1600 intptr_t offset = |
| 1601 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); |
| 1553 const TypeArguments& type_params = | 1602 const TypeArguments& type_params = |
| 1554 TypeArguments::Handle(mixin_app_class.type_parameters()); | 1603 TypeArguments::Handle(mixin_app_class.type_parameters()); |
| 1555 TypeArguments& instantiator = TypeArguments::Handle( | 1604 TypeArguments& instantiator = TypeArguments::Handle( |
| 1556 TypeArguments::New(offset + num_mixin_type_params)); | 1605 TypeArguments::New(offset + num_mixin_type_params)); |
| 1557 AbstractType& type = AbstractType::Handle(); | 1606 AbstractType& type = AbstractType::Handle(); |
| 1558 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1607 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1559 type = type_params.TypeAt(num_super_type_params + i); | 1608 type = type_params.TypeAt(num_super_type_params + i); |
| 1560 instantiator.SetTypeAt(offset + i, type); | 1609 instantiator.SetTypeAt(offset + i, type); |
| 1561 } | 1610 } |
| 1562 ASSERT(aliased_mixin_type.IsFinalized()); | 1611 ASSERT(aliased_mixin_type.IsFinalized()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1606 new_super_type_args.SetTypeAt(num_super_type_params + i, type); | 1655 new_super_type_args.SetTypeAt(num_super_type_params + i, type); |
| 1607 } | 1656 } |
| 1608 } | 1657 } |
| 1609 super_type = Type::New(inserted_class, | 1658 super_type = Type::New(inserted_class, |
| 1610 new_super_type_args, | 1659 new_super_type_args, |
| 1611 mixin_app_class.token_pos()); | 1660 mixin_app_class.token_pos()); |
| 1612 mixin_app_class.set_super_type(super_type); | 1661 mixin_app_class.set_super_type(super_type); |
| 1613 // Mark this mixin application class as being a typedef. | 1662 // Mark this mixin application class as being a typedef. |
| 1614 mixin_app_class.set_is_mixin_typedef(); | 1663 mixin_app_class.set_is_mixin_typedef(); |
| 1615 ASSERT(!mixin_app_class.is_type_finalized()); | 1664 ASSERT(!mixin_app_class.is_type_finalized()); |
| 1665 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
| 1616 if (FLAG_trace_class_finalization) { | 1666 if (FLAG_trace_class_finalization) { |
| 1617 OS::Print("Inserting class %s to mixin typedef application %s " | 1667 OS::Print("Inserting class %s to mixin typedef application %s " |
| 1618 "with super type '%s'\n", | 1668 "with super type '%s'\n", |
| 1619 inserted_class.ToCString(), | 1669 inserted_class.ToCString(), |
| 1620 mixin_app_class.ToCString(), | 1670 mixin_app_class.ToCString(), |
| 1621 String::Handle(super_type.Name()).ToCString()); | 1671 String::Handle(super_type.Name()).ToCString()); |
| 1622 } | 1672 } |
| 1623 } | 1673 } |
| 1624 | 1674 |
| 1625 | 1675 |
| (...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2611 expected_name ^= String::New("_offset"); | 2661 expected_name ^= String::New("_offset"); |
| 2612 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2662 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2613 field ^= fields_array.At(2); | 2663 field ^= fields_array.At(2); |
| 2614 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2664 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2615 name ^= field.name(); | 2665 name ^= field.name(); |
| 2616 ASSERT(name.Equals("length")); | 2666 ASSERT(name.Equals("length")); |
| 2617 #endif | 2667 #endif |
| 2618 } | 2668 } |
| 2619 | 2669 |
| 2620 } // namespace dart | 2670 } // namespace dart |
| OLD | NEW |