| 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 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 | 1479 |
| 1480 // Lastly, set the type arguments of the mixin type and of the single | 1480 // Lastly, set the type arguments of the mixin type and of the single |
| 1481 // interface type. | 1481 // interface type. |
| 1482 ASSERT(!mixin_type.IsFinalized()); | 1482 ASSERT(!mixin_type.IsFinalized()); |
| 1483 mixin_type.set_arguments(mixin_type_args); | 1483 mixin_type.set_arguments(mixin_type_args); |
| 1484 ASSERT(!interface.IsFinalized()); | 1484 ASSERT(!interface.IsFinalized()); |
| 1485 interface.set_arguments(interface_type_args); | 1485 interface.set_arguments(interface_type_args); |
| 1486 } | 1486 } |
| 1487 mixin_app_class.set_type_parameters(cloned_type_params); | 1487 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1488 } | 1488 } |
| 1489 // If the mixin class is a mixin application typedef class, we insert a new | 1489 // If the mixin class is a mixin application alias class, we insert a new |
| 1490 // synthesized mixin application class in the super chain of this mixin | 1490 // synthesized mixin application class in the super chain of this mixin |
| 1491 // application class. The new class will have the aliased mixin as actual | 1491 // application class. The new class will have the aliased mixin as actual |
| 1492 // mixin. | 1492 // mixin. |
| 1493 if (mixin_class.is_mixin_typedef()) { | 1493 if (mixin_class.is_mixin_app_alias()) { |
| 1494 ApplyMixinTypedef(mixin_app_class); | 1494 ApplyMixinAppAlias(mixin_app_class); |
| 1495 } | 1495 } |
| 1496 } | 1496 } |
| 1497 | 1497 |
| 1498 | 1498 |
| 1499 /* Support for mixin typedef. | 1499 /* Support for mixin alias. |
| 1500 Consider the following example: | 1500 Consider the following example: |
| 1501 | 1501 |
| 1502 class I<T> { } | 1502 class I<T> { } |
| 1503 class J<T> { } | 1503 class J<T> { } |
| 1504 class S<T> { } | 1504 class S<T> { } |
| 1505 class M<T> { } | 1505 class M<T> { } |
| 1506 class A<U, V> = Object with M<Map<U, V>> implements I<V>; | 1506 class A<U, V> = Object with M<Map<U, V>> implements I<V>; |
| 1507 class C<T, K> = S<T> with A<T, List<K>> implements J<K>; | 1507 class C<T, K> = S<T> with A<T, List<K>> implements J<K>; |
| 1508 | 1508 |
| 1509 Before the call to ApplyMixinTypedef, the VM has already synthesized 2 mixin | 1509 Before the call to ApplyMixinAppAlias, the VM has already synthesized 2 mixin |
| 1510 application classes Object&M and S&A: | 1510 application classes Object&M and S&A: |
| 1511 | 1511 |
| 1512 Object&M<T> extends Object implements M<T> { ... members of M applied here ... } | 1512 Object&M<T> extends Object implements M<T> { ... members of M applied here ... } |
| 1513 A<U, V> extends Object&M<Map<U, V>> implements I<V> { } | 1513 A<U, V> extends Object&M<Map<U, V>> implements I<V> { } |
| 1514 | 1514 |
| 1515 S&A<T`, U, V> extends S<T`> implements A<U, V> { } | 1515 S&A<T`, U, V> extends S<T`> implements A<U, V> { } |
| 1516 C<T, K> extends S&A<T, T, List<K>> implements J<K> { } | 1516 C<T, K> extends S&A<T, T, List<K>> implements J<K> { } |
| 1517 | 1517 |
| 1518 In theory, class A should be an alias of Object&M instead of extending it. | 1518 In theory, class A should be an alias of Object&M instead of extending it. |
| 1519 In practice, the additional class provides a hook for implemented interfaces | 1519 In practice, the additional class provides a hook for implemented interfaces |
| 1520 (e.g. I<V>) and for type argument substitution via the super type relation (e.g. | 1520 (e.g. I<V>) and for type argument substitution via the super type relation (e.g. |
| 1521 type parameter T of Object&M is substituted with Map<U, V>, U and V being the | 1521 type parameter T of Object&M is substituted with Map<U, V>, U and V being the |
| 1522 type parameters of the typedef A). | 1522 type parameters of the alias A). |
| 1523 | 1523 |
| 1524 Similarly, class C should be an alias of S&A instead of extending it. | 1524 Similarly, class C should be an alias of S&A instead of extending it. |
| 1525 | 1525 |
| 1526 Since A is used as a mixin, it must extend Object. The fact that it extends | 1526 Since A is used as a mixin, it must extend Object. The fact that it extends |
| 1527 Object&M must be hidden so that no error is wrongly reported. | 1527 Object&M must be hidden so that no error is wrongly reported. |
| 1528 | 1528 |
| 1529 Now, A does not have any members to be mixed into S&A, because A is a typedef. | 1529 Now, A does not have any members to be mixed into S&A, because A is an alias. |
| 1530 The members to be mixed in are actually those of M, and they should appear in a | 1530 The members to be mixed in are actually those of M, and they should appear in a |
| 1531 scope where the type parameter T is visible. The class S&A declares the type | 1531 scope where the type parameter T is visible. The class S&A declares the type |
| 1532 parameters of A, i.e. U and V, but not T. | 1532 parameters of A, i.e. U and V, but not T. |
| 1533 | 1533 |
| 1534 Therefore, the call to ApplyMixinTypedef inserts another synthesized class S&A` | 1534 Therefore, the call to ApplyMixinAppAlias inserts another synthesized class S&A` |
| 1535 as the superclass of S&A. The class S&A` declares a type argument T: | 1535 as the superclass of S&A. The class S&A` declares a type argument T: |
| 1536 | 1536 |
| 1537 Instead of | 1537 Instead of |
| 1538 S&A<T`, U, V> extends S<T`> implements A<U, V> { } | 1538 S&A<T`, U, V> extends S<T`> implements A<U, V> { } |
| 1539 | 1539 |
| 1540 We now have: | 1540 We now have: |
| 1541 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } | 1541 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } |
| 1542 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } | 1542 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } |
| 1543 | 1543 |
| 1544 The main implementation difficulty resides in the fact that the type parameters | 1544 The main implementation difficulty resides in the fact that the type parameters |
| 1545 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type | 1545 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type |
| 1546 parameters U and V of S&A. However, Map<U, V> is copied from the super type | 1546 parameters U and V of S&A. However, Map<U, V> is copied from the super type |
| 1547 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation | 1547 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation |
| 1548 step with a properly crafted instantiator vector takes care of the required type | 1548 step with a properly crafted instantiator vector takes care of the required type |
| 1549 parameter substitution. | 1549 parameter substitution. |
| 1550 | 1550 |
| 1551 The instantiator vector must end with the type parameters U and V of S&A. | 1551 The instantiator vector must end with the type parameters U and V of S&A. |
| 1552 The offset of the first type parameter U of S&A must be at the finalized index | 1552 The offset of the first type parameter U of S&A must be at the finalized index |
| 1553 of type parameter U of A. | 1553 of type parameter U of A. |
| 1554 */ | 1554 */ |
| 1555 // TODO(regis): The syntax does not use 'typedef' anymore. Rename to 'alias'? | 1555 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class) { |
| 1556 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { | 1556 // If this mixin alias is aliasing another mixin alias, another class |
| 1557 // If this mixin typedef is aliasing another mixin typedef, another class | |
| 1558 // will be inserted via recursion. No need to check here. | 1557 // will be inserted via recursion. No need to check here. |
| 1559 // The mixin type may or may not be finalized yet. | 1558 // The mixin type may or may not be finalized yet. |
| 1560 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); | 1559 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); |
| 1561 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1560 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1562 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1561 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1563 ASSERT(mixin_class.is_mixin_typedef()); | 1562 ASSERT(mixin_class.is_mixin_app_alias()); |
| 1564 const Class& aliased_mixin_app_class = Class::Handle( | 1563 const Class& aliased_mixin_app_class = Class::Handle( |
| 1565 mixin_class.SuperClass()); | 1564 mixin_class.SuperClass()); |
| 1566 const Type& aliased_mixin_type = Type::Handle( | 1565 const Type& aliased_mixin_type = Type::Handle( |
| 1567 aliased_mixin_app_class.mixin()); | 1566 aliased_mixin_app_class.mixin()); |
| 1568 // The name of the inserted mixin application class is the name of mixin | 1567 // The name of the inserted mixin application class is the name of mixin |
| 1569 // class name with a backtick added. | 1568 // class name with a backtick added. |
| 1570 String& inserted_class_name = String::Handle(mixin_app_class.Name()); | 1569 String& inserted_class_name = String::Handle(mixin_app_class.Name()); |
| 1571 inserted_class_name = String::Concat(inserted_class_name, | 1570 inserted_class_name = String::Concat(inserted_class_name, |
| 1572 Symbols::Backtick()); | 1571 Symbols::Backtick()); |
| 1573 const Library& library = Library::Handle(mixin_app_class.library()); | 1572 const Library& library = Library::Handle(mixin_app_class.library()); |
| 1574 Class& inserted_class = Class::Handle( | 1573 Class& inserted_class = Class::Handle( |
| 1575 library.LookupLocalClass(inserted_class_name)); | 1574 library.LookupLocalClass(inserted_class_name)); |
| 1576 if (inserted_class.IsNull()) { | 1575 if (inserted_class.IsNull()) { |
| 1577 inserted_class_name = Symbols::New(inserted_class_name); | 1576 inserted_class_name = Symbols::New(inserted_class_name); |
| 1578 const Script& script = Script::Handle(mixin_app_class.script()); | 1577 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1579 inserted_class = Class::New( | 1578 inserted_class = Class::New( |
| 1580 inserted_class_name, script, mixin_app_class.token_pos()); | 1579 inserted_class_name, script, mixin_app_class.token_pos()); |
| 1581 inserted_class.set_is_synthesized_class(); | 1580 inserted_class.set_is_synthesized_class(); |
| 1582 library.AddClass(inserted_class); | 1581 library.AddClass(inserted_class); |
| 1583 | 1582 |
| 1584 if (FLAG_trace_class_finalization) { | 1583 if (FLAG_trace_class_finalization) { |
| 1585 OS::Print("Creating mixin typedef application %s\n", | 1584 OS::Print("Creating mixin application alias %s\n", |
| 1586 inserted_class.ToCString()); | 1585 inserted_class.ToCString()); |
| 1587 } | 1586 } |
| 1588 | 1587 |
| 1589 // The super type of the inserted class is identical to the super type of | 1588 // The super type of the inserted class is identical to the super type of |
| 1590 // this mixin application class, except that it must refer to the type | 1589 // this mixin application class, except that it must refer to the type |
| 1591 // parameters of the inserted class rather than to those of the mixin | 1590 // parameters of the inserted class rather than to those of the mixin |
| 1592 // application class. | 1591 // application class. |
| 1593 // The type arguments of the super type will be set properly when calling | 1592 // The type arguments of the super type will be set properly when calling |
| 1594 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1593 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
| 1595 // type class is set properly. | 1594 // type class is set properly. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1608 } | 1607 } |
| 1609 | 1608 |
| 1610 // Finalize the types and call CloneMixinAppTypeParameters. | 1609 // Finalize the types and call CloneMixinAppTypeParameters. |
| 1611 FinalizeTypesInClass(inserted_class); | 1610 FinalizeTypesInClass(inserted_class); |
| 1612 | 1611 |
| 1613 // The super type of this mixin application class must point to the | 1612 // The super type of this mixin application class must point to the |
| 1614 // inserted class. The super type arguments are the concatenation of the | 1613 // inserted class. The super type arguments are the concatenation of the |
| 1615 // old super type arguments (propagating type arguments to the super class) | 1614 // old super type arguments (propagating type arguments to the super class) |
| 1616 // with new type arguments providing type arguments to the mixin. | 1615 // with new type arguments providing type arguments to the mixin. |
| 1617 // The appended type arguments are those of the super type of the mixin | 1616 // The appended type arguments are those of the super type of the mixin |
| 1618 // typedef that are forwarding to the aliased mixin type, except | 1617 // application alias that are forwarding to the aliased mixin type, except |
| 1619 // that they must refer to the type parameters of the mixin application | 1618 // that they must refer to the type parameters of the mixin application |
| 1620 // class rather than to those of the mixin typedef class. | 1619 // class rather than to those of the mixin application alias class. |
| 1621 // This type parameter substitution is performed by an instantiation step. | 1620 // This type parameter substitution is performed by an instantiation step. |
| 1622 // It is important that the type parameters of the mixin application class | 1621 // It is important that the type parameters of the mixin application class |
| 1623 // are not finalized yet, because new type parameters may have been added | 1622 // are not finalized yet, because new type parameters may have been added |
| 1624 // to the super class. | 1623 // to the super class. |
| 1625 Class& super_class = Class::Handle(super_type.type_class()); | 1624 Class& super_class = Class::Handle(super_type.type_class()); |
| 1626 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); | 1625 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); |
| 1627 while (super_class.IsMixinApplication()) { | 1626 while (super_class.IsMixinApplication()) { |
| 1628 super_class = super_class.SuperClass(); | 1627 super_class = super_class.SuperClass(); |
| 1629 } | 1628 } |
| 1630 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1629 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 } else { | 1684 } else { |
| 1686 type = new_mixin_type_args.TypeAt(i); | 1685 type = new_mixin_type_args.TypeAt(i); |
| 1687 } | 1686 } |
| 1688 new_super_type_args.SetTypeAt(num_super_type_params + i, type); | 1687 new_super_type_args.SetTypeAt(num_super_type_params + i, type); |
| 1689 } | 1688 } |
| 1690 } | 1689 } |
| 1691 super_type = Type::New(inserted_class, | 1690 super_type = Type::New(inserted_class, |
| 1692 new_super_type_args, | 1691 new_super_type_args, |
| 1693 mixin_app_class.token_pos()); | 1692 mixin_app_class.token_pos()); |
| 1694 mixin_app_class.set_super_type(super_type); | 1693 mixin_app_class.set_super_type(super_type); |
| 1695 // Mark this mixin application class as being a typedef. | 1694 // Mark this mixin application class as being an alias. |
| 1696 mixin_app_class.set_is_mixin_typedef(); | 1695 mixin_app_class.set_is_mixin_app_alias(); |
| 1697 ASSERT(!mixin_app_class.is_type_finalized()); | 1696 ASSERT(!mixin_app_class.is_type_finalized()); |
| 1698 ASSERT(!mixin_app_class.is_mixin_type_applied()); | 1697 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
| 1699 if (FLAG_trace_class_finalization) { | 1698 if (FLAG_trace_class_finalization) { |
| 1700 OS::Print("Inserting class %s to mixin typedef application %s " | 1699 OS::Print("Inserting class %s to mixin application alias %s " |
| 1701 "with super type '%s'\n", | 1700 "with super type '%s'\n", |
| 1702 inserted_class.ToCString(), | 1701 inserted_class.ToCString(), |
| 1703 mixin_app_class.ToCString(), | 1702 mixin_app_class.ToCString(), |
| 1704 String::Handle(super_type.Name()).ToCString()); | 1703 String::Handle(super_type.Name()).ToCString()); |
| 1705 } | 1704 } |
| 1706 } | 1705 } |
| 1707 | 1706 |
| 1708 | 1707 |
| 1709 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) { | 1708 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) { |
| 1710 if (mixin_app_class.is_mixin_type_applied()) { | 1709 if (mixin_app_class.is_mixin_type_applied()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1729 const Script& script = Script::Handle(mixin_class.script()); | 1728 const Script& script = Script::Handle(mixin_class.script()); |
| 1730 const String& class_name = String::Handle(mixin_class.Name()); | 1729 const String& class_name = String::Handle(mixin_class.Name()); |
| 1731 ReportError(Error::Handle(), // No previous error. | 1730 ReportError(Error::Handle(), // No previous error. |
| 1732 script, mixin_class.token_pos(), | 1731 script, mixin_class.token_pos(), |
| 1733 "mixin class '%s' illegally refers to itself", | 1732 "mixin class '%s' illegally refers to itself", |
| 1734 class_name.ToCString()); | 1733 class_name.ToCString()); |
| 1735 } | 1734 } |
| 1736 | 1735 |
| 1737 // Check that the super class of the mixin class is class Object. | 1736 // Check that the super class of the mixin class is class Object. |
| 1738 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass()); | 1737 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass()); |
| 1739 // Skip over mixin application typedef classes, which are aliases (but are | 1738 // Skip over mixin application alias classes, which are implemented as |
| 1740 // implemented as subclasses) of the mixin application classes they name. | 1739 // subclasses of the mixin application classes they name. |
| 1741 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_typedef()) { | 1740 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_app_alias()) { |
| 1742 while (mixin_super_class.is_mixin_typedef()) { | 1741 while (mixin_super_class.is_mixin_app_alias()) { |
| 1743 mixin_super_class = mixin_super_class.SuperClass(); | 1742 mixin_super_class = mixin_super_class.SuperClass(); |
| 1744 } | 1743 } |
| 1745 mixin_super_class = mixin_super_class.SuperClass(); | 1744 mixin_super_class = mixin_super_class.SuperClass(); |
| 1746 } | 1745 } |
| 1747 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) { | 1746 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) { |
| 1748 const Script& script = Script::Handle(mixin_app_class.script()); | 1747 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1749 const String& class_name = String::Handle(mixin_class.Name()); | 1748 const String& class_name = String::Handle(mixin_class.Name()); |
| 1750 ReportError(Error::Handle(), // No previous error. | 1749 ReportError(Error::Handle(), // No previous error. |
| 1751 script, mixin_app_class.token_pos(), | 1750 script, mixin_app_class.token_pos(), |
| 1752 "mixin class '%s' must extend class 'Object'", | 1751 "mixin class '%s' must extend class 'Object'", |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1766 String::Handle(mixin_type.Name()).ToCString(), | 1765 String::Handle(mixin_type.Name()).ToCString(), |
| 1767 String::Handle(mixin_app_class.Name()).ToCString(), | 1766 String::Handle(mixin_app_class.Name()).ToCString(), |
| 1768 TypeArguments::Handle( | 1767 TypeArguments::Handle( |
| 1769 mixin_app_class.type_parameters()).ToCString(), | 1768 mixin_app_class.type_parameters()).ToCString(), |
| 1770 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | 1769 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); |
| 1771 } | 1770 } |
| 1772 // Mark the application class as having been applied its mixin type in order | 1771 // Mark the application class as having been applied its mixin type in order |
| 1773 // to avoid cycles while finalizing its mixin type. | 1772 // to avoid cycles while finalizing its mixin type. |
| 1774 mixin_app_class.set_is_mixin_type_applied(); | 1773 mixin_app_class.set_is_mixin_type_applied(); |
| 1775 // Finalize the mixin type, which may have been changed in case | 1774 // Finalize the mixin type, which may have been changed in case |
| 1776 // mixin_app_class is a typedef. | 1775 // mixin_app_class is an alias. |
| 1777 mixin_type = mixin_app_class.mixin(); | 1776 mixin_type = mixin_app_class.mixin(); |
| 1778 ASSERT(!mixin_type.IsBeingFinalized()); | 1777 ASSERT(!mixin_type.IsBeingFinalized()); |
| 1779 mixin_type ^= | 1778 mixin_type ^= |
| 1780 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); | 1779 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); |
| 1781 // TODO(14453): Check for a malbounded mixin_type. | 1780 // TODO(14453): Check for a malbounded mixin_type. |
| 1782 mixin_app_class.set_mixin(mixin_type); | 1781 mixin_app_class.set_mixin(mixin_type); |
| 1783 } | 1782 } |
| 1784 | 1783 |
| 1785 | 1784 |
| 1786 void ClassFinalizer::CreateForwardingConstructors( | 1785 void ClassFinalizer::CreateForwardingConstructors( |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 } | 1840 } |
| 1842 | 1841 |
| 1843 | 1842 |
| 1844 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { | 1843 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { |
| 1845 Isolate* isolate = Isolate::Current(); | 1844 Isolate* isolate = Isolate::Current(); |
| 1846 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); | 1845 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); |
| 1847 ASSERT(!mixin_type.IsNull()); | 1846 ASSERT(!mixin_type.IsNull()); |
| 1848 ASSERT(mixin_type.HasResolvedTypeClass()); | 1847 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 1849 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); | 1848 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); |
| 1850 mixin_cls.EnsureIsFinalized(isolate); | 1849 mixin_cls.EnsureIsFinalized(isolate); |
| 1851 // If the mixin is a mixin application typedef class, there are no members to | 1850 // If the mixin is a mixin application alias class, there are no members to |
| 1852 // apply here. A new synthesized class representing the aliased mixin | 1851 // apply here. A new synthesized class representing the aliased mixin |
| 1853 // application class was inserted in the super chain of this mixin application | 1852 // application class was inserted in the super chain of this mixin application |
| 1854 // class. Members of the actual mixin class will be applied when visiting | 1853 // class. Members of the actual mixin class will be applied when visiting |
| 1855 // the mixin application class referring to the actual mixin. | 1854 // the mixin application class referring to the actual mixin. |
| 1856 ASSERT(!mixin_cls.is_mixin_typedef() || | 1855 ASSERT(!mixin_cls.is_mixin_app_alias() || |
| 1857 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); | 1856 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); |
| 1858 // A default constructor will be created for the typedef class. | 1857 // A default constructor will be created for the mixin app alias class. |
| 1859 | 1858 |
| 1860 if (FLAG_trace_class_finalization) { | 1859 if (FLAG_trace_class_finalization) { |
| 1861 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n", | 1860 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n", |
| 1862 mixin_cls.ToCString(), | 1861 mixin_cls.ToCString(), |
| 1863 cls.ToCString(), | 1862 cls.ToCString(), |
| 1864 cls.token_pos()); | 1863 cls.token_pos()); |
| 1865 } | 1864 } |
| 1866 | 1865 |
| 1867 const GrowableObjectArray& cloned_funcs = | 1866 const GrowableObjectArray& cloned_funcs = |
| 1868 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 1867 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2062 // the class conflict with inherited methods. | 2061 // the class conflict with inherited methods. |
| 2063 ApplyMixinMembers(cls); | 2062 ApplyMixinMembers(cls); |
| 2064 } | 2063 } |
| 2065 // Ensure super class is finalized. | 2064 // Ensure super class is finalized. |
| 2066 const Class& super = Class::Handle(cls.SuperClass()); | 2065 const Class& super = Class::Handle(cls.SuperClass()); |
| 2067 if (!super.IsNull()) { | 2066 if (!super.IsNull()) { |
| 2068 FinalizeClass(super); | 2067 FinalizeClass(super); |
| 2069 } | 2068 } |
| 2070 // Mark as parsed and finalized. | 2069 // Mark as parsed and finalized. |
| 2071 cls.Finalize(); | 2070 cls.Finalize(); |
| 2072 // Mixin typedef classes may still lack their forwarding constructor. | 2071 // Mixin app alias classes may still lack their forwarding constructor. |
| 2073 if (cls.is_mixin_typedef() && | 2072 if (cls.is_mixin_app_alias() && |
| 2074 (cls.functions() == Object::empty_array().raw())) { | 2073 (cls.functions() == Object::empty_array().raw())) { |
| 2075 const GrowableObjectArray& cloned_funcs = | 2074 const GrowableObjectArray& cloned_funcs = |
| 2076 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2075 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2077 CreateForwardingConstructors(cls, cloned_funcs); | 2076 CreateForwardingConstructors(cls, cloned_funcs); |
| 2078 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); | 2077 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); |
| 2079 cls.SetFunctions(functions); | 2078 cls.SetFunctions(functions); |
| 2080 } | 2079 } |
| 2081 // Every class should have at least a constructor, unless it is a top level | 2080 // Every class should have at least a constructor, unless it is a top level |
| 2082 // class or a signature class. | 2081 // class or a signature class. |
| 2083 ASSERT(cls.IsTopLevel() || | 2082 ASSERT(cls.IsTopLevel() || |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2750 expected_name ^= String::New("_offset"); | 2749 expected_name ^= String::New("_offset"); |
| 2751 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2750 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2752 field ^= fields_array.At(2); | 2751 field ^= fields_array.At(2); |
| 2753 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2752 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2754 name ^= field.name(); | 2753 name ^= field.name(); |
| 2755 ASSERT(name.Equals("length")); | 2754 ASSERT(name.Equals("length")); |
| 2756 #endif | 2755 #endif |
| 2757 } | 2756 } |
| 2758 | 2757 |
| 2759 } // namespace dart | 2758 } // namespace dart |
| OLD | NEW |