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 |