| 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 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 name.ToCString(), | 1352 name.ToCString(), |
| 1353 class_name.ToCString(), | 1353 class_name.ToCString(), |
| 1354 name.ToCString(), | 1354 name.ToCString(), |
| 1355 super_class_name.ToCString()); | 1355 super_class_name.ToCString()); |
| 1356 } | 1356 } |
| 1357 } | 1357 } |
| 1358 } | 1358 } |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 | 1361 |
| 1362 // Copy the type parameters of the super and mixin classes to the | 1362 // Clone the type parameters of the super class and of the mixin class of this |
| 1363 // mixin application class. Change type arguments of super type and of | 1363 // mixin application class and use them as the type parameters of this mixin |
| 1364 // interfaces to refer to the respective type parameters of the mixin | 1364 // application class. Set the type arguments of the super type, of the mixin |
| 1365 // application class. | 1365 // type (as well as of the interface type, which is identical to the mixin type) |
| 1366 // to refer to the respective type parameters of the mixin application class. |
| 1367 // In other words, decorate this mixin application class with type parameters |
| 1368 // that forward to the super type and mixin type (and interface type). |
| 1369 // Example: |
| 1370 // class S<T> { } |
| 1371 // class M<T> { } |
| 1372 // class C<E> extends S<E> with M<List<E>> { } |
| 1373 // results in |
| 1374 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> |
| 1375 // class C<E> extends S&M<E, List<E>> { } |
| 1376 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and |
| 1377 // T, and use them as type arguments in S<T`> and M<T>. |
| 1366 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1378 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
| 1367 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); | 1379 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); |
| 1368 const AbstractType& super_type = AbstractType::Handle( | 1380 const AbstractType& super_type = AbstractType::Handle( |
| 1369 mixin_app_class.super_type()); | 1381 mixin_app_class.super_type()); |
| 1370 ASSERT(super_type.IsResolved()); | 1382 ASSERT(super_type.IsResolved()); |
| 1371 const Class& super_class = Class::Handle(super_type.type_class()); | 1383 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1372 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1384 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1373 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1385 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1374 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1386 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1375 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1387 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1376 // The mixin class cannot be Object and this was checked earlier. | 1388 // The mixin class cannot be Object and this was checked earlier. |
| 1377 ASSERT(!mixin_class.IsObjectClass()); | 1389 ASSERT(!mixin_class.IsObjectClass()); |
| 1378 | 1390 |
| 1379 // Add the mixin type to the interfaces that the mixin application | 1391 // Add the mixin type to the interfaces that the mixin application |
| 1380 // class implements. This is necessary so that type tests work. | 1392 // class implements. This is necessary so that type tests work. |
| 1381 const Array& interfaces = Array::Handle(Array::New(1)); | 1393 const Array& interfaces = Array::Handle(Array::New(1)); |
| 1382 const Type& interface = Type::Handle(Type::New( | 1394 const Type& interface = Type::Handle(Type::New( |
| 1383 mixin_class, | 1395 mixin_class, |
| 1384 Object::null_abstract_type_arguments(), // Set again below if generic. | 1396 Object::null_abstract_type_arguments(), // Set again below if generic. |
| 1385 mixin_app_class.token_pos())); | 1397 mixin_app_class.token_pos())); |
| 1386 ASSERT(!interface.IsFinalized()); | 1398 ASSERT(!interface.IsFinalized()); |
| 1387 interfaces.SetAt(0, interface); | 1399 interfaces.SetAt(0, interface); |
| 1400 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
| 1388 mixin_app_class.set_interfaces(interfaces); | 1401 mixin_app_class.set_interfaces(interfaces); |
| 1389 | 1402 |
| 1390 // If both the super type and the mixin type are non generic, the mixin | 1403 // If both the super type and the mixin type are non generic, the mixin |
| 1391 // application class is non generic as well and we can skip type parameter | 1404 // application class is non generic as well and we can skip type parameter |
| 1392 // cloning. | 1405 // cloning. |
| 1393 if ((num_super_type_params + num_mixin_type_params) > 0) { | 1406 if ((num_super_type_params + num_mixin_type_params) > 0) { |
| 1394 // First, clone the super class type parameters. Rename them so that | 1407 // First, clone the super class type parameters. Rename them so that |
| 1395 // there can be no name conflict between the parameters of the super | 1408 // there can be no name conflict between the parameters of the super |
| 1396 // class and the mixin class. | 1409 // class and the mixin class. |
| 1397 const TypeArguments& cloned_type_params = TypeArguments::Handle( | 1410 const TypeArguments& cloned_type_params = TypeArguments::Handle( |
| 1398 TypeArguments::New(num_super_type_params + num_mixin_type_params)); | 1411 TypeArguments::New(num_super_type_params + num_mixin_type_params)); |
| 1399 TypeParameter& param = TypeParameter::Handle(); | 1412 TypeParameter& param = TypeParameter::Handle(); |
| 1400 TypeParameter& cloned_param = TypeParameter::Handle(); | 1413 TypeParameter& cloned_param = TypeParameter::Handle(); |
| 1401 String& param_name = String::Handle(); | 1414 String& param_name = String::Handle(); |
| 1402 AbstractType& param_bound = AbstractType::Handle(); | 1415 AbstractType& param_bound = AbstractType::Handle(); |
| 1403 intptr_t cloned_index = 0; | 1416 intptr_t cloned_index = 0; |
| 1404 if (num_super_type_params > 0) { | 1417 if (num_super_type_params > 0) { |
| 1405 const TypeArguments& super_type_params = | 1418 const TypeArguments& super_type_params = |
| 1406 TypeArguments::Handle(super_class.type_parameters()); | 1419 TypeArguments::Handle(super_class.type_parameters()); |
| 1407 const TypeArguments& super_type_args = | 1420 const TypeArguments& super_type_args = |
| 1408 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); | 1421 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); |
| 1409 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1422 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1410 param ^= super_type_params.TypeAt(i); | 1423 param ^= super_type_params.TypeAt(i); |
| 1411 param_name = param.name(); | 1424 param_name = param.name(); |
| 1412 param_bound = param.bound(); | 1425 param_bound = param.bound(); |
| 1413 // TODO(hausner): handle type bounds. | 1426 // TODO(14453): handle type bounds. |
| 1414 if (!param_bound.IsObjectType()) { | 1427 if (!param_bound.IsObjectType()) { |
| 1415 const Script& script = Script::Handle(mixin_app_class.script()); | 1428 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1416 ReportError(Error::Handle(), // No previous error. | 1429 ReportError(Error::Handle(), // No previous error. |
| 1417 script, param.token_pos(), | 1430 script, param.token_pos(), |
| 1418 "type parameter '%s': type bounds not yet" | 1431 "type parameter '%s': type bounds not yet" |
| 1419 " implemented for mixins\n", | 1432 " implemented for mixins\n", |
| 1420 param_name.ToCString()); | 1433 param_name.ToCString()); |
| 1421 } | 1434 } |
| 1422 param_name = String::Concat(param_name, Symbols::Backtick()); | 1435 param_name = String::Concat(param_name, Symbols::Backtick()); |
| 1423 param_name = Symbols::New(param_name); | 1436 param_name = Symbols::New(param_name); |
| 1424 cloned_param = TypeParameter::New(mixin_app_class, | 1437 cloned_param = TypeParameter::New(mixin_app_class, |
| 1425 cloned_index, | 1438 cloned_index, |
| 1426 param_name, | 1439 param_name, |
| 1427 param_bound, | 1440 param_bound, |
| 1428 param.token_pos()); | 1441 param.token_pos()); |
| 1429 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1442 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1430 // Change the type arguments of the super type to refer to the | 1443 // Change the type arguments of the super type to refer to the |
| 1431 // cloned type parameters of the mixin application class. | 1444 // cloned type parameters of the mixin application class. |
| 1432 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1445 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1433 cloned_index++; | 1446 cloned_index++; |
| 1434 } | 1447 } |
| 1435 // TODO(hausner): May need to handle BoundedType here. | 1448 // TODO(14453): May need to handle BoundedType here. |
| 1436 ASSERT(super_type.IsType()); | 1449 ASSERT(super_type.IsType()); |
| 1437 Type::Cast(super_type).set_arguments(super_type_args); | 1450 Type::Cast(super_type).set_arguments(super_type_args); |
| 1438 ASSERT(!super_type.IsFinalized()); | 1451 ASSERT(!super_type.IsFinalized()); |
| 1439 } | 1452 } |
| 1440 | 1453 |
| 1441 // Second, clone the type parameters of the mixin class. | 1454 // Second, clone the type parameters of the mixin class. |
| 1442 // We need to retain the parameter names of the mixin class | 1455 // We need to retain the parameter names of the mixin class |
| 1443 // since the code that will be compiled in the context of the | 1456 // since the code that will be compiled in the context of the |
| 1444 // mixin application class may refer to the type parameters | 1457 // mixin application class may refer to the type parameters |
| 1445 // with that name. | 1458 // with that name. |
| 1446 if (num_mixin_type_params > 0) { | 1459 if (num_mixin_type_params > 0) { |
| 1447 const TypeArguments& mixin_params = | 1460 const TypeArguments& mixin_params = |
| 1448 TypeArguments::Handle(mixin_class.type_parameters()); | 1461 TypeArguments::Handle(mixin_class.type_parameters()); |
| 1462 const TypeArguments& mixin_type_args = TypeArguments::Handle( |
| 1463 TypeArguments::New(num_mixin_type_params)); |
| 1464 // TODO(regis): Can we share interface type and mixin_type? |
| 1449 const TypeArguments& interface_type_args = TypeArguments::Handle( | 1465 const TypeArguments& interface_type_args = TypeArguments::Handle( |
| 1450 TypeArguments::New(num_mixin_type_params)); | 1466 TypeArguments::New(num_mixin_type_params)); |
| 1451 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1467 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1452 param ^= mixin_params.TypeAt(i); | 1468 param ^= mixin_params.TypeAt(i); |
| 1453 param_name = param.name(); | 1469 param_name = param.name(); |
| 1454 param_bound = param.bound(); | 1470 param_bound = param.bound(); |
| 1455 | 1471 |
| 1456 // TODO(hausner): handle type bounds. | 1472 // TODO(14453): handle type bounds. |
| 1457 if (!param_bound.IsObjectType()) { | 1473 if (!param_bound.IsObjectType()) { |
| 1458 const Script& script = Script::Handle(mixin_app_class.script()); | 1474 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1459 ReportError(Error::Handle(), // No previous error. | 1475 ReportError(Error::Handle(), // No previous error. |
| 1460 script, param.token_pos(), | 1476 script, param.token_pos(), |
| 1461 "type parameter '%s': type bounds not yet" | 1477 "type parameter '%s': type bounds not yet" |
| 1462 " implemented for mixins\n", | 1478 " implemented for mixins\n", |
| 1463 param_name.ToCString()); | 1479 param_name.ToCString()); |
| 1464 } | 1480 } |
| 1465 cloned_param = TypeParameter::New(mixin_app_class, | 1481 cloned_param = TypeParameter::New(mixin_app_class, |
| 1466 cloned_index, | 1482 cloned_index, |
| 1467 param_name, | 1483 param_name, |
| 1468 param_bound, | 1484 param_bound, |
| 1469 param.token_pos()); | 1485 param.token_pos()); |
| 1470 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1486 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1471 interface_type_args.SetTypeAt(i, cloned_param); | 1487 interface_type_args.SetTypeAt(i, cloned_param); |
| 1488 mixin_type_args.SetTypeAt(i, cloned_param); |
| 1472 cloned_index++; | 1489 cloned_index++; |
| 1473 } | 1490 } |
| 1474 | 1491 |
| 1475 // Lastly, set the type arguments of the single interface type. | 1492 // Lastly, set the type arguments of the mixin type and of the single |
| 1493 // interface type. |
| 1494 ASSERT(!mixin_type.IsFinalized()); |
| 1495 mixin_type.set_arguments(mixin_type_args); |
| 1476 ASSERT(!interface.IsFinalized()); | 1496 ASSERT(!interface.IsFinalized()); |
| 1477 interface.set_arguments(interface_type_args); | 1497 interface.set_arguments(interface_type_args); |
| 1478 } | 1498 } |
| 1479 mixin_app_class.set_type_parameters(cloned_type_params); | 1499 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1480 } | 1500 } |
| 1481 // If the mixin class is a mixin application typedef class, we insert a new | 1501 // If the mixin class is a mixin application typedef class, we insert a new |
| 1482 // synthesized mixin application class in the super chain of this mixin | 1502 // synthesized mixin application class in the super chain of this mixin |
| 1483 // application class. The new class will have the aliased mixin as actual | 1503 // application class. The new class will have the aliased mixin as actual |
| 1484 // mixin. | 1504 // mixin. |
| 1485 if (mixin_class.is_mixin_typedef()) { | 1505 if (mixin_class.is_mixin_typedef()) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1537 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type | 1557 U and V in the super type S&A`<T`, Map<U, V>> of S&A must refer to the type |
| 1538 parameters U and V of S&A. However, Map<U, V> is copied from the super type | 1558 parameters U and V of S&A. However, Map<U, V> is copied from the super type |
| 1539 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation | 1559 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation |
| 1540 step with a properly crafted instantiator vector takes care of the required type | 1560 step with a properly crafted instantiator vector takes care of the required type |
| 1541 parameter substitution. | 1561 parameter substitution. |
| 1542 | 1562 |
| 1543 The instantiator vector must end with the type parameters U and V of S&A. | 1563 The instantiator vector must end with the type parameters U and V of S&A. |
| 1544 The offset of the first type parameter U of S&A must be at the finalized index | 1564 The offset of the first type parameter U of S&A must be at the finalized index |
| 1545 of type parameter U of A. | 1565 of type parameter U of A. |
| 1546 */ | 1566 */ |
| 1567 // TODO(regis): The syntax does not use 'typedef' anymore. Rename to 'alias'? |
| 1547 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { | 1568 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { |
| 1548 // If this mixin typedef is aliasing another mixin typedef, another class | 1569 // If this mixin typedef is aliasing another mixin typedef, another class |
| 1549 // will be inserted via recursion. No need to check here. | 1570 // will be inserted via recursion. No need to check here. |
| 1550 // The mixin type may or may not be finalized yet. | 1571 // The mixin type may or may not be finalized yet. |
| 1572 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); |
| 1551 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1573 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1552 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1574 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1553 ASSERT(mixin_class.is_mixin_typedef()); | 1575 ASSERT(mixin_class.is_mixin_typedef()); |
| 1554 const Class& aliased_mixin_app_class = Class::Handle( | 1576 const Class& aliased_mixin_app_class = Class::Handle( |
| 1555 mixin_class.SuperClass()); | 1577 mixin_class.SuperClass()); |
| 1556 const Type& aliased_mixin_type = Type::Handle( | 1578 const Type& aliased_mixin_type = Type::Handle( |
| 1557 aliased_mixin_app_class.mixin()); | 1579 aliased_mixin_app_class.mixin()); |
| 1558 // The name of the inserted mixin application class is the name of mixin | 1580 // The name of the inserted mixin application class is the name of mixin |
| 1559 // class name with a backtick added. | 1581 // class name with a backtick added. |
| 1560 String& inserted_class_name = String::Handle(mixin_app_class.Name()); | 1582 String& inserted_class_name = String::Handle(mixin_app_class.Name()); |
| 1561 inserted_class_name = String::Concat(inserted_class_name, | 1583 inserted_class_name = String::Concat(inserted_class_name, |
| 1562 Symbols::Backtick()); | 1584 Symbols::Backtick()); |
| 1563 inserted_class_name = Symbols::New(inserted_class_name); | |
| 1564 const Script& script = Script::Handle(mixin_app_class.script()); | |
| 1565 const Library& library = Library::Handle(mixin_app_class.library()); | 1585 const Library& library = Library::Handle(mixin_app_class.library()); |
| 1566 const Class& inserted_class = Class::Handle(Class::New( | 1586 Class& inserted_class = Class::Handle( |
| 1567 inserted_class_name, script, mixin_app_class.token_pos())); | 1587 library.LookupLocalClass(inserted_class_name)); |
| 1568 inserted_class.set_library(library); | 1588 if (inserted_class.IsNull()) { |
| 1569 inserted_class.set_is_synthesized_class(); | 1589 inserted_class_name = Symbols::New(inserted_class_name); |
| 1590 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1591 inserted_class = Class::New( |
| 1592 inserted_class_name, script, mixin_app_class.token_pos()); |
| 1593 inserted_class.set_is_synthesized_class(); |
| 1594 library.AddClass(inserted_class); |
| 1570 | 1595 |
| 1571 // The super type of the inserted class is identical to the super type of | 1596 if (FLAG_trace_class_finalization) { |
| 1572 // this mixin application class, except that it must refer to the type | 1597 OS::Print("Creating mixin typedef application %s\n", |
| 1573 // parameters of the inserted class rather than to those of the mixin | 1598 inserted_class.ToCString()); |
| 1574 // application class. | 1599 } |
| 1575 // The type arguments of the super type will be set properly when calling | |
| 1576 // CloneMixinAppTypeParameters on the inserted class, as long as the super | |
| 1577 // type class is set properly. | |
| 1578 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); | |
| 1579 inserted_class.set_super_type(super_type); // Super class only is used. | |
| 1580 | 1600 |
| 1581 // The mixin type must also be set before calling CloneMixinAppTypeParameters. | 1601 // The super type of the inserted class is identical to the super type of |
| 1582 // It refers to the type parameters of the mixin class typedef. | 1602 // this mixin application class, except that it must refer to the type |
| 1583 inserted_class.set_mixin(aliased_mixin_type); // Mixin class only is used. | 1603 // parameters of the inserted class rather than to those of the mixin |
| 1604 // application class. |
| 1605 // The type arguments of the super type will be set properly when calling |
| 1606 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
| 1607 // type class is set properly. |
| 1608 inserted_class.set_super_type(super_type); // Super class only is used. |
| 1609 |
| 1610 // The mixin type and interface type must also be set before calling |
| 1611 // CloneMixinAppTypeParameters. |
| 1612 // After FinalizeTypesInClass, they will refer to the type parameters of |
| 1613 // the mixin class typedef. |
| 1614 const Type& generic_mixin_type = Type::Handle( |
| 1615 Type::New(Class::Handle(aliased_mixin_type.type_class()), |
| 1616 Object::null_abstract_type_arguments(), |
| 1617 aliased_mixin_type.token_pos())); |
| 1618 inserted_class.set_mixin(generic_mixin_type); |
| 1619 // The interface will be set in CloneMixinAppTypeParameters. |
| 1620 } |
| 1584 | 1621 |
| 1585 // Finalize the types and call CloneMixinAppTypeParameters. | 1622 // Finalize the types and call CloneMixinAppTypeParameters. |
| 1586 FinalizeTypesInClass(inserted_class); | 1623 FinalizeTypesInClass(inserted_class); |
| 1587 | 1624 |
| 1588 // The super type of this mixin application class must point to the | 1625 // The super type of this mixin application class must point to the |
| 1589 // inserted class. The super type arguments are the concatenation of the | 1626 // inserted class. The super type arguments are the concatenation of the |
| 1590 // old super type arguments (propagating type arguments to the super class) | 1627 // old super type arguments (propagating type arguments to the super class) |
| 1591 // with new type arguments providing type arguments to the mixin. | 1628 // with new type arguments providing type arguments to the mixin. |
| 1592 // The appended type arguments are those of the aliased mixin type, except | 1629 // The appended type arguments are those of the super type of the mixin |
| 1630 // typedef that are forwarding to the aliased mixin type, except |
| 1593 // that they must refer to the type parameters of the mixin application | 1631 // that they must refer to the type parameters of the mixin application |
| 1594 // class rather than to those of the aliased mixin class. | 1632 // class rather than to those of the mixin typedef class. |
| 1595 // This type parameter substitution is performed by an instantiation step. | 1633 // This type parameter substitution is performed by an instantiation step. |
| 1596 // It is important that the type parameters of the mixin application class | 1634 // It is important that the type parameters of the mixin application class |
| 1597 // are not finalized yet, because new type parameters may have been added | 1635 // are not finalized yet, because new type parameters may have been added |
| 1598 // to the super class. | 1636 // to the super class. |
| 1599 Class& super_class = Class::Handle(super_type.type_class()); | 1637 Class& super_class = Class::Handle(super_type.type_class()); |
| 1600 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); | 1638 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); |
| 1601 while (super_class.IsMixinApplication()) { | 1639 while (super_class.IsMixinApplication()) { |
| 1602 super_class = super_class.SuperClass(); | 1640 super_class = super_class.SuperClass(); |
| 1603 } | 1641 } |
| 1604 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1642 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1618 const Class& aliased_mixin_type_class = Class::Handle( | 1656 const Class& aliased_mixin_type_class = Class::Handle( |
| 1619 aliased_mixin_type.type_class()); | 1657 aliased_mixin_type.type_class()); |
| 1620 const intptr_t num_aliased_mixin_type_params = | 1658 const intptr_t num_aliased_mixin_type_params = |
| 1621 aliased_mixin_type_class.NumTypeParameters(); | 1659 aliased_mixin_type_class.NumTypeParameters(); |
| 1622 const intptr_t num_aliased_mixin_type_args = | 1660 const intptr_t num_aliased_mixin_type_args = |
| 1623 aliased_mixin_type_class.NumTypeArguments(); | 1661 aliased_mixin_type_class.NumTypeArguments(); |
| 1624 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; | 1662 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; |
| 1625 ASSERT(inserted_class.NumTypeParameters() == | 1663 ASSERT(inserted_class.NumTypeParameters() == |
| 1626 (num_super_type_params + num_aliased_mixin_type_params)); | 1664 (num_super_type_params + num_aliased_mixin_type_params)); |
| 1627 // The aliased_mixin_type may be raw. | 1665 // The aliased_mixin_type may be raw. |
| 1628 const AbstractTypeArguments& aliased_mixin_type_args = | 1666 const AbstractTypeArguments& mixin_class_super_type_args = |
| 1629 AbstractTypeArguments::Handle(aliased_mixin_type.arguments()); | 1667 AbstractTypeArguments::Handle( |
| 1668 AbstractType::Handle(mixin_class.super_type()).arguments()); |
| 1630 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); | 1669 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); |
| 1631 if ((num_aliased_mixin_type_params > 0) && | 1670 if ((num_aliased_mixin_type_params > 0) && |
| 1632 !aliased_mixin_type_args.IsNull()) { | 1671 !mixin_class_super_type_args.IsNull()) { |
| 1633 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); | 1672 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); |
| 1634 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1673 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
| 1635 type = aliased_mixin_type_args.TypeAt(offset + i); | 1674 type = mixin_class_super_type_args.TypeAt(offset + i); |
| 1636 new_mixin_type_args.SetTypeAt(i, type); | 1675 new_mixin_type_args.SetTypeAt(i, type); |
| 1637 } | 1676 } |
| 1638 } | 1677 } |
| 1639 if (!new_mixin_type_args.IsNull() && | 1678 if (!new_mixin_type_args.IsNull() && |
| 1640 !new_mixin_type_args.IsInstantiated()) { | 1679 !new_mixin_type_args.IsInstantiated()) { |
| 1641 Error& bound_error = Error::Handle(); | 1680 Error& bound_error = Error::Handle(); |
| 1642 new_mixin_type_args ^= | 1681 new_mixin_type_args ^= |
| 1643 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); | 1682 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); |
| 1644 // TODO(regis): Handle bound error. | 1683 // TODO(14453): Handle bound error. |
| 1645 ASSERT(bound_error.IsNull()); | 1684 ASSERT(bound_error.IsNull()); |
| 1646 } | 1685 } |
| 1647 TypeArguments& new_super_type_args = TypeArguments::Handle(); | 1686 TypeArguments& new_super_type_args = TypeArguments::Handle(); |
| 1648 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 1687 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
| 1649 new_super_type_args = TypeArguments::New(num_super_type_params + | 1688 new_super_type_args = TypeArguments::New(num_super_type_params + |
| 1650 num_aliased_mixin_type_params); | 1689 num_aliased_mixin_type_params); |
| 1651 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1690 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1652 type = type_params.TypeAt(i); | 1691 type = type_params.TypeAt(i); |
| 1653 new_super_type_args.SetTypeAt(i, type); | 1692 new_super_type_args.SetTypeAt(i, type); |
| 1654 } | 1693 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 } | 1783 } |
| 1745 // Mark the application class as having been applied its mixin type in order | 1784 // Mark the application class as having been applied its mixin type in order |
| 1746 // to avoid cycles while finalizing its mixin type. | 1785 // to avoid cycles while finalizing its mixin type. |
| 1747 mixin_app_class.set_is_mixin_type_applied(); | 1786 mixin_app_class.set_is_mixin_type_applied(); |
| 1748 // Finalize the mixin type, which may have been changed in case | 1787 // Finalize the mixin type, which may have been changed in case |
| 1749 // mixin_app_class is a typedef. | 1788 // mixin_app_class is a typedef. |
| 1750 mixin_type = mixin_app_class.mixin(); | 1789 mixin_type = mixin_app_class.mixin(); |
| 1751 ASSERT(!mixin_type.IsBeingFinalized()); | 1790 ASSERT(!mixin_type.IsBeingFinalized()); |
| 1752 mixin_type ^= | 1791 mixin_type ^= |
| 1753 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); | 1792 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed); |
| 1754 // TODO(regis): Check for a malbounded mixin_type. | 1793 // TODO(14453): Check for a malbounded mixin_type. |
| 1755 mixin_app_class.set_mixin(mixin_type); | 1794 mixin_app_class.set_mixin(mixin_type); |
| 1756 } | 1795 } |
| 1757 | 1796 |
| 1758 | 1797 |
| 1759 void ClassFinalizer::CreateForwardingConstructors( | 1798 void ClassFinalizer::CreateForwardingConstructors( |
| 1760 const Class& mixin_app, | 1799 const Class& mixin_app, |
| 1761 const GrowableObjectArray& cloned_funcs) { | 1800 const GrowableObjectArray& cloned_funcs) { |
| 1762 const String& mixin_name = String::Handle(mixin_app.Name()); | 1801 const String& mixin_name = String::Handle(mixin_app.Name()); |
| 1763 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 1802 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
| 1764 const String& super_name = String::Handle(super_class.Name()); | 1803 const String& super_name = String::Handle(super_class.Name()); |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2217 // Discard provided type arguments and treat type as raw. | 2256 // Discard provided type arguments and treat type as raw. |
| 2218 } | 2257 } |
| 2219 // Fill arguments with type dynamic. | 2258 // Fill arguments with type dynamic. |
| 2220 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2259 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 2221 arg = Type::DynamicType(); | 2260 arg = Type::DynamicType(); |
| 2222 collected_args.Add(arg); | 2261 collected_args.Add(arg); |
| 2223 } | 2262 } |
| 2224 } | 2263 } |
| 2225 | 2264 |
| 2226 | 2265 |
| 2227 RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls, | 2266 RawType* ClassFinalizer::ResolveMixinAppType( |
| 2228 const MixinAppType& mixin_app) { | 2267 const Class& cls, |
| 2229 // Resolve super type and all mixin types. | 2268 const MixinAppType& mixin_app_type) { |
| 2269 // Lookup or create mixin application classes in the library of cls |
| 2270 // and resolve super type and mixin types. |
| 2271 const Library& library = Library::Handle(cls.library()); |
| 2272 ASSERT(!library.IsNull()); |
| 2273 const Script& script = Script::Handle(cls.script()); |
| 2274 ASSERT(!script.IsNull()); |
| 2230 const GrowableObjectArray& type_args = | 2275 const GrowableObjectArray& type_args = |
| 2231 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2276 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2232 AbstractType& type = AbstractType::Handle(mixin_app.SuperType()); | 2277 AbstractType& mixin_super_type = |
| 2233 ResolveType(cls, type, kCanonicalizeWellFormed); | 2278 AbstractType::Handle(mixin_app_type.super_type()); |
| 2234 ASSERT(type.HasResolvedTypeClass()); | 2279 ResolveType(cls, mixin_super_type, kCanonicalizeWellFormed); |
| 2235 // TODO(hausner): May need to handle BoundedType here. | 2280 ASSERT(mixin_super_type.HasResolvedTypeClass()); |
| 2236 ASSERT(type.IsType()); | 2281 // TODO(14453): May need to handle BoundedType here. |
| 2237 CollectTypeArguments(cls, Type::Cast(type), type_args); | 2282 ASSERT(mixin_super_type.IsType()); |
| 2283 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
| 2284 AbstractType& mixin_type = AbstractType::Handle(); |
| 2285 Type& generic_mixin_type = Type::Handle(); |
| 2286 Class& mixin_type_class = Class::Handle(); |
| 2238 Class& mixin_app_class = Class::Handle(); | 2287 Class& mixin_app_class = Class::Handle(); |
| 2239 const intptr_t depth = mixin_app.Depth(); | 2288 String& mixin_app_class_name = String::Handle(); |
| 2289 String& mixin_type_class_name = String::Handle(); |
| 2290 const intptr_t depth = mixin_app_type.Depth(); |
| 2240 for (intptr_t i = 0; i < depth; i++) { | 2291 for (intptr_t i = 0; i < depth; i++) { |
| 2241 mixin_app_class = mixin_app.MixinAppAt(i); | 2292 mixin_type = mixin_app_type.MixinTypeAt(i); |
| 2242 type = mixin_app_class.mixin(); | 2293 ASSERT(!mixin_type.IsNull()); |
| 2243 ASSERT(!type.IsNull()); | 2294 ResolveType(cls, mixin_type, kCanonicalizeWellFormed); |
| 2244 ResolveType(cls, type, kCanonicalizeWellFormed); | 2295 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 2245 ASSERT(type.HasResolvedTypeClass()); | 2296 ASSERT(mixin_type.IsType()); |
| 2246 ASSERT(type.IsType()); | 2297 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
| 2247 CollectTypeArguments(cls, Type::Cast(type), type_args); | 2298 |
| 2299 // The name of the mixin application class is a combination of |
| 2300 // the super class name and mixin class name. |
| 2301 mixin_app_class_name = mixin_super_type.ClassName(); |
| 2302 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 2303 Symbols::Ampersand()); |
| 2304 mixin_type_class_name = mixin_type.ClassName(); |
| 2305 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 2306 mixin_type_class_name); |
| 2307 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
| 2308 if (mixin_app_class.IsNull()) { |
| 2309 mixin_app_class_name = Symbols::New(mixin_app_class_name); |
| 2310 mixin_app_class = Class::New(mixin_app_class_name, |
| 2311 script, |
| 2312 mixin_type.token_pos()); |
| 2313 mixin_app_class.set_super_type(mixin_super_type); |
| 2314 mixin_type_class = mixin_type.type_class(); |
| 2315 generic_mixin_type = Type::New(mixin_type_class, |
| 2316 Object::null_abstract_type_arguments(), |
| 2317 mixin_type.token_pos()); |
| 2318 mixin_app_class.set_mixin(generic_mixin_type); |
| 2319 mixin_app_class.set_is_synthesized_class(); |
| 2320 library.AddClass(mixin_app_class); |
| 2321 |
| 2322 // No need to add the new class to pending_classes, since it will be |
| 2323 // processed via the super_type chain of a pending class. |
| 2324 |
| 2325 if (FLAG_trace_class_finalization) { |
| 2326 OS::Print("Creating mixin application %s\n", |
| 2327 mixin_app_class.ToCString()); |
| 2328 } |
| 2329 } |
| 2330 // This mixin application class becomes the type class of the super type of |
| 2331 // the next mixin application class. It is however too early to provide the |
| 2332 // correct super type arguments. We use the raw type for now. |
| 2333 mixin_super_type = Type::New(mixin_app_class, |
| 2334 Object::null_abstract_type_arguments(), |
| 2335 mixin_type.token_pos()); |
| 2248 } | 2336 } |
| 2337 AbstractType& type_arg = AbstractType::Handle(); |
| 2249 const TypeArguments& mixin_app_args = | 2338 const TypeArguments& mixin_app_args = |
| 2250 TypeArguments::Handle(TypeArguments::New(type_args.Length())); | 2339 TypeArguments::Handle(TypeArguments::New(type_args.Length())); |
| 2251 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2340 for (intptr_t i = 0; i < type_args.Length(); i++) { |
| 2252 type ^= type_args.At(i); | 2341 type_arg ^= type_args.At(i); |
| 2253 mixin_app_args.SetTypeAt(i, type); | 2342 mixin_app_args.SetTypeAt(i, type_arg); |
| 2254 } | 2343 } |
| 2255 if (FLAG_trace_class_finalization) { | 2344 if (FLAG_trace_class_finalization) { |
| 2256 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", | 2345 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", |
| 2257 mixin_app_args.ToCString()); | 2346 mixin_app_args.ToCString()); |
| 2258 } | 2347 } |
| 2259 // The mixin application class at depth k is a subclass of mixin application | 2348 // The mixin application class at depth k is a subclass of mixin application |
| 2260 // class at depth k - 1. Build a new super type with the class at the highest | 2349 // class at depth k - 1. Build a new super type with the class at the highest |
| 2261 // depth (the last one processed by the loop above) as the type class and the | 2350 // depth (the last one processed by the loop above) as the type class and the |
| 2262 // collected type arguments from the super type and all mixin types. | 2351 // collected type arguments from the super type and all mixin types. |
| 2263 // This super type replaces the MixinAppType object in the class that extends | 2352 // This super type replaces the MixinAppType object in the class that extends |
| 2264 // the mixin application. | 2353 // the mixin application. |
| 2265 return Type::New(mixin_app_class, mixin_app_args, mixin_app.token_pos()); | 2354 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); |
| 2266 } | 2355 } |
| 2267 | 2356 |
| 2268 | 2357 |
| 2269 // Recursively walks the graph of explicitly declared super type and | 2358 // Recursively walks the graph of explicitly declared super type and |
| 2270 // interfaces, resolving unresolved super types and interfaces. | 2359 // interfaces, resolving unresolved super types and interfaces. |
| 2271 // Reports an error if there is an interface reference that cannot be | 2360 // Reports an error if there is an interface reference that cannot be |
| 2272 // resolved, or if there is a cycle in the graph. We detect cycles by | 2361 // resolved, or if there is a cycle in the graph. We detect cycles by |
| 2273 // remembering interfaces we've visited in each path through the | 2362 // remembering interfaces we've visited in each path through the |
| 2274 // graph. If we visit an interface a second time on a given path, | 2363 // graph. If we visit an interface a second time on a given path, |
| 2275 // we found a loop. | 2364 // we found a loop. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2657 expected_name ^= String::New("_offset"); | 2746 expected_name ^= String::New("_offset"); |
| 2658 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2747 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2659 field ^= fields_array.At(2); | 2748 field ^= fields_array.At(2); |
| 2660 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2749 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2661 name ^= field.name(); | 2750 name ^= field.name(); |
| 2662 ASSERT(name.Equals("length")); | 2751 ASSERT(name.Equals("length")); |
| 2663 #endif | 2752 #endif |
| 2664 } | 2753 } |
| 2665 | 2754 |
| 2666 } // namespace dart | 2755 } // namespace dart |
| OLD | NEW |