Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 1232613005: Allow super calls in mixins (for now behind a --supermixin flag). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "vm/longjump.h" 11 #include "vm/longjump.h"
12 #include "vm/object_store.h" 12 #include "vm/object_store.h"
13 #include "vm/report.h" 13 #include "vm/report.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 18 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
19 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 19 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
20 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 20 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
21 DECLARE_FLAG(bool, supermixin);
21 DECLARE_FLAG(bool, use_cha_deopt); 22 DECLARE_FLAG(bool, use_cha_deopt);
22 23
23 24
24 bool ClassFinalizer::AllClassesFinalized() { 25 bool ClassFinalizer::AllClassesFinalized() {
25 ObjectStore* object_store = Isolate::Current()->object_store(); 26 ObjectStore* object_store = Isolate::Current()->object_store();
26 const GrowableObjectArray& classes = 27 const GrowableObjectArray& classes =
27 GrowableObjectArray::Handle(object_store->pending_classes()); 28 GrowableObjectArray::Handle(object_store->pending_classes());
28 return classes.Length() == 0; 29 return classes.Length() == 0;
29 } 30 }
30 31
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 1555
1555 1556
1556 // Clone the type parameters of the super class and of the mixin class of this 1557 // Clone the type parameters of the super class and of the mixin class of this
1557 // mixin application class and use them as the type parameters of this mixin 1558 // mixin application class and use them as the type parameters of this mixin
1558 // application class. Set the type arguments of the super type, of the mixin 1559 // application class. Set the type arguments of the super type, of the mixin
1559 // type (as well as of the interface type, which is identical to the mixin type) 1560 // type (as well as of the interface type, which is identical to the mixin type)
1560 // to refer to the respective type parameters of the mixin application class. 1561 // to refer to the respective type parameters of the mixin application class.
1561 // In other words, decorate this mixin application class with type parameters 1562 // In other words, decorate this mixin application class with type parameters
1562 // that forward to the super type and mixin type (and interface type). 1563 // that forward to the super type and mixin type (and interface type).
1563 // Example: 1564 // Example:
1564 // class S<T> { } 1565 // class S<T extends BT> { }
1565 // class M<T> { } 1566 // class M<T extends BT> { }
1566 // class C<E> extends S<E> with M<List<E>> { } 1567 // class C<E extends BE> extends S<E> with M<List<E>> { }
1567 // results in 1568 // results in
1568 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> 1569 // class S&M<T`, T extends BT> extends S<T`> implements M<T> { }
1569 // class C<E> extends S&M<E, List<E>> { } 1570 // class C<E extends BE> extends S&M<E, List<E>> { }
1570 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and 1571 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and
1571 // T, and use them as type arguments in S<T`> and M<T>. 1572 // T, and use them as type arguments in S<T`> and M<T>.
1573 // Note that the bound BT on T of S is not applied to T` of S&M. However, the
1574 // bound BT on T of M is applied to T of S&M. See comments below.
1572 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { 1575 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
1573 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); 1576 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null());
1574 Isolate* isolate = Isolate::Current(); 1577 Isolate* isolate = Isolate::Current();
1575 const AbstractType& super_type = AbstractType::Handle(isolate, 1578 const AbstractType& super_type = AbstractType::Handle(isolate,
1576 mixin_app_class.super_type()); 1579 mixin_app_class.super_type());
1577 ASSERT(super_type.IsResolved()); 1580 ASSERT(super_type.IsResolved());
1578 const Class& super_class = Class::Handle(isolate, super_type.type_class()); 1581 const Class& super_class = Class::Handle(isolate, super_type.type_class());
1579 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 1582 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1580 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); 1583 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
1581 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); 1584 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
1582 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); 1585 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1583 // The mixin class cannot be Object and this was checked earlier.
1584 ASSERT(!mixin_class.IsObjectClass());
1585 1586
1586 // The mixin type (in raw form) should have been added to the interfaces 1587 // The mixin type (in raw form) should have been added to the interfaces
1587 // implemented by the mixin application class. This is necessary so that cycle 1588 // implemented by the mixin application class. This is necessary so that cycle
1588 // check works at compile time (type arguments are ignored) and so that 1589 // check works at compile time (type arguments are ignored) and so that
1589 // type tests work at runtime (by then, type arguments will have been set, see 1590 // type tests work at runtime (by then, type arguments will have been set, see
1590 // below). 1591 // below).
1591 ASSERT(mixin_app_class.interfaces() != Object::empty_array().raw()); 1592 ASSERT(mixin_app_class.interfaces() != Object::empty_array().raw());
1592 1593
1593 // If both the super type and the mixin type are non generic, the mixin 1594 // If both the super type and the mixin type are non generic, the mixin
1594 // application class is non generic as well and we can skip type parameter 1595 // application class is non generic as well and we can skip type parameter
1595 // cloning. 1596 // cloning.
1596 bool has_uninstantiated_bounds = false; 1597 TypeArguments& instantiator = TypeArguments::Handle(isolate);
1597 if ((num_super_type_params + num_mixin_type_params) > 0) { 1598 if ((num_super_type_params + num_mixin_type_params) > 0) {
1598 // If the last ampersand in the name of the mixin application class is 1599 // If the last ampersand in the name of the mixin application class is
1599 // doubled, the same type parameters can propagate the type arguments to 1600 // doubled, the same type parameters can propagate the type arguments to
1600 // the super type and to the mixin type. 1601 // the super type and to the mixin type.
1601 bool share_type_params = false; 1602 bool share_type_params = false;
1602 if (num_super_type_params == num_mixin_type_params) { 1603 if (num_super_type_params == num_mixin_type_params) {
1603 const String& name = String::Handle(isolate, mixin_app_class.Name()); 1604 const String& name = String::Handle(isolate, mixin_app_class.Name());
1604 for (intptr_t i = name.Length() - 1; i > 0; --i) { 1605 for (intptr_t i = name.Length() - 1; i > 0; --i) {
1605 if (name.CharAt(i) == '&') { 1606 if (name.CharAt(i) == '&') {
1606 if (name.CharAt(i - 1) == '&') { 1607 if (name.CharAt(i - 1) == '&') {
(...skipping 16 matching lines...) Expand all
1623 // First, clone the super class type parameters. Rename them so that 1624 // First, clone the super class type parameters. Rename them so that
1624 // there can be no name conflict between the parameters of the super 1625 // there can be no name conflict between the parameters of the super
1625 // class and the mixin class. 1626 // class and the mixin class.
1626 if (!share_type_params && (num_super_type_params > 0)) { 1627 if (!share_type_params && (num_super_type_params > 0)) {
1627 const TypeArguments& super_type_params = 1628 const TypeArguments& super_type_params =
1628 TypeArguments::Handle(isolate, super_class.type_parameters()); 1629 TypeArguments::Handle(isolate, super_class.type_parameters());
1629 const TypeArguments& super_type_args = TypeArguments::Handle(isolate, 1630 const TypeArguments& super_type_args = TypeArguments::Handle(isolate,
1630 TypeArguments::New(num_super_type_params)); 1631 TypeArguments::New(num_super_type_params));
1631 // The cloned super class type parameters do not need to repeat their 1632 // The cloned super class type parameters do not need to repeat their
1632 // bounds, since the bound checks will be performed at the super class 1633 // bounds, since the bound checks will be performed at the super class
1633 // level. 1634 // level. As a consequence, if this mixin application is used itself as a
1635 // mixin in another mixin application, the bounds will be ignored, which
1636 // is correct, because the other mixin application does not inherit from
1637 // the super class of its mixin. Note also that the other mixin
1638 // application will only mixin the last mixin type listed in the first
1639 // mixin application it is mixing in.
1634 param_bound = isolate->object_store()->object_type(); 1640 param_bound = isolate->object_store()->object_type();
1635 for (intptr_t i = 0; i < num_super_type_params; i++) { 1641 for (intptr_t i = 0; i < num_super_type_params; i++) {
1636 param ^= super_type_params.TypeAt(i); 1642 param ^= super_type_params.TypeAt(i);
1637 param_name = param.name(); 1643 param_name = param.name();
1638 param_name = String::Concat(param_name, Symbols::Backtick()); 1644 param_name = String::Concat(param_name, Symbols::Backtick());
1639 param_name = Symbols::New(param_name); 1645 param_name = Symbols::New(param_name);
1640 cloned_param = TypeParameter::New(mixin_app_class, 1646 cloned_param = TypeParameter::New(mixin_app_class,
1641 cloned_index, 1647 cloned_index,
1642 param_name, 1648 param_name,
1643 param_bound, 1649 param_bound,
1644 param.token_pos()); 1650 param.token_pos());
1645 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1651 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1646 // Change the type arguments of the super type to refer to the 1652 // Change the type arguments of the super type to refer to the
1647 // cloned type parameters of the mixin application class. 1653 // cloned type parameters of the mixin application class.
1648 super_type_args.SetTypeAt(cloned_index, cloned_param); 1654 super_type_args.SetTypeAt(cloned_index, cloned_param);
1649 cloned_index++; 1655 cloned_index++;
1650 } 1656 }
1651 // The super type may have a BoundedType as type argument, but cannot be 1657 // The super type may have a BoundedType as type argument, but cannot be
1652 // a BoundedType itself. 1658 // a BoundedType itself.
1653 Type::Cast(super_type).set_arguments(super_type_args); 1659 Type::Cast(super_type).set_arguments(super_type_args);
1654 ASSERT(!super_type.IsFinalized()); 1660 ASSERT(!super_type.IsFinalized());
1655 } 1661 }
1656 1662
1657 // Second, clone the type parameters of the mixin class. 1663 // Second, clone the type parameters of the mixin class.
1658 // We need to retain the parameter names of the mixin class 1664 // We need to retain the parameter names of the mixin class
1659 // since the code that will be compiled in the context of the 1665 // since the code that will be compiled in the context of the
1660 // mixin application class may refer to the type parameters 1666 // mixin application class may refer to the type parameters
1661 // with that name. 1667 // with that name. We also retain the type parameter bounds.
1662 if (num_mixin_type_params > 0) { 1668 if (num_mixin_type_params > 0) {
1663 const TypeArguments& mixin_params = 1669 const TypeArguments& mixin_params =
1664 TypeArguments::Handle(isolate, mixin_class.type_parameters()); 1670 TypeArguments::Handle(isolate, mixin_class.type_parameters());
1671 const intptr_t offset =
1672 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters();
1665 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate, 1673 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate,
1666 TypeArguments::New(num_mixin_type_params)); 1674 TypeArguments::New(num_mixin_type_params));
1675 instantiator ^= TypeArguments::New(offset + num_mixin_type_params);
1676 bool has_uninstantiated_bounds = false;
1667 for (intptr_t i = 0; i < num_mixin_type_params; i++) { 1677 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1668 param ^= mixin_params.TypeAt(i); 1678 param ^= mixin_params.TypeAt(i);
1669 param_name = param.name(); 1679 param_name = param.name();
1670 param_bound = param.bound(); // The bound will be adjusted below. 1680 param_bound = param.bound(); // The bound will be adjusted below.
1671 if (!param_bound.IsInstantiated()) { 1681 if (!param_bound.IsInstantiated()) {
1672 has_uninstantiated_bounds = true; 1682 has_uninstantiated_bounds = true;
1673 } 1683 }
1674 cloned_param = TypeParameter::New(mixin_app_class, 1684 cloned_param = TypeParameter::New(mixin_app_class,
1675 cloned_index, 1685 cloned_index, // Unfinalized index.
1676 param_name, 1686 param_name,
1677 param_bound, 1687 param_bound,
1678 param.token_pos()); 1688 param.token_pos());
1679 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1689 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1680 mixin_type_args.SetTypeAt(i, cloned_param); 1690 mixin_type_args.SetTypeAt(i, cloned_param); // Unfinalized length.
1691 instantiator.SetTypeAt(offset + i, cloned_param); // Finalized length.
1681 cloned_index++; 1692 cloned_index++;
1682 } 1693 }
1683 1694
1684 // Third, replace the type parameters appearing in the bounds of the mixin 1695 // Third, replace the type parameters appearing in the bounds of the mixin
1685 // type parameters, if any, by the cloned type parameters. This can be 1696 // type parameters, if any, by the cloned type parameters. This can be
1686 // done by instantiating each bound using the mixin_type_args as 1697 // done by instantiating each bound using the instantiator built above.
1687 // instantiator. Since the mixin class must extend Object, its first type 1698 // If the mixin class extends a generic super class, its first finalized
1688 // parameter has index 0, therefore, the instantiator does not require 1699 // type parameter has a non-zero index, therefore, the instantiator
1689 // shifting. There is however an exception where the mixin class is an 1700 // requires shifting by the offset calculated above.
1690 // alias, in which case shifting is required and performed later in
1691 // ApplyMixinAppAlias.
1692 // Unfinalized type parameters replace finalized type parameters, which 1701 // Unfinalized type parameters replace finalized type parameters, which
1693 // is not a problem since they will get finalized shortly as the mixin 1702 // is not a problem since they will get finalized shortly as the mixin
1694 // application class gets finalized. 1703 // application class gets finalized.
1695 if (has_uninstantiated_bounds && !mixin_class.is_mixin_app_alias()) { 1704 if (has_uninstantiated_bounds) {
1696 Error& bound_error = Error::Handle(isolate); 1705 Error& bound_error = Error::Handle(isolate);
1697 for (intptr_t i = 0; i < num_mixin_type_params; i++) { 1706 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1698 param ^= mixin_type_args.TypeAt(i); 1707 param ^= mixin_type_args.TypeAt(i);
1699 param_bound = param.bound(); 1708 param_bound = param.bound();
1700 if (!param_bound.IsInstantiated()) { 1709 if (!param_bound.IsInstantiated()) {
1701 // Make sure the bound is finalized before instantiating it. 1710 // Make sure the bound is finalized before instantiating it.
1702 if (!param_bound.IsFinalized() && 1711 if (!param_bound.IsFinalized() &&
1703 !param_bound.IsBeingFinalized()) { 1712 !param_bound.IsBeingFinalized()) {
1704 param_bound = 1713 param_bound =
1705 FinalizeType(mixin_app_class, param_bound, kCanonicalize); 1714 FinalizeType(mixin_app_class, param_bound, kCanonicalize);
1706 param.set_bound(param_bound); // In case part of recursive type. 1715 param.set_bound(param_bound); // In case part of recursive type.
1707 } 1716 }
1708 param_bound = param_bound.InstantiateFrom(mixin_type_args, 1717 param_bound = param_bound.InstantiateFrom(instantiator,
1709 &bound_error); 1718 &bound_error);
1710 // The instantiator contains only TypeParameter objects and no 1719 // The instantiator contains only TypeParameter objects and no
1711 // BoundedType objects, so no bound error may occur. 1720 // BoundedType objects, so no bound error may occur.
1721 ASSERT(!param_bound.IsBoundedType());
1712 ASSERT(bound_error.IsNull()); 1722 ASSERT(bound_error.IsNull());
1713 ASSERT(!param_bound.IsInstantiated()); 1723 ASSERT(!param_bound.IsInstantiated());
1714 param.set_bound(param_bound); 1724 param.set_bound(param_bound);
1715 } 1725 }
1716 } 1726 }
1717 } 1727 }
1718 1728
1719 // Lastly, set the type arguments of the mixin type, which is also the 1729 // Lastly, set the type arguments of the mixin type, which is also the
1720 // single interface type. 1730 // single interface type.
1721 ASSERT(!mixin_type.IsFinalized()); 1731 ASSERT(!mixin_type.IsFinalized());
1722 mixin_type.set_arguments(mixin_type_args); 1732 mixin_type.set_arguments(mixin_type_args);
1723 if (share_type_params) { 1733 if (share_type_params) {
1724 Type::Cast(super_type).set_arguments(mixin_type_args); 1734 Type::Cast(super_type).set_arguments(mixin_type_args);
1725 ASSERT(!super_type.IsFinalized()); 1735 ASSERT(!super_type.IsFinalized());
1726 } 1736 }
1727 } 1737 }
1728 mixin_app_class.set_type_parameters(cloned_type_params); 1738 mixin_app_class.set_type_parameters(cloned_type_params);
1729 } 1739 }
1730 // If the mixin class is a mixin application alias class, we insert a new 1740 // If the mixin class is a mixin application alias class, we insert a new
1731 // synthesized mixin application class in the super chain of this mixin 1741 // synthesized mixin application class in the super chain of this mixin
1732 // application class. The new class will have the aliased mixin as actual 1742 // application class. The new class will have the aliased mixin as actual
1733 // mixin. 1743 // mixin.
1734 if (mixin_class.is_mixin_app_alias()) { 1744 if (mixin_class.is_mixin_app_alias()) {
1735 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds); 1745 ApplyMixinAppAlias(mixin_app_class, instantiator);
1736 } 1746 }
1737 } 1747 }
1738 1748
1739 1749
1740 /* Support for mixin alias. 1750 /* Support for mixin alias.
1741 Consider the following example: 1751 Consider the following example:
1742 1752
1743 class I<T> { } 1753 class I<T> { }
1744 class J<T> { } 1754 class J<T> { }
1745 class S<T> { } 1755 class S<T extends num> { }
1746 class M<T> { } 1756 class M<T extends Map> { }
1747 class A<U, V> = Object with M<Map<U, V>> implements I<V>; 1757 class A<U, V extends List> = Object with M<Map<U, V>> implements I<V>;
1748 class C<T, K> = S<T> with A<T, List<K>> implements J<K>; 1758 class C<T, K extends T> = S<T> with A<T, List<K>> implements J<K>;
1749 1759
1750 Before the call to ApplyMixinAppAlias, the VM has already synthesized 2 mixin 1760 Before the call to ApplyMixinAppAlias, the VM has already synthesized 2 mixin
1751 application classes Object&M and S&A: 1761 application classes Object&M and S&A:
1752 1762
1753 Object&M<T> extends Object implements M<T> { ... members of M applied here ... } 1763 Object&M<T extends Map> extends Object implements M<T> {
1754 A<U, V> extends Object&M<Map<U, V>> implements I<V> { } 1764 ... members of M applied here ...
1765 }
1766 A<U, V extends List> extends Object&M<Map<U, V>> implements I<V> { }
1755 1767
1756 S&A<T`, U, V> extends S<T`> implements A<U, V> { } 1768 S&A<T`, U, V extends List> extends S<T`> implements A<U, V> {
1757 C<T, K> extends S&A<T, T, List<K>> implements J<K> { } 1769 ... members of A applied here, but A has no members ...
1770 }
1771 C<T, K extends T> extends S&A<T, T, List<K>> implements J<K> { }
1758 1772
1759 In theory, class A should be an alias of Object&M instead of extending it. 1773 In theory, class A should be an alias of Object&M instead of extending it.
1760 In practice, the additional class provides a hook for implemented interfaces 1774 In practice, the additional class provides a hook for implemented interfaces
1761 (e.g. I<V>) and for type argument substitution via the super type relation (e.g. 1775 (e.g. I<V>) and for type argument substitution via the super type relation (e.g.
1762 type parameter T of Object&M is substituted with Map<U, V>, U and V being the 1776 type parameter T of Object&M is substituted with Map<U, V>, U and V being the
1763 type parameters of the alias A). 1777 type parameters of the alias A).
1764 1778
1765 Similarly, class C should be an alias of S&A instead of extending it. 1779 Similarly, class C should be an alias of S&A instead of extending it.
1766 1780
1767 Since A is used as a mixin, it must extend Object. The fact that it extends
1768 Object&M must be hidden so that no error is wrongly reported.
1769
1770 Now, A does not have any members to be mixed into S&A, because A is an alias. 1781 Now, A does not have any members to be mixed into S&A, because A is an alias.
1771 The members to be mixed in are actually those of M, and they should appear in a 1782 The members to be mixed in are actually those of M, and they should appear in a
1772 scope where the type parameter T is visible. The class S&A declares the type 1783 scope where the type parameter T is visible. The class S&A declares the type
1773 parameters of A, i.e. U and V, but not T. 1784 parameters of A, i.e. U and V, but not T.
1774 1785
1775 Therefore, the call to ApplyMixinAppAlias inserts another synthesized class S&A` 1786 Therefore, the call to ApplyMixinAppAlias inserts another synthesized class S&A`
1776 as the superclass of S&A. The class S&A` declares a type argument T: 1787 as the superclass of S&A. The class S&A` declares a type argument T:
1777 1788
1778 Instead of 1789 Instead of
1779 S&A<T`, U, V> extends S<T`> implements A<U, V> { } 1790 S&A<T`, U, V extends List> extends S<T`> implements A<U, V> { }
1780 1791
1781 We now have: 1792 We now have:
1782 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } 1793 S&A`<T`, T extends Map> extends S<T`> implements M<T> {
1783 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } 1794 ... members of M applied here ...
1795 }
1796 S&A<T`, U, V extends List> extends S&A`<T`, Map<U, V>> implements A<U, V> { }
1784 1797
1785 The main implementation difficulty resides in the fact that the type parameters 1798 The main implementation difficulty resides in the fact that the type parameters
1786 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type 1799 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type
1787 parameters U and V of S&A. However, Map<U, V> is copied from the super type 1800 parameters U and V of S&A. However, Map<U, V> is copied from the super type
1788 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation 1801 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation
1789 step with a properly crafted instantiator vector takes care of the required type 1802 step with a properly crafted instantiator vector takes care of the required type
1790 parameter substitution. 1803 parameter substitution.
1791 The instantiator vector must end with the type parameters U and V of S&A. 1804 The instantiator vector must end with the type parameters U and V of S&A.
1792 The offset of the first type parameter U of S&A must be at the finalized index 1805 The offset in the instantiator of the type parameter U of S&A must be at the
1793 of type parameter U of A. 1806 finalized index of type parameter U of A.
1794 1807
1795 The same instantiator vector is used to adjust the type parameter bounds on U 1808 The same instantiator vector is used to adjust the type parameter bounds on U
1796 and V, if any. This step was postponed from CloneMixinAppTypeParameters above. 1809 and V, if any. This step is done in CloneMixinAppTypeParameters above, and the
1810 already built instantiator is passed here.
1797 1811
1798 Also, a possible bound on type parameter T of M (not shown in the example above) 1812 Also, a possible bound on type parameter T of M must be applied to type
1799 must be applied to type parameter T of S&A`. If the bound is uninstantiated, 1813 parameter T of S&A`. If the bound is uninstantiated, i.e. if it refers to T or
1800 i.e. if it refers to T or other type parameters of M, an instantiation step is 1814 other type parameters of M, an instantiation step is required to substitute
1801 required to substitute these type parameters of M with type parameters of S&A`. 1815 these type parameters of M with type parameters of S&A`.
1802 The instantiator vector consists of the cloned type parameters of M without 1816 The instantiator vector consists of the cloned type parameters of M shifted by
1803 offset, since class M must extend Object. This is done in the recursive call to 1817 an offset corresponding to the finalized index of the first type parameter of M.
1804 CloneMixinAppTypeParameters and does not require specific code in 1818 This is done in the recursive call to CloneMixinAppTypeParameters and does not
1805 ApplyMixinAppAlias. 1819 require specific code in ApplyMixinAppAlias.
1806 */ 1820 */
1807 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, 1821 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class,
1808 bool has_uninstantiated_bounds) { 1822 const TypeArguments& instantiator) {
1809 // If this mixin alias is aliasing another mixin alias, another class 1823 // If this mixin alias is aliasing another mixin alias, another class
1810 // will be inserted via recursion. No need to check here. 1824 // will be inserted via recursion. No need to check here.
1811 // The mixin type may or may not be finalized yet. 1825 // The mixin type may or may not be finalized yet.
1812 Isolate* isolate = Isolate::Current(); 1826 Isolate* isolate = Isolate::Current();
1813 AbstractType& super_type = AbstractType::Handle(isolate, 1827 AbstractType& super_type = AbstractType::Handle(isolate,
1814 mixin_app_class.super_type()); 1828 mixin_app_class.super_type());
1815 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); 1829 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
1816 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); 1830 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
1817 ASSERT(mixin_class.is_mixin_app_alias()); 1831 ASSERT(mixin_class.is_mixin_app_alias());
1818 const Class& aliased_mixin_app_class = Class::Handle(isolate, 1832 const Class& aliased_mixin_app_class = Class::Handle(isolate,
1819 mixin_class.SuperClass()); 1833 mixin_class.SuperClass());
1834 // Note that the super class of aliased_mixin_app_class can itself be a
1835 // mixin application class (this happens if the alias is mixing more than one
1836 // type). Instead of trying to recursively insert yet another class as the
1837 // super class of this inserted class, we apply the composition rules of the
1838 // spec and only mixin the members of aliased_mixin_app_class, not those of
1839 // its super class. In other words, we only mixin the last mixin of the alias.
1820 const Type& aliased_mixin_type = Type::Handle(isolate, 1840 const Type& aliased_mixin_type = Type::Handle(isolate,
1821 aliased_mixin_app_class.mixin()); 1841 aliased_mixin_app_class.mixin());
1822 // The name of the inserted mixin application class is the name of mixin 1842 // The name of the inserted mixin application class is the name of mixin
1823 // class name with a backtick added. 1843 // class name with a backtick added.
1824 String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name()); 1844 String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name());
1825 inserted_class_name = String::Concat(inserted_class_name, 1845 inserted_class_name = String::Concat(inserted_class_name,
1826 Symbols::Backtick()); 1846 Symbols::Backtick());
1827 const Library& library = Library::Handle(isolate, mixin_app_class.library()); 1847 const Library& library = Library::Handle(isolate, mixin_app_class.library());
1828 Class& inserted_class = Class::Handle(isolate, 1848 Class& inserted_class = Class::Handle(isolate,
1829 library.LookupLocalClass(inserted_class_name)); 1849 library.LookupLocalClass(inserted_class_name));
(...skipping 14 matching lines...) Expand all
1844 // this mixin application class, except that it must refer to the type 1864 // this mixin application class, except that it must refer to the type
1845 // parameters of the inserted class rather than to those of the mixin 1865 // parameters of the inserted class rather than to those of the mixin
1846 // application class. 1866 // application class.
1847 // The type arguments of the super type will be set properly when calling 1867 // The type arguments of the super type will be set properly when calling
1848 // CloneMixinAppTypeParameters on the inserted class, as long as the super 1868 // CloneMixinAppTypeParameters on the inserted class, as long as the super
1849 // type class is set properly. 1869 // type class is set properly.
1850 inserted_class.set_super_type(super_type); // Super class only is used. 1870 inserted_class.set_super_type(super_type); // Super class only is used.
1851 1871
1852 // The mixin type and interface type must also be set before calling 1872 // The mixin type and interface type must also be set before calling
1853 // CloneMixinAppTypeParameters. 1873 // CloneMixinAppTypeParameters.
1854 // After FinalizeTypesInClass, they will refer to the type parameters of 1874 // After FinalizeTypesInClass, if the mixin type and interface type are
1855 // the mixin class typedef. 1875 // generic, their type arguments will refer to the type parameters of
1856 const Type& generic_mixin_type = Type::Handle(isolate, 1876 // inserted_class.
1877 const Type& inserted_class_mixin_type = Type::Handle(isolate,
1857 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), 1878 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()),
1858 Object::null_type_arguments(), 1879 Object::null_type_arguments(),
1859 aliased_mixin_type.token_pos())); 1880 aliased_mixin_type.token_pos()));
1860 inserted_class.set_mixin(generic_mixin_type); 1881 inserted_class.set_mixin(inserted_class_mixin_type);
1861 // Add the mixin type to the list of interfaces that the mixin application 1882 // Add the mixin type to the list of interfaces that the mixin application
1862 // class implements. This is necessary so that cycle check work at 1883 // class implements. This is necessary so that cycle check work at
1863 // compile time (type arguments are ignored by that check). 1884 // compile time (type arguments are ignored by that check).
1864 const Array& interfaces = Array::Handle(Array::New(1)); 1885 const Array& interfaces = Array::Handle(Array::New(1));
1865 interfaces.SetAt(0, generic_mixin_type); 1886 interfaces.SetAt(0, inserted_class_mixin_type);
1866 ASSERT(inserted_class.interfaces() == Object::empty_array().raw()); 1887 ASSERT(inserted_class.interfaces() == Object::empty_array().raw());
1867 inserted_class.set_interfaces(interfaces); 1888 inserted_class.set_interfaces(interfaces);
1868 // The type arguments of the interface, if any, will be set in 1889 // The type arguments of the interface, if any, will be set in
1869 // CloneMixinAppTypeParameters, which is called indirectly from 1890 // CloneMixinAppTypeParameters, which is called indirectly from
1870 // FinalizeTypesInClass below. 1891 // FinalizeTypesInClass below.
1871 } 1892 }
1872 1893
1873 // Finalize the types and call CloneMixinAppTypeParameters. 1894 // Finalize the types and call CloneMixinAppTypeParameters.
1874 FinalizeTypesInClass(inserted_class); 1895 FinalizeTypesInClass(inserted_class);
1875 1896
1876 // The super type of this mixin application class must point to the 1897 // The super type of this mixin application class must point to the
1877 // inserted class. The super type arguments are the concatenation of the 1898 // inserted class. The super type arguments are the concatenation of the
1878 // old super type arguments (propagating type arguments to the super class) 1899 // old super type arguments (propagating type arguments to the super class)
1879 // with new type arguments providing type arguments to the mixin. 1900 // with new type arguments providing type arguments to the mixin.
1880 // The appended type arguments are those of the super type of the mixin 1901 // The appended type arguments are those of the super type of the mixin
1881 // application alias that are forwarding to the aliased mixin type, except 1902 // application alias that are forwarding to the aliased mixin type, except
1882 // that they must refer to the type parameters of the mixin application 1903 // that they must refer to the type parameters of the mixin application
1883 // class rather than to those of the mixin application alias class. 1904 // class rather than to those of the mixin application alias class.
1884 // This type parameter substitution is performed by an instantiation step. 1905 // This type parameter substitution is performed by an instantiation step.
1885 // It is important that the type parameters of the mixin application class 1906 // It is important that the type parameters of the mixin application class
1886 // are not finalized yet, because new type parameters may have been added 1907 // are not finalized yet, because new type parameters may have been added
1887 // to the super class. 1908 // to the super class.
1888 Class& super_class = Class::Handle(isolate, super_type.type_class()); 1909 const Class& super_class = Class::Handle(isolate, super_type.type_class());
1889 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); 1910 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); // Will change.
1890 while (super_class.IsMixinApplication()) {
1891 super_class = super_class.SuperClass();
1892 }
1893 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 1911 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1894 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1895 intptr_t offset =
1896 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters();
1897 const TypeArguments& type_params =
1898 TypeArguments::Handle(isolate, mixin_app_class.type_parameters());
1899 TypeArguments& instantiator = TypeArguments::Handle(isolate,
1900 TypeArguments::New(offset + num_mixin_type_params));
1901 AbstractType& type = AbstractType::Handle(isolate); 1912 AbstractType& type = AbstractType::Handle(isolate);
1902 for (intptr_t i = 0; i < num_mixin_type_params; i++) { 1913 // The instantiator is mapping finalized type parameters of mixin_class to
1903 type = type_params.TypeAt(num_super_type_params + i); 1914 // unfinalized type parameters of mixin_app_class.
1904 instantiator.SetTypeAt(offset + i, type);
1905 }
1906 ASSERT(aliased_mixin_type.IsFinalized()); 1915 ASSERT(aliased_mixin_type.IsFinalized());
1907 const Class& aliased_mixin_type_class = Class::Handle(isolate, 1916 const Class& aliased_mixin_type_class = Class::Handle(isolate,
1908 aliased_mixin_type.type_class()); 1917 aliased_mixin_type.type_class());
1909 const intptr_t num_aliased_mixin_type_params = 1918 const intptr_t num_aliased_mixin_type_params =
1910 aliased_mixin_type_class.NumTypeParameters(); 1919 aliased_mixin_type_class.NumTypeParameters();
1911 const intptr_t num_aliased_mixin_type_args =
1912 aliased_mixin_type_class.NumTypeArguments();
1913 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params;
1914 ASSERT(inserted_class.NumTypeParameters() == 1920 ASSERT(inserted_class.NumTypeParameters() ==
1915 (num_super_type_params + num_aliased_mixin_type_params)); 1921 (num_super_type_params + num_aliased_mixin_type_params));
1922 const AbstractType& mixin_class_super_type =
1923 AbstractType::Handle(isolate, mixin_class.super_type());
1924 ASSERT(mixin_class_super_type.IsFinalized());
1916 // The aliased_mixin_type may be raw. 1925 // The aliased_mixin_type may be raw.
1917 const TypeArguments& mixin_class_super_type_args = 1926 const TypeArguments& mixin_class_super_type_args =
1918 TypeArguments::Handle(isolate, 1927 TypeArguments::Handle(isolate, mixin_class_super_type.arguments());
1919 AbstractType::Handle(isolate, mixin_class.super_type()).arguments());
1920 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); 1928 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate);
1921 if ((num_aliased_mixin_type_params > 0) && 1929 if ((num_aliased_mixin_type_params > 0) &&
1922 !mixin_class_super_type_args.IsNull()) { 1930 !mixin_class_super_type_args.IsNull()) {
1923 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); 1931 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
1932 AbstractType& bounded_type = AbstractType::Handle(isolate);
1933 AbstractType& upper_bound = AbstractType::Handle(isolate);
1934 TypeParameter& type_parameter = TypeParameter::Handle(isolate);
1935 Error& bound_error = Error::Handle(isolate);
1936 const intptr_t offset =
1937 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params;
1924 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { 1938 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1925 type = mixin_class_super_type_args.TypeAt(offset + i); 1939 type = mixin_class_super_type_args.TypeAt(offset + i);
1940 if (!type.IsInstantiated()) {
1941 // In the presence of bounds, the bounded type and the upper bound must
1942 // be instantiated separately. Instantiating a BoundedType would wrap
1943 // the BoundedType in another BoundedType.
1944 if (type.IsBoundedType()) {
1945 bounded_type = BoundedType::Cast(type).type();
1946 bounded_type = bounded_type.InstantiateFrom(instantiator,
1947 &bound_error);
1948 // The instantiator contains only TypeParameter objects and no
1949 // BoundedType objects, so no bound error may occur.
1950 ASSERT(bound_error.IsNull());
1951 upper_bound = BoundedType::Cast(type).bound();
1952 upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error);
1953 ASSERT(bound_error.IsNull());
1954 type_parameter = BoundedType::Cast(type).type_parameter();
1955 // The type parameter that declared the bound does not change.
1956 type = BoundedType::New(bounded_type, upper_bound, type_parameter);
1957 } else {
1958 type = type.InstantiateFrom(instantiator, &bound_error);
1959 ASSERT(bound_error.IsNull());
1960 }
1961 }
1926 new_mixin_type_args.SetTypeAt(i, type); 1962 new_mixin_type_args.SetTypeAt(i, type);
1927 } 1963 }
1928 } 1964 }
1929 if (!new_mixin_type_args.IsNull() &&
1930 !new_mixin_type_args.IsInstantiated()) {
1931 Error& bound_error = Error::Handle(isolate);
1932 new_mixin_type_args ^=
1933 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
1934 // The instantiator contains only TypeParameter objects and no BoundedType
1935 // objects, so no bound error may occur.
1936 ASSERT(bound_error.IsNull());
1937 }
1938 TypeArguments& new_super_type_args = TypeArguments::Handle(isolate); 1965 TypeArguments& new_super_type_args = TypeArguments::Handle(isolate);
1939 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { 1966 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) {
1940 new_super_type_args = TypeArguments::New(num_super_type_params + 1967 new_super_type_args = TypeArguments::New(num_super_type_params +
1941 num_aliased_mixin_type_params); 1968 num_aliased_mixin_type_params);
1969 const TypeArguments& type_params =
1970 TypeArguments::Handle(isolate, mixin_app_class.type_parameters());
1942 for (intptr_t i = 0; i < num_super_type_params; i++) { 1971 for (intptr_t i = 0; i < num_super_type_params; i++) {
1943 type = type_params.TypeAt(i); 1972 type = type_params.TypeAt(i);
1944 new_super_type_args.SetTypeAt(i, type); 1973 new_super_type_args.SetTypeAt(i, type);
1945 } 1974 }
1946 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { 1975 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1947 if (new_mixin_type_args.IsNull()) { 1976 if (new_mixin_type_args.IsNull()) {
1948 type = Type::DynamicType(); 1977 type = Type::DynamicType();
1949 } else { 1978 } else {
1950 type = new_mixin_type_args.TypeAt(i); 1979 type = new_mixin_type_args.TypeAt(i);
1951 } 1980 }
1952 new_super_type_args.SetTypeAt(num_super_type_params + i, type); 1981 new_super_type_args.SetTypeAt(num_super_type_params + i, type);
1953 } 1982 }
1954 } 1983 }
1955 super_type = Type::New(inserted_class, 1984 super_type = Type::New(inserted_class,
1956 new_super_type_args, 1985 new_super_type_args,
1957 mixin_app_class.token_pos()); 1986 mixin_app_class.token_pos());
1958 mixin_app_class.set_super_type(super_type); 1987 mixin_app_class.set_super_type(super_type);
1959 1988
1960 // Perform the bound adjustment posponed from CloneMixinAppTypeParameters.
1961 if (has_uninstantiated_bounds) {
1962 TypeParameter& param = TypeParameter::Handle(isolate);
1963 AbstractType& param_bound = AbstractType::Handle(isolate);
1964 Error& bound_error = Error::Handle(isolate);
1965 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1966 param ^= type_params.TypeAt(num_super_type_params + i);
1967 param_bound = param.bound();
1968 if (!param_bound.IsInstantiated()) {
1969 param_bound = param_bound.InstantiateFrom(instantiator, &bound_error);
1970 // The instantiator contains only TypeParameter objects and no
1971 // BoundedType objects, so no bound error may occur.
1972 ASSERT(bound_error.IsNull());
1973 ASSERT(!param_bound.IsInstantiated());
1974 param.set_bound(param_bound);
1975 }
1976 }
1977 }
1978
1979 // Mark this mixin application class as being an alias. 1989 // Mark this mixin application class as being an alias.
1980 mixin_app_class.set_is_mixin_app_alias(); 1990 mixin_app_class.set_is_mixin_app_alias();
1981 ASSERT(!mixin_app_class.is_type_finalized()); 1991 ASSERT(!mixin_app_class.is_type_finalized());
1982 ASSERT(!mixin_app_class.is_mixin_type_applied()); 1992 ASSERT(!mixin_app_class.is_mixin_type_applied());
1983 if (FLAG_trace_class_finalization) { 1993 if (FLAG_trace_class_finalization) {
1984 OS::Print("Inserting class %s to mixin application alias %s " 1994 OS::Print("Inserting class '%s' %s\n"
1985 "with super type '%s'\n", 1995 " as super type '%s' with %" Pd " type args: %s\n"
1986 inserted_class.ToCString(), 1996 " of mixin application alias '%s' %s\n",
1987 mixin_app_class.ToCString(), 1997 String::Handle(inserted_class.Name()).ToCString(),
1988 String::Handle(isolate, super_type.Name()).ToCString()); 1998 TypeArguments::Handle(
1999 inserted_class.type_parameters()).ToCString(),
2000 String::Handle(isolate, super_type.Name()).ToCString(),
2001 num_super_type_params + num_aliased_mixin_type_params,
2002 super_type.ToCString(),
2003 String::Handle(mixin_app_class.Name()).ToCString(),
2004 TypeArguments::Handle(
2005 mixin_app_class.type_parameters()).ToCString());
1989 } 2006 }
1990 } 2007 }
1991 2008
1992 2009
1993 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, 2010 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class,
1994 GrowableObjectArray* pending_types) { 2011 GrowableObjectArray* pending_types) {
1995 if (mixin_app_class.is_mixin_type_applied()) { 2012 if (mixin_app_class.is_mixin_type_applied()) {
1996 return; 2013 return;
1997 } 2014 }
1998 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 2015 Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1999 ASSERT(!mixin_type.IsNull()); 2016 ASSERT(!mixin_type.IsNull());
2000 ASSERT(mixin_type.HasResolvedTypeClass()); 2017 ASSERT(mixin_type.HasResolvedTypeClass());
2001 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 2018 const Class& mixin_class = Class::Handle(mixin_type.type_class());
2002 2019
2003 if (FLAG_trace_class_finalization) { 2020 if (FLAG_trace_class_finalization) {
2004 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", 2021 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
2005 String::Handle(mixin_type.Name()).ToCString(), 2022 String::Handle(mixin_type.Name()).ToCString(),
2006 mixin_app_class.ToCString(), 2023 mixin_app_class.ToCString(),
2007 mixin_app_class.token_pos()); 2024 mixin_app_class.token_pos());
2008 } 2025 }
2009 2026
2010 // Check for illegal self references. This has to be done before checking 2027 // Check for illegal self references.
2011 // that the super class of the mixin class is class Object.
2012 GrowableArray<intptr_t> visited_mixins; 2028 GrowableArray<intptr_t> visited_mixins;
2013 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) { 2029 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) {
2014 const String& class_name = String::Handle(mixin_class.Name()); 2030 const String& class_name = String::Handle(mixin_class.Name());
2015 ReportError(mixin_class, mixin_class.token_pos(), 2031 ReportError(mixin_class, mixin_class.token_pos(),
2016 "mixin class '%s' illegally refers to itself", 2032 "mixin class '%s' illegally refers to itself",
2017 class_name.ToCString()); 2033 class_name.ToCString());
2018 } 2034 }
2019 2035
2020 // Check that the super class of the mixin class is class Object. 2036 if (!FLAG_supermixin) {
2021 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass()); 2037 // Check that the super class of the mixin class is class Object.
2022 // Skip over mixin application alias classes, which are implemented as 2038 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass());
2023 // subclasses of the mixin application classes they name. 2039 // Skip over mixin application alias classes, which are implemented as
2024 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_app_alias()) { 2040 // subclasses of the mixin application classes they name.
2025 while (mixin_super_class.is_mixin_app_alias()) { 2041 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_app_alias()) {
2042 while (mixin_super_class.is_mixin_app_alias()) {
2043 mixin_super_class = mixin_super_class.SuperClass();
2044 }
2026 mixin_super_class = mixin_super_class.SuperClass(); 2045 mixin_super_class = mixin_super_class.SuperClass();
2027 } 2046 }
2028 mixin_super_class = mixin_super_class.SuperClass(); 2047 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) {
2029 } 2048 const String& class_name = String::Handle(mixin_class.Name());
2030 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) { 2049 ReportError(mixin_app_class, mixin_app_class.token_pos(),
2031 const String& class_name = String::Handle(mixin_class.Name()); 2050 "mixin class '%s' must extend class 'Object'",
2032 ReportError(mixin_app_class, mixin_app_class.token_pos(), 2051 class_name.ToCString());
2033 "mixin class '%s' must extend class 'Object'", 2052 }
2034 class_name.ToCString());
2035 } 2053 }
2036 2054
2037 // Copy type parameters to mixin application class. 2055 // Copy type parameters to mixin application class.
2038 CloneMixinAppTypeParameters(mixin_app_class); 2056 CloneMixinAppTypeParameters(mixin_app_class);
2039 2057
2040 // Verify that no restricted class is used as a mixin by checking the 2058 // Verify that no restricted class is used as a mixin by checking the
2041 // interfaces of the mixin application class, which implements its mixin. 2059 // interfaces of the mixin application class, which implements its mixin.
2042 GrowableArray<intptr_t> visited_interfaces; 2060 GrowableArray<intptr_t> visited_interfaces;
2043 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); 2061 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces);
2044 2062
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 AbstractType& interface_type = AbstractType::Handle(); 2308 AbstractType& interface_type = AbstractType::Handle();
2291 AbstractType& seen_interf = AbstractType::Handle(); 2309 AbstractType& seen_interf = AbstractType::Handle();
2292 for (intptr_t i = 0; i < interface_types.Length(); i++) { 2310 for (intptr_t i = 0; i < interface_types.Length(); i++) {
2293 interface_type ^= interface_types.At(i); 2311 interface_type ^= interface_types.At(i);
2294 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 2312 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
2295 interface_types.SetAt(i, interface_type); 2313 interface_types.SetAt(i, interface_type);
2296 2314
2297 // Check whether the interface is duplicated. We need to wait with 2315 // Check whether the interface is duplicated. We need to wait with
2298 // this check until the super type and interface types are finalized, 2316 // this check until the super type and interface types are finalized,
2299 // so that we can use Type::Equals() for the test. 2317 // so that we can use Type::Equals() for the test.
2318 // TODO(regis): This restriction about duplicated interfaces may get lifted.
2300 ASSERT(interface_type.IsFinalized()); 2319 ASSERT(interface_type.IsFinalized());
2301 ASSERT(super_type.IsNull() || super_type.IsFinalized()); 2320 ASSERT(super_type.IsNull() || super_type.IsFinalized());
2302 if (!super_type.IsNull() && interface_type.Equals(super_type)) { 2321 if (!super_type.IsNull() && interface_type.Equals(super_type)) {
2303 ReportError(cls, cls.token_pos(), 2322 ReportError(cls, cls.token_pos(),
2304 "super type '%s' may not be listed in " 2323 "super type '%s' may not be listed in "
2305 "implements clause of class '%s'", 2324 "implements clause of class '%s'",
2306 String::Handle(super_type.Name()).ToCString(), 2325 String::Handle(super_type.Name()).ToCString(),
2307 String::Handle(cls.Name()).ToCString()); 2326 String::Handle(cls.Name()).ToCString());
2308 } 2327 }
2309 for (intptr_t j = 0; j < i; j++) { 2328 for (intptr_t j = 0; j < i; j++) {
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2636 const GrowableObjectArray& type_args = 2655 const GrowableObjectArray& type_args =
2637 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 2656 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
2638 AbstractType& mixin_super_type = 2657 AbstractType& mixin_super_type =
2639 AbstractType::Handle(isolate, mixin_app_type.super_type()); 2658 AbstractType::Handle(isolate, mixin_app_type.super_type());
2640 ResolveType(cls, mixin_super_type); 2659 ResolveType(cls, mixin_super_type);
2641 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. 2660 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed.
2642 // The super type may have a BoundedType as type argument, but cannot be 2661 // The super type may have a BoundedType as type argument, but cannot be
2643 // a BoundedType itself. 2662 // a BoundedType itself.
2644 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); 2663 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
2645 AbstractType& mixin_type = AbstractType::Handle(isolate); 2664 AbstractType& mixin_type = AbstractType::Handle(isolate);
2646 Type& generic_mixin_type = Type::Handle(isolate);
2647 Class& mixin_type_class = Class::Handle(isolate); 2665 Class& mixin_type_class = Class::Handle(isolate);
2648 Class& mixin_app_class = Class::Handle(isolate); 2666 Class& mixin_app_class = Class::Handle(isolate);
2649 String& mixin_app_class_name = String::Handle(isolate); 2667 String& mixin_app_class_name = String::Handle(isolate);
2650 String& mixin_type_class_name = String::Handle(isolate); 2668 String& mixin_type_class_name = String::Handle(isolate);
2651 AbstractType& super_type_arg = AbstractType::Handle(isolate); 2669 AbstractType& super_type_arg = AbstractType::Handle(isolate);
2652 AbstractType& mixin_type_arg = AbstractType::Handle(isolate); 2670 AbstractType& mixin_type_arg = AbstractType::Handle(isolate);
2653 const intptr_t depth = mixin_app_type.Depth(); 2671 const intptr_t depth = mixin_app_type.Depth();
2654 for (intptr_t i = 0; i < depth; i++) { 2672 for (intptr_t i = 0; i < depth; i++) {
2655 mixin_type = mixin_app_type.MixinTypeAt(i); 2673 mixin_type = mixin_app_type.MixinTypeAt(i);
2656 ASSERT(!mixin_type.IsNull()); 2674 ASSERT(!mixin_type.IsNull());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2697 mixin_app_class_name = String::Concat(mixin_app_class_name, 2715 mixin_app_class_name = String::Concat(mixin_app_class_name,
2698 mixin_type_class_name); 2716 mixin_type_class_name);
2699 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); 2717 mixin_app_class = library.LookupLocalClass(mixin_app_class_name);
2700 if (mixin_app_class.IsNull()) { 2718 if (mixin_app_class.IsNull()) {
2701 mixin_app_class_name = Symbols::New(mixin_app_class_name); 2719 mixin_app_class_name = Symbols::New(mixin_app_class_name);
2702 mixin_app_class = Class::New(mixin_app_class_name, 2720 mixin_app_class = Class::New(mixin_app_class_name,
2703 script, 2721 script,
2704 mixin_type.token_pos()); 2722 mixin_type.token_pos());
2705 mixin_app_class.set_super_type(mixin_super_type); 2723 mixin_app_class.set_super_type(mixin_super_type);
2706 mixin_type_class = mixin_type.type_class(); 2724 mixin_type_class = mixin_type.type_class();
2707 generic_mixin_type = Type::New(mixin_type_class, 2725 const Type& generic_mixin_type = Type::Handle(isolate,
2708 Object::null_type_arguments(), 2726 Type::New(mixin_type_class,
2709 mixin_type.token_pos()); 2727 Object::null_type_arguments(),
2728 mixin_type.token_pos()));
2710 mixin_app_class.set_mixin(generic_mixin_type); 2729 mixin_app_class.set_mixin(generic_mixin_type);
2711 // Add the mixin type to the list of interfaces that the mixin application 2730 // Add the mixin type to the list of interfaces that the mixin application
2712 // class implements. This is necessary so that cycle check work at 2731 // class implements. This is necessary so that cycle check work at
2713 // compile time (type arguments are ignored by that check). 2732 // compile time (type arguments are ignored by that check).
2714 const Array& interfaces = Array::Handle(isolate, Array::New(1)); 2733 const Array& interfaces = Array::Handle(isolate, Array::New(1));
2715 interfaces.SetAt(0, generic_mixin_type); 2734 interfaces.SetAt(0, generic_mixin_type);
2716 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); 2735 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
2717 mixin_app_class.set_interfaces(interfaces); 2736 mixin_app_class.set_interfaces(interfaces);
2718 mixin_app_class.set_is_synthesized_class(); 2737 mixin_app_class.set_is_synthesized_class();
2719 library.AddClass(mixin_app_class); 2738 library.AddClass(mixin_app_class);
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3219 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3201 field ^= fields_array.At(0); 3220 field ^= fields_array.At(0);
3202 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3221 ASSERT(field.Offset() == ByteBuffer::data_offset());
3203 name ^= field.name(); 3222 name ^= field.name();
3204 expected_name ^= String::New("_data"); 3223 expected_name ^= String::New("_data");
3205 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3224 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3206 #endif 3225 #endif
3207 } 3226 }
3208 3227
3209 } // namespace dart 3228 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698