| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 // class S<T> { } | 1386 // class S<T> { } |
| 1387 // class M<T> { } | 1387 // class M<T> { } |
| 1388 // class C<E> extends S<E> with M<List<E>> { } | 1388 // class C<E> extends S<E> with M<List<E>> { } |
| 1389 // results in | 1389 // results in |
| 1390 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> | 1390 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> |
| 1391 // class C<E> extends S&M<E, List<E>> { } | 1391 // class C<E> extends S&M<E, List<E>> { } |
| 1392 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and | 1392 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and |
| 1393 // T, and use them as type arguments in S<T`> and M<T>. | 1393 // T, and use them as type arguments in S<T`> and M<T>. |
| 1394 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1394 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
| 1395 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); | 1395 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); |
| 1396 const AbstractType& super_type = AbstractType::Handle( | 1396 Isolate* isolate = Isolate::Current(); |
| 1397 const AbstractType& super_type = AbstractType::Handle(isolate, |
| 1397 mixin_app_class.super_type()); | 1398 mixin_app_class.super_type()); |
| 1398 ASSERT(super_type.IsResolved()); | 1399 ASSERT(super_type.IsResolved()); |
| 1399 const Class& super_class = Class::Handle(super_type.type_class()); | 1400 const Class& super_class = Class::Handle(isolate, super_type.type_class()); |
| 1400 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1401 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1401 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1402 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); |
| 1402 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1403 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); |
| 1403 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1404 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1404 // The mixin class cannot be Object and this was checked earlier. | 1405 // The mixin class cannot be Object and this was checked earlier. |
| 1405 ASSERT(!mixin_class.IsObjectClass()); | 1406 ASSERT(!mixin_class.IsObjectClass()); |
| 1406 | 1407 |
| 1407 // Add the mixin type to the interfaces that the mixin application | 1408 // Add the mixin type to the interfaces that the mixin application |
| 1408 // class implements. This is necessary so that type tests work. | 1409 // class implements. This is necessary so that type tests work. |
| 1409 const Array& interfaces = Array::Handle(Array::New(1)); | 1410 const Array& interfaces = Array::Handle(isolate, Array::New(1)); |
| 1410 const Type& interface = Type::Handle(Type::New( | 1411 const Type& interface = Type::Handle(isolate, Type::New( |
| 1411 mixin_class, | 1412 mixin_class, |
| 1412 Object::null_abstract_type_arguments(), // Set again below if generic. | 1413 Object::null_abstract_type_arguments(), // Set again below if generic. |
| 1413 mixin_app_class.token_pos())); | 1414 mixin_app_class.token_pos())); |
| 1414 ASSERT(!interface.IsFinalized()); | 1415 ASSERT(!interface.IsFinalized()); |
| 1415 interfaces.SetAt(0, interface); | 1416 interfaces.SetAt(0, interface); |
| 1416 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 1417 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
| 1417 mixin_app_class.set_interfaces(interfaces); | 1418 mixin_app_class.set_interfaces(interfaces); |
| 1418 | 1419 |
| 1419 // If both the super type and the mixin type are non generic, the mixin | 1420 // If both the super type and the mixin type are non generic, the mixin |
| 1420 // application class is non generic as well and we can skip type parameter | 1421 // application class is non generic as well and we can skip type parameter |
| 1421 // cloning. | 1422 // cloning. |
| 1423 bool has_uninstantiated_bounds = false; |
| 1422 if ((num_super_type_params + num_mixin_type_params) > 0) { | 1424 if ((num_super_type_params + num_mixin_type_params) > 0) { |
| 1423 // First, clone the super class type parameters. Rename them so that | 1425 // First, clone the super class type parameters. Rename them so that |
| 1424 // there can be no name conflict between the parameters of the super | 1426 // there can be no name conflict between the parameters of the super |
| 1425 // class and the mixin class. | 1427 // class and the mixin class. |
| 1426 const TypeArguments& cloned_type_params = TypeArguments::Handle( | 1428 const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate, |
| 1427 TypeArguments::New(num_super_type_params + num_mixin_type_params)); | 1429 TypeArguments::New(num_super_type_params + num_mixin_type_params)); |
| 1428 TypeParameter& param = TypeParameter::Handle(); | 1430 TypeParameter& param = TypeParameter::Handle(isolate); |
| 1429 TypeParameter& cloned_param = TypeParameter::Handle(); | 1431 TypeParameter& cloned_param = TypeParameter::Handle(isolate); |
| 1430 String& param_name = String::Handle(); | 1432 String& param_name = String::Handle(isolate); |
| 1431 AbstractType& param_bound = AbstractType::Handle(); | 1433 AbstractType& param_bound = AbstractType::Handle(isolate); |
| 1432 intptr_t cloned_index = 0; | 1434 intptr_t cloned_index = 0; |
| 1433 if (num_super_type_params > 0) { | 1435 if (num_super_type_params > 0) { |
| 1434 const TypeArguments& super_type_params = | 1436 const TypeArguments& super_type_params = |
| 1435 TypeArguments::Handle(super_class.type_parameters()); | 1437 TypeArguments::Handle(isolate, super_class.type_parameters()); |
| 1436 const TypeArguments& super_type_args = | 1438 const TypeArguments& super_type_args = TypeArguments::Handle(isolate, |
| 1437 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); | 1439 TypeArguments::New(num_super_type_params)); |
| 1440 // The cloned super class type parameters do not need to repeat their |
| 1441 // bounds, since the bound checks will be performed at the super class |
| 1442 // level. |
| 1443 param_bound = isolate->object_store()->object_type(); |
| 1438 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1444 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1439 param ^= super_type_params.TypeAt(i); | 1445 param ^= super_type_params.TypeAt(i); |
| 1440 param_name = param.name(); | 1446 param_name = param.name(); |
| 1441 param_bound = param.bound(); | |
| 1442 // TODO(14453): handle type bounds. | |
| 1443 if (!param_bound.IsObjectType()) { | |
| 1444 const Script& script = Script::Handle(mixin_app_class.script()); | |
| 1445 ReportError(Error::Handle(), // No previous error. | |
| 1446 script, param.token_pos(), | |
| 1447 "type parameter '%s': type bounds not yet" | |
| 1448 " implemented for mixins\n", | |
| 1449 param_name.ToCString()); | |
| 1450 } | |
| 1451 param_name = String::Concat(param_name, Symbols::Backtick()); | 1447 param_name = String::Concat(param_name, Symbols::Backtick()); |
| 1452 param_name = Symbols::New(param_name); | 1448 param_name = Symbols::New(param_name); |
| 1453 cloned_param = TypeParameter::New(mixin_app_class, | 1449 cloned_param = TypeParameter::New(mixin_app_class, |
| 1454 cloned_index, | 1450 cloned_index, |
| 1455 param_name, | 1451 param_name, |
| 1456 param_bound, | 1452 param_bound, |
| 1457 param.token_pos()); | 1453 param.token_pos()); |
| 1458 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1454 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1459 // Change the type arguments of the super type to refer to the | 1455 // Change the type arguments of the super type to refer to the |
| 1460 // cloned type parameters of the mixin application class. | 1456 // cloned type parameters of the mixin application class. |
| 1461 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1457 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1462 cloned_index++; | 1458 cloned_index++; |
| 1463 } | 1459 } |
| 1464 // TODO(14453): May need to handle BoundedType here. | 1460 // The super type may have a BoundedType as type argument, but cannot be |
| 1465 ASSERT(super_type.IsType()); | 1461 // a BoundedType itself. |
| 1466 Type::Cast(super_type).set_arguments(super_type_args); | 1462 Type::Cast(super_type).set_arguments(super_type_args); |
| 1467 ASSERT(!super_type.IsFinalized()); | 1463 ASSERT(!super_type.IsFinalized()); |
| 1468 } | 1464 } |
| 1469 | 1465 |
| 1470 // Second, clone the type parameters of the mixin class. | 1466 // Second, clone the type parameters of the mixin class. |
| 1471 // We need to retain the parameter names of the mixin class | 1467 // We need to retain the parameter names of the mixin class |
| 1472 // since the code that will be compiled in the context of the | 1468 // since the code that will be compiled in the context of the |
| 1473 // mixin application class may refer to the type parameters | 1469 // mixin application class may refer to the type parameters |
| 1474 // with that name. | 1470 // with that name. |
| 1475 if (num_mixin_type_params > 0) { | 1471 if (num_mixin_type_params > 0) { |
| 1476 const TypeArguments& mixin_params = | 1472 const TypeArguments& mixin_params = |
| 1477 TypeArguments::Handle(mixin_class.type_parameters()); | 1473 TypeArguments::Handle(isolate, mixin_class.type_parameters()); |
| 1478 const TypeArguments& mixin_type_args = TypeArguments::Handle( | 1474 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate, |
| 1479 TypeArguments::New(num_mixin_type_params)); | 1475 TypeArguments::New(num_mixin_type_params)); |
| 1480 // TODO(regis): Can we share interface type and mixin_type? | 1476 // TODO(regis): Can we share interface type and mixin_type? |
| 1481 const TypeArguments& interface_type_args = TypeArguments::Handle( | 1477 const TypeArguments& interface_type_args = TypeArguments::Handle(isolate, |
| 1482 TypeArguments::New(num_mixin_type_params)); | 1478 TypeArguments::New(num_mixin_type_params)); |
| 1483 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1479 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1484 param ^= mixin_params.TypeAt(i); | 1480 param ^= mixin_params.TypeAt(i); |
| 1485 param_name = param.name(); | 1481 param_name = param.name(); |
| 1486 param_bound = param.bound(); | 1482 param_bound = param.bound(); // The bound will be adjusted below. |
| 1487 | 1483 if (!param_bound.IsInstantiated()) { |
| 1488 // TODO(14453): handle type bounds. | 1484 has_uninstantiated_bounds = true; |
| 1489 if (!param_bound.IsObjectType()) { | |
| 1490 const Script& script = Script::Handle(mixin_app_class.script()); | |
| 1491 ReportError(Error::Handle(), // No previous error. | |
| 1492 script, param.token_pos(), | |
| 1493 "type parameter '%s': type bounds not yet" | |
| 1494 " implemented for mixins\n", | |
| 1495 param_name.ToCString()); | |
| 1496 } | 1485 } |
| 1497 cloned_param = TypeParameter::New(mixin_app_class, | 1486 cloned_param = TypeParameter::New(mixin_app_class, |
| 1498 cloned_index, | 1487 cloned_index, |
| 1499 param_name, | 1488 param_name, |
| 1500 param_bound, | 1489 param_bound, |
| 1501 param.token_pos()); | 1490 param.token_pos()); |
| 1502 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1491 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1503 interface_type_args.SetTypeAt(i, cloned_param); | 1492 interface_type_args.SetTypeAt(i, cloned_param); |
| 1504 mixin_type_args.SetTypeAt(i, cloned_param); | 1493 mixin_type_args.SetTypeAt(i, cloned_param); |
| 1505 cloned_index++; | 1494 cloned_index++; |
| 1506 } | 1495 } |
| 1507 | 1496 |
| 1497 // Third, replace the type parameters appearing in the bounds of the mixin |
| 1498 // type parameters, if any, by the cloned type parameters. This can be |
| 1499 // done by instantiating each bound using the mixin_type_args as |
| 1500 // instantiator. Since the mixin class must extend Object, its first type |
| 1501 // parameter has index 0, therefore, the instantiator does not require |
| 1502 // shifting. There is however an exception where the mixin class is an |
| 1503 // alias, in which case shifting is required and performed later in |
| 1504 // ApplyMixinAppAlias. |
| 1505 // Unfinalized type parameters replace finalized type parameters, which |
| 1506 // is not a problem since they will get finalized shortly as the mixin |
| 1507 // application class gets finalized. |
| 1508 if (has_uninstantiated_bounds && !mixin_class.is_mixin_app_alias()) { |
| 1509 Error& bound_error = Error::Handle(isolate); |
| 1510 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1511 param ^= mixin_type_args.TypeAt(i); |
| 1512 param_bound = param.bound(); |
| 1513 if (!param_bound.IsInstantiated()) { |
| 1514 param_bound = param_bound.InstantiateFrom(mixin_type_args, |
| 1515 &bound_error); |
| 1516 // The instantiator contains only TypeParameter objects and no |
| 1517 // BoundedType objects, so no bound error may occur. |
| 1518 ASSERT(bound_error.IsNull()); |
| 1519 ASSERT(!param_bound.IsInstantiated()); |
| 1520 param.set_bound(param_bound); |
| 1521 } |
| 1522 } |
| 1523 } |
| 1524 |
| 1508 // Lastly, set the type arguments of the mixin type and of the single | 1525 // Lastly, set the type arguments of the mixin type and of the single |
| 1509 // interface type. | 1526 // interface type. |
| 1510 ASSERT(!mixin_type.IsFinalized()); | 1527 ASSERT(!mixin_type.IsFinalized()); |
| 1511 mixin_type.set_arguments(mixin_type_args); | 1528 mixin_type.set_arguments(mixin_type_args); |
| 1512 ASSERT(!interface.IsFinalized()); | 1529 ASSERT(!interface.IsFinalized()); |
| 1513 interface.set_arguments(interface_type_args); | 1530 interface.set_arguments(interface_type_args); |
| 1514 } | 1531 } |
| 1515 mixin_app_class.set_type_parameters(cloned_type_params); | 1532 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1516 } | 1533 } |
| 1517 // If the mixin class is a mixin application alias class, we insert a new | 1534 // If the mixin class is a mixin application alias class, we insert a new |
| 1518 // synthesized mixin application class in the super chain of this mixin | 1535 // synthesized mixin application class in the super chain of this mixin |
| 1519 // application class. The new class will have the aliased mixin as actual | 1536 // application class. The new class will have the aliased mixin as actual |
| 1520 // mixin. | 1537 // mixin. |
| 1521 if (mixin_class.is_mixin_app_alias()) { | 1538 if (mixin_class.is_mixin_app_alias()) { |
| 1522 ApplyMixinAppAlias(mixin_app_class); | 1539 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds); |
| 1523 } | 1540 } |
| 1524 } | 1541 } |
| 1525 | 1542 |
| 1526 | 1543 |
| 1527 /* Support for mixin alias. | 1544 /* Support for mixin alias. |
| 1528 Consider the following example: | 1545 Consider the following example: |
| 1529 | 1546 |
| 1530 class I<T> { } | 1547 class I<T> { } |
| 1531 class J<T> { } | 1548 class J<T> { } |
| 1532 class S<T> { } | 1549 class S<T> { } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 We now have: | 1585 We now have: |
| 1569 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } | 1586 S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... } |
| 1570 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } | 1587 S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { } |
| 1571 | 1588 |
| 1572 The main implementation difficulty resides in the fact that the type parameters | 1589 The main implementation difficulty resides in the fact that the type parameters |
| 1573 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type | 1590 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type |
| 1574 parameters U and V of S&A. However, Map<U, V> is copied from the super type | 1591 parameters U and V of S&A. However, Map<U, V> is copied from the super type |
| 1575 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation | 1592 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation |
| 1576 step with a properly crafted instantiator vector takes care of the required type | 1593 step with a properly crafted instantiator vector takes care of the required type |
| 1577 parameter substitution. | 1594 parameter substitution. |
| 1578 | |
| 1579 The instantiator vector must end with the type parameters U and V of S&A. | 1595 The instantiator vector must end with the type parameters U and V of S&A. |
| 1580 The offset of the first type parameter U of S&A must be at the finalized index | 1596 The offset of the first type parameter U of S&A must be at the finalized index |
| 1581 of type parameter U of A. | 1597 of type parameter U of A. |
| 1598 |
| 1599 The same instantiator vector is used to adjust the type parameter bounds on U |
| 1600 and V, if any. This step was postponed from CloneMixinAppTypeParameters above. |
| 1601 |
| 1602 Also, a possible bound on type parameter T of M (not shown in the example above) |
| 1603 must be applied to type parameter T of S&A`. If the bound is uninstantiated, |
| 1604 i.e. if it refers to T or other type parameters of M, an instantiation step is |
| 1605 required to substitute these type parameters of M with type parameters of S&A`. |
| 1606 The instantiator vector consists of the cloned type parameters of M without |
| 1607 offset, since class M must extend Object. This is done in the recursive call to |
| 1608 CloneMixinAppTypeParameters and does not require specific code in |
| 1609 ApplyMixinAppAlias. |
| 1582 */ | 1610 */ |
| 1583 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class) { | 1611 void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class, |
| 1612 bool has_uninstantiated_bounds) { |
| 1584 // If this mixin alias is aliasing another mixin alias, another class | 1613 // If this mixin alias is aliasing another mixin alias, another class |
| 1585 // will be inserted via recursion. No need to check here. | 1614 // will be inserted via recursion. No need to check here. |
| 1586 // The mixin type may or may not be finalized yet. | 1615 // The mixin type may or may not be finalized yet. |
| 1587 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); | 1616 Isolate* isolate = Isolate::Current(); |
| 1588 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1617 AbstractType& super_type = AbstractType::Handle(isolate, |
| 1589 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1618 mixin_app_class.super_type()); |
| 1619 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); |
| 1620 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); |
| 1590 ASSERT(mixin_class.is_mixin_app_alias()); | 1621 ASSERT(mixin_class.is_mixin_app_alias()); |
| 1591 const Class& aliased_mixin_app_class = Class::Handle( | 1622 const Class& aliased_mixin_app_class = Class::Handle(isolate, |
| 1592 mixin_class.SuperClass()); | 1623 mixin_class.SuperClass()); |
| 1593 const Type& aliased_mixin_type = Type::Handle( | 1624 const Type& aliased_mixin_type = Type::Handle(isolate, |
| 1594 aliased_mixin_app_class.mixin()); | 1625 aliased_mixin_app_class.mixin()); |
| 1595 // The name of the inserted mixin application class is the name of mixin | 1626 // The name of the inserted mixin application class is the name of mixin |
| 1596 // class name with a backtick added. | 1627 // class name with a backtick added. |
| 1597 String& inserted_class_name = String::Handle(mixin_app_class.Name()); | 1628 String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name()); |
| 1598 inserted_class_name = String::Concat(inserted_class_name, | 1629 inserted_class_name = String::Concat(inserted_class_name, |
| 1599 Symbols::Backtick()); | 1630 Symbols::Backtick()); |
| 1600 const Library& library = Library::Handle(mixin_app_class.library()); | 1631 const Library& library = Library::Handle(isolate, mixin_app_class.library()); |
| 1601 Class& inserted_class = Class::Handle( | 1632 Class& inserted_class = Class::Handle(isolate, |
| 1602 library.LookupLocalClass(inserted_class_name)); | 1633 library.LookupLocalClass(inserted_class_name)); |
| 1603 if (inserted_class.IsNull()) { | 1634 if (inserted_class.IsNull()) { |
| 1604 inserted_class_name = Symbols::New(inserted_class_name); | 1635 inserted_class_name = Symbols::New(inserted_class_name); |
| 1605 const Script& script = Script::Handle(mixin_app_class.script()); | 1636 const Script& script = Script::Handle(isolate, mixin_app_class.script()); |
| 1606 inserted_class = Class::New( | 1637 inserted_class = Class::New( |
| 1607 inserted_class_name, script, mixin_app_class.token_pos()); | 1638 inserted_class_name, script, mixin_app_class.token_pos()); |
| 1608 inserted_class.set_is_synthesized_class(); | 1639 inserted_class.set_is_synthesized_class(); |
| 1609 library.AddClass(inserted_class); | 1640 library.AddClass(inserted_class); |
| 1610 | 1641 |
| 1611 if (FLAG_trace_class_finalization) { | 1642 if (FLAG_trace_class_finalization) { |
| 1612 OS::Print("Creating mixin application alias %s\n", | 1643 OS::Print("Creating mixin application alias %s\n", |
| 1613 inserted_class.ToCString()); | 1644 inserted_class.ToCString()); |
| 1614 } | 1645 } |
| 1615 | 1646 |
| 1616 // The super type of the inserted class is identical to the super type of | 1647 // The super type of the inserted class is identical to the super type of |
| 1617 // this mixin application class, except that it must refer to the type | 1648 // this mixin application class, except that it must refer to the type |
| 1618 // parameters of the inserted class rather than to those of the mixin | 1649 // parameters of the inserted class rather than to those of the mixin |
| 1619 // application class. | 1650 // application class. |
| 1620 // The type arguments of the super type will be set properly when calling | 1651 // The type arguments of the super type will be set properly when calling |
| 1621 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1652 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
| 1622 // type class is set properly. | 1653 // type class is set properly. |
| 1623 inserted_class.set_super_type(super_type); // Super class only is used. | 1654 inserted_class.set_super_type(super_type); // Super class only is used. |
| 1624 | 1655 |
| 1625 // The mixin type and interface type must also be set before calling | 1656 // The mixin type and interface type must also be set before calling |
| 1626 // CloneMixinAppTypeParameters. | 1657 // CloneMixinAppTypeParameters. |
| 1627 // After FinalizeTypesInClass, they will refer to the type parameters of | 1658 // After FinalizeTypesInClass, they will refer to the type parameters of |
| 1628 // the mixin class typedef. | 1659 // the mixin class typedef. |
| 1629 const Type& generic_mixin_type = Type::Handle( | 1660 const Type& generic_mixin_type = Type::Handle(isolate, |
| 1630 Type::New(Class::Handle(aliased_mixin_type.type_class()), | 1661 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), |
| 1631 Object::null_abstract_type_arguments(), | 1662 Object::null_abstract_type_arguments(), |
| 1632 aliased_mixin_type.token_pos())); | 1663 aliased_mixin_type.token_pos())); |
| 1633 inserted_class.set_mixin(generic_mixin_type); | 1664 inserted_class.set_mixin(generic_mixin_type); |
| 1634 // The interface will be set in CloneMixinAppTypeParameters. | 1665 // The interface will be set in CloneMixinAppTypeParameters. |
| 1635 } | 1666 } |
| 1636 | 1667 |
| 1637 // Finalize the types and call CloneMixinAppTypeParameters. | 1668 // Finalize the types and call CloneMixinAppTypeParameters. |
| 1638 FinalizeTypesInClass(inserted_class); | 1669 FinalizeTypesInClass(inserted_class); |
| 1639 | 1670 |
| 1640 // The super type of this mixin application class must point to the | 1671 // The super type of this mixin application class must point to the |
| 1641 // inserted class. The super type arguments are the concatenation of the | 1672 // inserted class. The super type arguments are the concatenation of the |
| 1642 // old super type arguments (propagating type arguments to the super class) | 1673 // old super type arguments (propagating type arguments to the super class) |
| 1643 // with new type arguments providing type arguments to the mixin. | 1674 // with new type arguments providing type arguments to the mixin. |
| 1644 // The appended type arguments are those of the super type of the mixin | 1675 // The appended type arguments are those of the super type of the mixin |
| 1645 // application alias that are forwarding to the aliased mixin type, except | 1676 // application alias that are forwarding to the aliased mixin type, except |
| 1646 // that they must refer to the type parameters of the mixin application | 1677 // that they must refer to the type parameters of the mixin application |
| 1647 // class rather than to those of the mixin application alias class. | 1678 // class rather than to those of the mixin application alias class. |
| 1648 // This type parameter substitution is performed by an instantiation step. | 1679 // This type parameter substitution is performed by an instantiation step. |
| 1649 // It is important that the type parameters of the mixin application class | 1680 // It is important that the type parameters of the mixin application class |
| 1650 // are not finalized yet, because new type parameters may have been added | 1681 // are not finalized yet, because new type parameters may have been added |
| 1651 // to the super class. | 1682 // to the super class. |
| 1652 Class& super_class = Class::Handle(super_type.type_class()); | 1683 Class& super_class = Class::Handle(isolate, super_type.type_class()); |
| 1653 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); | 1684 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); |
| 1654 while (super_class.IsMixinApplication()) { | 1685 while (super_class.IsMixinApplication()) { |
| 1655 super_class = super_class.SuperClass(); | 1686 super_class = super_class.SuperClass(); |
| 1656 } | 1687 } |
| 1657 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1688 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1658 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1689 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1659 intptr_t offset = | 1690 intptr_t offset = |
| 1660 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); | 1691 mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters(); |
| 1661 const TypeArguments& type_params = | 1692 const TypeArguments& type_params = |
| 1662 TypeArguments::Handle(mixin_app_class.type_parameters()); | 1693 TypeArguments::Handle(isolate, mixin_app_class.type_parameters()); |
| 1663 TypeArguments& instantiator = TypeArguments::Handle( | 1694 TypeArguments& instantiator = TypeArguments::Handle(isolate, |
| 1664 TypeArguments::New(offset + num_mixin_type_params)); | 1695 TypeArguments::New(offset + num_mixin_type_params)); |
| 1665 AbstractType& type = AbstractType::Handle(); | 1696 AbstractType& type = AbstractType::Handle(isolate); |
| 1666 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1697 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1667 type = type_params.TypeAt(num_super_type_params + i); | 1698 type = type_params.TypeAt(num_super_type_params + i); |
| 1668 instantiator.SetTypeAt(offset + i, type); | 1699 instantiator.SetTypeAt(offset + i, type); |
| 1669 } | 1700 } |
| 1670 ASSERT(aliased_mixin_type.IsFinalized()); | 1701 ASSERT(aliased_mixin_type.IsFinalized()); |
| 1671 const Class& aliased_mixin_type_class = Class::Handle( | 1702 const Class& aliased_mixin_type_class = Class::Handle(isolate, |
| 1672 aliased_mixin_type.type_class()); | 1703 aliased_mixin_type.type_class()); |
| 1673 const intptr_t num_aliased_mixin_type_params = | 1704 const intptr_t num_aliased_mixin_type_params = |
| 1674 aliased_mixin_type_class.NumTypeParameters(); | 1705 aliased_mixin_type_class.NumTypeParameters(); |
| 1675 const intptr_t num_aliased_mixin_type_args = | 1706 const intptr_t num_aliased_mixin_type_args = |
| 1676 aliased_mixin_type_class.NumTypeArguments(); | 1707 aliased_mixin_type_class.NumTypeArguments(); |
| 1677 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; | 1708 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; |
| 1678 ASSERT(inserted_class.NumTypeParameters() == | 1709 ASSERT(inserted_class.NumTypeParameters() == |
| 1679 (num_super_type_params + num_aliased_mixin_type_params)); | 1710 (num_super_type_params + num_aliased_mixin_type_params)); |
| 1680 // The aliased_mixin_type may be raw. | 1711 // The aliased_mixin_type may be raw. |
| 1681 const AbstractTypeArguments& mixin_class_super_type_args = | 1712 const AbstractTypeArguments& mixin_class_super_type_args = |
| 1682 AbstractTypeArguments::Handle( | 1713 AbstractTypeArguments::Handle(isolate, |
| 1683 AbstractType::Handle(mixin_class.super_type()).arguments()); | 1714 AbstractType::Handle(isolate, mixin_class.super_type()).arguments()); |
| 1684 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); | 1715 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); |
| 1685 if ((num_aliased_mixin_type_params > 0) && | 1716 if ((num_aliased_mixin_type_params > 0) && |
| 1686 !mixin_class_super_type_args.IsNull()) { | 1717 !mixin_class_super_type_args.IsNull()) { |
| 1687 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); | 1718 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); |
| 1688 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1719 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
| 1689 type = mixin_class_super_type_args.TypeAt(offset + i); | 1720 type = mixin_class_super_type_args.TypeAt(offset + i); |
| 1690 new_mixin_type_args.SetTypeAt(i, type); | 1721 new_mixin_type_args.SetTypeAt(i, type); |
| 1691 } | 1722 } |
| 1692 } | 1723 } |
| 1693 if (!new_mixin_type_args.IsNull() && | 1724 if (!new_mixin_type_args.IsNull() && |
| 1694 !new_mixin_type_args.IsInstantiated()) { | 1725 !new_mixin_type_args.IsInstantiated()) { |
| 1695 Error& bound_error = Error::Handle(); | 1726 Error& bound_error = Error::Handle(isolate); |
| 1696 new_mixin_type_args ^= | 1727 new_mixin_type_args ^= |
| 1697 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); | 1728 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); |
| 1698 // TODO(14453): Handle bound error. | 1729 // The instantiator contains only TypeParameter objects and no BoundedType |
| 1730 // objects, so no bound error may occur. |
| 1699 ASSERT(bound_error.IsNull()); | 1731 ASSERT(bound_error.IsNull()); |
| 1700 } | 1732 } |
| 1701 TypeArguments& new_super_type_args = TypeArguments::Handle(); | 1733 TypeArguments& new_super_type_args = TypeArguments::Handle(isolate); |
| 1702 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 1734 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
| 1703 new_super_type_args = TypeArguments::New(num_super_type_params + | 1735 new_super_type_args = TypeArguments::New(num_super_type_params + |
| 1704 num_aliased_mixin_type_params); | 1736 num_aliased_mixin_type_params); |
| 1705 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1737 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1706 type = type_params.TypeAt(i); | 1738 type = type_params.TypeAt(i); |
| 1707 new_super_type_args.SetTypeAt(i, type); | 1739 new_super_type_args.SetTypeAt(i, type); |
| 1708 } | 1740 } |
| 1709 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1741 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
| 1710 if (new_mixin_type_args.IsNull()) { | 1742 if (new_mixin_type_args.IsNull()) { |
| 1711 type = Type::DynamicType(); | 1743 type = Type::DynamicType(); |
| 1712 } else { | 1744 } else { |
| 1713 type = new_mixin_type_args.TypeAt(i); | 1745 type = new_mixin_type_args.TypeAt(i); |
| 1714 } | 1746 } |
| 1715 new_super_type_args.SetTypeAt(num_super_type_params + i, type); | 1747 new_super_type_args.SetTypeAt(num_super_type_params + i, type); |
| 1716 } | 1748 } |
| 1717 } | 1749 } |
| 1718 super_type = Type::New(inserted_class, | 1750 super_type = Type::New(inserted_class, |
| 1719 new_super_type_args, | 1751 new_super_type_args, |
| 1720 mixin_app_class.token_pos()); | 1752 mixin_app_class.token_pos()); |
| 1721 mixin_app_class.set_super_type(super_type); | 1753 mixin_app_class.set_super_type(super_type); |
| 1754 |
| 1755 // Perform the bound adjustment posponed from CloneMixinAppTypeParameters. |
| 1756 if (has_uninstantiated_bounds) { |
| 1757 TypeParameter& param = TypeParameter::Handle(isolate); |
| 1758 AbstractType& param_bound = AbstractType::Handle(isolate); |
| 1759 Error& bound_error = Error::Handle(isolate); |
| 1760 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1761 param ^= type_params.TypeAt(num_super_type_params + i); |
| 1762 param_bound = param.bound(); |
| 1763 if (!param_bound.IsInstantiated()) { |
| 1764 param_bound = param_bound.InstantiateFrom(instantiator, &bound_error); |
| 1765 // The instantiator contains only TypeParameter objects and no |
| 1766 // BoundedType objects, so no bound error may occur. |
| 1767 ASSERT(bound_error.IsNull()); |
| 1768 ASSERT(!param_bound.IsInstantiated()); |
| 1769 param.set_bound(param_bound); |
| 1770 } |
| 1771 } |
| 1772 } |
| 1773 |
| 1722 // Mark this mixin application class as being an alias. | 1774 // Mark this mixin application class as being an alias. |
| 1723 mixin_app_class.set_is_mixin_app_alias(); | 1775 mixin_app_class.set_is_mixin_app_alias(); |
| 1724 ASSERT(!mixin_app_class.is_type_finalized()); | 1776 ASSERT(!mixin_app_class.is_type_finalized()); |
| 1725 ASSERT(!mixin_app_class.is_mixin_type_applied()); | 1777 ASSERT(!mixin_app_class.is_mixin_type_applied()); |
| 1726 if (FLAG_trace_class_finalization) { | 1778 if (FLAG_trace_class_finalization) { |
| 1727 OS::Print("Inserting class %s to mixin application alias %s " | 1779 OS::Print("Inserting class %s to mixin application alias %s " |
| 1728 "with super type '%s'\n", | 1780 "with super type '%s'\n", |
| 1729 inserted_class.ToCString(), | 1781 inserted_class.ToCString(), |
| 1730 mixin_app_class.ToCString(), | 1782 mixin_app_class.ToCString(), |
| 1731 String::Handle(super_type.Name()).ToCString()); | 1783 String::Handle(isolate, super_type.Name()).ToCString()); |
| 1732 } | 1784 } |
| 1733 } | 1785 } |
| 1734 | 1786 |
| 1735 | 1787 |
| 1736 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 1788 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
| 1737 GrowableObjectArray* pending_types) { | 1789 GrowableObjectArray* pending_types) { |
| 1738 if (mixin_app_class.is_mixin_type_applied()) { | 1790 if (mixin_app_class.is_mixin_type_applied()) { |
| 1739 return; | 1791 return; |
| 1740 } | 1792 } |
| 1741 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1793 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1799 } | 1851 } |
| 1800 // Mark the application class as having been applied its mixin type in order | 1852 // Mark the application class as having been applied its mixin type in order |
| 1801 // to avoid cycles while finalizing its mixin type. | 1853 // to avoid cycles while finalizing its mixin type. |
| 1802 mixin_app_class.set_is_mixin_type_applied(); | 1854 mixin_app_class.set_is_mixin_type_applied(); |
| 1803 // Finalize the mixin type, which may have been changed in case | 1855 // Finalize the mixin type, which may have been changed in case |
| 1804 // mixin_app_class is an alias. | 1856 // mixin_app_class is an alias. |
| 1805 mixin_type = mixin_app_class.mixin(); | 1857 mixin_type = mixin_app_class.mixin(); |
| 1806 ASSERT(!mixin_type.IsBeingFinalized()); | 1858 ASSERT(!mixin_type.IsBeingFinalized()); |
| 1807 mixin_type ^= | 1859 mixin_type ^= |
| 1808 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); | 1860 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); |
| 1809 // TODO(14453): Check for a malbounded mixin_type. | 1861 // The mixin type cannot be malbounded, since it merely substitutes the |
| 1862 // type parameters of the mixin class with those of the mixin application |
| 1863 // class, but it does not instantiate them. |
| 1864 ASSERT(!mixin_type.IsMalbounded()); |
| 1810 mixin_app_class.set_mixin(mixin_type); | 1865 mixin_app_class.set_mixin(mixin_type); |
| 1811 } | 1866 } |
| 1812 | 1867 |
| 1813 | 1868 |
| 1814 void ClassFinalizer::CreateForwardingConstructors( | 1869 void ClassFinalizer::CreateForwardingConstructors( |
| 1815 const Class& mixin_app, | 1870 const Class& mixin_app, |
| 1816 const GrowableObjectArray& cloned_funcs) { | 1871 const GrowableObjectArray& cloned_funcs) { |
| 1817 const String& mixin_name = String::Handle(mixin_app.Name()); | 1872 const String& mixin_name = String::Handle(mixin_app.Name()); |
| 1818 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 1873 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
| 1819 const String& super_name = String::Handle(super_class.Name()); | 1874 const String& super_name = String::Handle(super_class.Name()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1869 } | 1924 } |
| 1870 } | 1925 } |
| 1871 | 1926 |
| 1872 | 1927 |
| 1873 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { | 1928 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { |
| 1874 Isolate* isolate = Isolate::Current(); | 1929 Isolate* isolate = Isolate::Current(); |
| 1875 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); | 1930 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); |
| 1876 ASSERT(!mixin_type.IsNull()); | 1931 ASSERT(!mixin_type.IsNull()); |
| 1877 ASSERT(mixin_type.HasResolvedTypeClass()); | 1932 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 1878 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); | 1933 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); |
| 1879 mixin_cls.EnsureIsFinalized(isolate); | 1934 const Error& error = Error::Handle(mixin_cls.EnsureIsFinalized(isolate)); |
| 1935 ASSERT(error.IsNull()); |
| 1880 // If the mixin is a mixin application alias class, there are no members to | 1936 // If the mixin is a mixin application alias class, there are no members to |
| 1881 // apply here. A new synthesized class representing the aliased mixin | 1937 // apply here. A new synthesized class representing the aliased mixin |
| 1882 // application class was inserted in the super chain of this mixin application | 1938 // application class was inserted in the super chain of this mixin application |
| 1883 // class. Members of the actual mixin class will be applied when visiting | 1939 // class. Members of the actual mixin class will be applied when visiting |
| 1884 // the mixin application class referring to the actual mixin. | 1940 // the mixin application class referring to the actual mixin. |
| 1885 ASSERT(!mixin_cls.is_mixin_app_alias() || | 1941 ASSERT(!mixin_cls.is_mixin_app_alias() || |
| 1886 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); | 1942 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication()); |
| 1887 // A default constructor will be created for the mixin app alias class. | 1943 // A default constructor will be created for the mixin app alias class. |
| 1888 | 1944 |
| 1889 if (FLAG_trace_class_finalization) { | 1945 if (FLAG_trace_class_finalization) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 } | 2031 } |
| 1976 // Finalize type parameters before finalizing the super type. | 2032 // Finalize type parameters before finalizing the super type. |
| 1977 FinalizeTypeParameters(cls); // May change super type. | 2033 FinalizeTypeParameters(cls); // May change super type. |
| 1978 super_class = cls.SuperClass(); | 2034 super_class = cls.SuperClass(); |
| 1979 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); | 2035 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
| 1980 ResolveUpperBounds(cls); | 2036 ResolveUpperBounds(cls); |
| 1981 // Finalize super type. | 2037 // Finalize super type. |
| 1982 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2038 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 1983 if (!super_type.IsNull()) { | 2039 if (!super_type.IsNull()) { |
| 1984 // In case of a bound error in the super type in production mode, the | 2040 // In case of a bound error in the super type in production mode, the |
| 1985 // finalized super type will be a BoundedType with a malformed bound. | 2041 // finalized super type will have a BoundedType as type argument for the |
| 2042 // out of bound type argument. |
| 1986 // It should not be a problem if the class is written to a snapshot and | 2043 // It should not be a problem if the class is written to a snapshot and |
| 1987 // later executed in checked mode. Note that the finalized type argument | 2044 // later executed in checked mode. Note that the finalized type argument |
| 1988 // vector of any type of the base class will contain a BoundedType for the | 2045 // vector of any type of the base class will contain a BoundedType for the |
| 1989 // out of bound type argument. | 2046 // out of bound type argument. |
| 1990 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); | 2047 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); |
| 1991 cls.set_super_type(super_type); | 2048 cls.set_super_type(super_type); |
| 1992 } | 2049 } |
| 1993 if (cls.IsSignatureClass()) { | 2050 if (cls.IsSignatureClass()) { |
| 1994 // Check for illegal self references. | 2051 // Check for illegal self references. |
| 1995 GrowableArray<intptr_t> visited_aliases; | 2052 GrowableArray<intptr_t> visited_aliases; |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2308 // and resolve super type and mixin types. | 2365 // and resolve super type and mixin types. |
| 2309 const Library& library = Library::Handle(cls.library()); | 2366 const Library& library = Library::Handle(cls.library()); |
| 2310 ASSERT(!library.IsNull()); | 2367 ASSERT(!library.IsNull()); |
| 2311 const Script& script = Script::Handle(cls.script()); | 2368 const Script& script = Script::Handle(cls.script()); |
| 2312 ASSERT(!script.IsNull()); | 2369 ASSERT(!script.IsNull()); |
| 2313 const GrowableObjectArray& type_args = | 2370 const GrowableObjectArray& type_args = |
| 2314 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2371 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2315 AbstractType& mixin_super_type = | 2372 AbstractType& mixin_super_type = |
| 2316 AbstractType::Handle(mixin_app_type.super_type()); | 2373 AbstractType::Handle(mixin_app_type.super_type()); |
| 2317 ResolveType(cls, mixin_super_type); | 2374 ResolveType(cls, mixin_super_type); |
| 2318 ASSERT(mixin_super_type.HasResolvedTypeClass()); | 2375 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
| 2319 // TODO(14453): May need to handle BoundedType here. | 2376 // The super type may have a BoundedType as type argument, but cannot be |
| 2320 ASSERT(mixin_super_type.IsType()); | 2377 // a BoundedType itself. |
| 2321 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2378 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
| 2322 AbstractType& mixin_type = AbstractType::Handle(); | 2379 AbstractType& mixin_type = AbstractType::Handle(); |
| 2323 Type& generic_mixin_type = Type::Handle(); | 2380 Type& generic_mixin_type = Type::Handle(); |
| 2324 Class& mixin_type_class = Class::Handle(); | 2381 Class& mixin_type_class = Class::Handle(); |
| 2325 Class& mixin_app_class = Class::Handle(); | 2382 Class& mixin_app_class = Class::Handle(); |
| 2326 String& mixin_app_class_name = String::Handle(); | 2383 String& mixin_app_class_name = String::Handle(); |
| 2327 String& mixin_type_class_name = String::Handle(); | 2384 String& mixin_type_class_name = String::Handle(); |
| 2328 const intptr_t depth = mixin_app_type.Depth(); | 2385 const intptr_t depth = mixin_app_type.Depth(); |
| 2329 for (intptr_t i = 0; i < depth; i++) { | 2386 for (intptr_t i = 0; i < depth; i++) { |
| 2330 mixin_type = mixin_app_type.MixinTypeAt(i); | 2387 mixin_type = mixin_app_type.MixinTypeAt(i); |
| 2331 ASSERT(!mixin_type.IsNull()); | 2388 ASSERT(!mixin_type.IsNull()); |
| 2332 ResolveType(cls, mixin_type); | 2389 ResolveType(cls, mixin_type); |
| 2333 ASSERT(mixin_type.HasResolvedTypeClass()); | 2390 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
| 2334 ASSERT(mixin_type.IsType()); | 2391 ASSERT(mixin_type.IsType()); |
| 2335 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2392 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
| 2336 | 2393 |
| 2337 // The name of the mixin application class is a combination of | 2394 // The name of the mixin application class is a combination of |
| 2338 // the super class name and mixin class name. | 2395 // the super class name and mixin class name. |
| 2339 mixin_app_class_name = mixin_super_type.ClassName(); | 2396 mixin_app_class_name = mixin_super_type.ClassName(); |
| 2340 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2397 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 2341 Symbols::Ampersand()); | 2398 Symbols::Ampersand()); |
| 2342 mixin_type_class_name = mixin_type.ClassName(); | 2399 mixin_type_class_name = mixin_type.ClassName(); |
| 2343 mixin_app_class_name = String::Concat(mixin_app_class_name, | 2400 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 expected_name ^= String::New("_offset"); | 2860 expected_name ^= String::New("_offset"); |
| 2804 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2861 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2805 field ^= fields_array.At(2); | 2862 field ^= fields_array.At(2); |
| 2806 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2863 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2807 name ^= field.name(); | 2864 name ^= field.name(); |
| 2808 ASSERT(name.Equals("length")); | 2865 ASSERT(name.Equals("length")); |
| 2809 #endif | 2866 #endif |
| 2810 } | 2867 } |
| 2811 | 2868 |
| 2812 } // namespace dart | 2869 } // namespace dart |
| OLD | NEW |