Chromium Code Reviews| 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 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 // Copy the type parameters of the super and mixin classes to the |
| 1363 // mixin application class. Change type arguments of super type and of | 1363 // mixin application class. Change type arguments of super type, mixin type, and |
| 1364 // interfaces to refer to the respective type parameters of the mixin | 1364 // only interface to refer to the respective type parameters of the mixin |
|
siva
2013/10/25 16:55:53
I am finding it hard to parse this comment.
hausner
2013/10/25 17:11:49
what are "only" interfaces?
regis
2013/10/25 18:34:25
Clarified and added an example.
regis
2013/10/25 18:34:25
Bad wording. The mixin application class has a uni
| |
| 1365 // application class. | 1365 // application class. |
| 1366 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1366 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
| 1367 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); | 1367 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); |
| 1368 const AbstractType& super_type = AbstractType::Handle( | 1368 const AbstractType& super_type = AbstractType::Handle( |
| 1369 mixin_app_class.super_type()); | 1369 mixin_app_class.super_type()); |
| 1370 ASSERT(super_type.IsResolved()); | 1370 ASSERT(super_type.IsResolved()); |
| 1371 const Class& super_class = Class::Handle(super_type.type_class()); | 1371 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1372 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1372 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1373 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1373 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1374 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1374 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1375 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1375 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1376 // The mixin class cannot be Object and this was checked earlier. | 1376 // The mixin class cannot be Object and this was checked earlier. |
| 1377 ASSERT(!mixin_class.IsObjectClass()); | 1377 ASSERT(!mixin_class.IsObjectClass()); |
| 1378 | 1378 |
| 1379 // Add the mixin type to the interfaces that the mixin application | 1379 // Add the mixin type to the interfaces that the mixin application |
| 1380 // class implements. This is necessary so that type tests work. | 1380 // class implements. This is necessary so that type tests work. |
| 1381 const Array& interfaces = Array::Handle(Array::New(1)); | 1381 const Array& interfaces = Array::Handle(Array::New(1)); |
| 1382 const Type& interface = Type::Handle(Type::New( | 1382 const Type& interface = Type::Handle(Type::New( |
| 1383 mixin_class, | 1383 mixin_class, |
| 1384 Object::null_abstract_type_arguments(), // Set again below if generic. | 1384 Object::null_abstract_type_arguments(), // Set again below if generic. |
| 1385 mixin_app_class.token_pos())); | 1385 mixin_app_class.token_pos())); |
| 1386 ASSERT(!interface.IsFinalized()); | 1386 ASSERT(!interface.IsFinalized()); |
| 1387 interfaces.SetAt(0, interface); | 1387 interfaces.SetAt(0, interface); |
| 1388 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | |
| 1388 mixin_app_class.set_interfaces(interfaces); | 1389 mixin_app_class.set_interfaces(interfaces); |
| 1389 | 1390 |
| 1390 // If both the super type and the mixin type are non generic, the mixin | 1391 // 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 | 1392 // application class is non generic as well and we can skip type parameter |
| 1392 // cloning. | 1393 // cloning. |
| 1393 if ((num_super_type_params + num_mixin_type_params) > 0) { | 1394 if ((num_super_type_params + num_mixin_type_params) > 0) { |
| 1394 // First, clone the super class type parameters. Rename them so that | 1395 // First, clone the super class type parameters. Rename them so that |
| 1395 // there can be no name conflict between the parameters of the super | 1396 // there can be no name conflict between the parameters of the super |
| 1396 // class and the mixin class. | 1397 // class and the mixin class. |
| 1397 const TypeArguments& cloned_type_params = TypeArguments::Handle( | 1398 const TypeArguments& cloned_type_params = TypeArguments::Handle( |
| 1398 TypeArguments::New(num_super_type_params + num_mixin_type_params)); | 1399 TypeArguments::New(num_super_type_params + num_mixin_type_params)); |
| 1399 TypeParameter& param = TypeParameter::Handle(); | 1400 TypeParameter& param = TypeParameter::Handle(); |
| 1400 TypeParameter& cloned_param = TypeParameter::Handle(); | 1401 TypeParameter& cloned_param = TypeParameter::Handle(); |
| 1401 String& param_name = String::Handle(); | 1402 String& param_name = String::Handle(); |
| 1402 AbstractType& param_bound = AbstractType::Handle(); | 1403 AbstractType& param_bound = AbstractType::Handle(); |
| 1403 intptr_t cloned_index = 0; | 1404 intptr_t cloned_index = 0; |
| 1404 if (num_super_type_params > 0) { | 1405 if (num_super_type_params > 0) { |
| 1405 const TypeArguments& super_type_params = | 1406 const TypeArguments& super_type_params = |
| 1406 TypeArguments::Handle(super_class.type_parameters()); | 1407 TypeArguments::Handle(super_class.type_parameters()); |
| 1407 const TypeArguments& super_type_args = | 1408 const TypeArguments& super_type_args = |
| 1408 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); | 1409 TypeArguments::Handle(TypeArguments::New(num_super_type_params)); |
| 1409 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1410 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 1410 param ^= super_type_params.TypeAt(i); | 1411 param ^= super_type_params.TypeAt(i); |
| 1411 param_name = param.name(); | 1412 param_name = param.name(); |
| 1412 param_bound = param.bound(); | 1413 param_bound = param.bound(); |
| 1413 // TODO(hausner): handle type bounds. | 1414 // TODO(regis): handle type bounds. |
|
siva
2013/10/25 16:55:53
maybe open an issue and use the issue number here
hausner
2013/10/25 17:11:49
Thank you :-)
regis
2013/10/25 18:34:25
Issue 14453 filed.
regis
2013/10/25 18:34:25
Oh good, I was afraid you would be upset I grab it
| |
| 1414 if (!param_bound.IsObjectType()) { | 1415 if (!param_bound.IsObjectType()) { |
| 1415 const Script& script = Script::Handle(mixin_app_class.script()); | 1416 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1416 ReportError(Error::Handle(), // No previous error. | 1417 ReportError(Error::Handle(), // No previous error. |
| 1417 script, param.token_pos(), | 1418 script, param.token_pos(), |
| 1418 "type parameter '%s': type bounds not yet" | 1419 "type parameter '%s': type bounds not yet" |
| 1419 " implemented for mixins\n", | 1420 " implemented for mixins\n", |
| 1420 param_name.ToCString()); | 1421 param_name.ToCString()); |
| 1421 } | 1422 } |
| 1422 param_name = String::Concat(param_name, Symbols::Backtick()); | 1423 param_name = String::Concat(param_name, Symbols::Backtick()); |
| 1423 param_name = Symbols::New(param_name); | 1424 param_name = Symbols::New(param_name); |
| 1424 cloned_param = TypeParameter::New(mixin_app_class, | 1425 cloned_param = TypeParameter::New(mixin_app_class, |
| 1425 cloned_index, | 1426 cloned_index, |
| 1426 param_name, | 1427 param_name, |
| 1427 param_bound, | 1428 param_bound, |
| 1428 param.token_pos()); | 1429 param.token_pos()); |
| 1429 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1430 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1430 // Change the type arguments of the super type to refer to the | 1431 // Change the type arguments of the super type to refer to the |
| 1431 // cloned type parameters of the mixin application class. | 1432 // cloned type parameters of the mixin application class. |
| 1432 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1433 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1433 cloned_index++; | 1434 cloned_index++; |
| 1434 } | 1435 } |
| 1435 // TODO(hausner): May need to handle BoundedType here. | 1436 // TODO(regis): May need to handle BoundedType here. |
| 1436 ASSERT(super_type.IsType()); | 1437 ASSERT(super_type.IsType()); |
| 1437 Type::Cast(super_type).set_arguments(super_type_args); | 1438 Type::Cast(super_type).set_arguments(super_type_args); |
| 1438 ASSERT(!super_type.IsFinalized()); | 1439 ASSERT(!super_type.IsFinalized()); |
| 1439 } | 1440 } |
| 1440 | 1441 |
| 1441 // Second, clone the type parameters of the mixin class. | 1442 // Second, clone the type parameters of the mixin class. |
| 1442 // We need to retain the parameter names of the mixin class | 1443 // We need to retain the parameter names of the mixin class |
| 1443 // since the code that will be compiled in the context of the | 1444 // since the code that will be compiled in the context of the |
| 1444 // mixin application class may refer to the type parameters | 1445 // mixin application class may refer to the type parameters |
| 1445 // with that name. | 1446 // with that name. |
| 1446 if (num_mixin_type_params > 0) { | 1447 if (num_mixin_type_params > 0) { |
| 1447 const TypeArguments& mixin_params = | 1448 const TypeArguments& mixin_params = |
| 1448 TypeArguments::Handle(mixin_class.type_parameters()); | 1449 TypeArguments::Handle(mixin_class.type_parameters()); |
| 1450 const TypeArguments& mixin_type_args = TypeArguments::Handle( | |
| 1451 TypeArguments::New(num_mixin_type_params)); | |
| 1452 // TODO(regis): Can we share interface type and mixin_type? | |
| 1449 const TypeArguments& interface_type_args = TypeArguments::Handle( | 1453 const TypeArguments& interface_type_args = TypeArguments::Handle( |
| 1450 TypeArguments::New(num_mixin_type_params)); | 1454 TypeArguments::New(num_mixin_type_params)); |
| 1451 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1455 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1452 param ^= mixin_params.TypeAt(i); | 1456 param ^= mixin_params.TypeAt(i); |
| 1453 param_name = param.name(); | 1457 param_name = param.name(); |
| 1454 param_bound = param.bound(); | 1458 param_bound = param.bound(); |
| 1455 | 1459 |
| 1456 // TODO(hausner): handle type bounds. | 1460 // TODO(regis): handle type bounds. |
| 1457 if (!param_bound.IsObjectType()) { | 1461 if (!param_bound.IsObjectType()) { |
| 1458 const Script& script = Script::Handle(mixin_app_class.script()); | 1462 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1459 ReportError(Error::Handle(), // No previous error. | 1463 ReportError(Error::Handle(), // No previous error. |
| 1460 script, param.token_pos(), | 1464 script, param.token_pos(), |
| 1461 "type parameter '%s': type bounds not yet" | 1465 "type parameter '%s': type bounds not yet" |
| 1462 " implemented for mixins\n", | 1466 " implemented for mixins\n", |
| 1463 param_name.ToCString()); | 1467 param_name.ToCString()); |
| 1464 } | 1468 } |
| 1465 cloned_param = TypeParameter::New(mixin_app_class, | 1469 cloned_param = TypeParameter::New(mixin_app_class, |
| 1466 cloned_index, | 1470 cloned_index, |
| 1467 param_name, | 1471 param_name, |
| 1468 param_bound, | 1472 param_bound, |
| 1469 param.token_pos()); | 1473 param.token_pos()); |
| 1470 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1474 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1471 interface_type_args.SetTypeAt(i, cloned_param); | 1475 interface_type_args.SetTypeAt(i, cloned_param); |
| 1476 mixin_type_args.SetTypeAt(i, cloned_param); | |
| 1472 cloned_index++; | 1477 cloned_index++; |
| 1473 } | 1478 } |
| 1474 | 1479 |
| 1475 // Lastly, set the type arguments of the single interface type. | 1480 // Lastly, set the type arguments of the mixin type and of the single |
| 1481 // interface type. | |
| 1482 ASSERT(!mixin_type.IsFinalized()); | |
| 1483 mixin_type.set_arguments(mixin_type_args); | |
| 1476 ASSERT(!interface.IsFinalized()); | 1484 ASSERT(!interface.IsFinalized()); |
| 1477 interface.set_arguments(interface_type_args); | 1485 interface.set_arguments(interface_type_args); |
| 1478 } | 1486 } |
| 1479 mixin_app_class.set_type_parameters(cloned_type_params); | 1487 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1480 } | 1488 } |
| 1481 // If the mixin class is a mixin application typedef class, we insert a new | 1489 // 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 | 1490 // synthesized mixin application class in the super chain of this mixin |
| 1483 // 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 |
| 1484 // mixin. | 1492 // mixin. |
| 1485 if (mixin_class.is_mixin_typedef()) { | 1493 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 | 1545 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 | 1546 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 | 1547 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 | 1548 step with a properly crafted instantiator vector takes care of the required type |
| 1541 parameter substitution. | 1549 parameter substitution. |
| 1542 | 1550 |
| 1543 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. |
| 1544 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 |
| 1545 of type parameter U of A. | 1553 of type parameter U of A. |
| 1546 */ | 1554 */ |
| 1547 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { | 1555 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) { |
|
hausner
2013/10/25 17:11:49
Unrelated to this change, but maybe it's time to r
regis
2013/10/25 18:34:25
Right. We also have a is_mixin_typedef() function.
| |
| 1548 // If this mixin typedef is aliasing another mixin typedef, another class | 1556 // If this mixin typedef is aliasing another mixin typedef, another class |
| 1549 // will be inserted via recursion. No need to check here. | 1557 // will be inserted via recursion. No need to check here. |
| 1550 // The mixin type may or may not be finalized yet. | 1558 // The mixin type may or may not be finalized yet. |
| 1559 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type()); | |
| 1551 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 1560 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1552 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1561 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1553 ASSERT(mixin_class.is_mixin_typedef()); | 1562 ASSERT(mixin_class.is_mixin_typedef()); |
| 1554 const Class& aliased_mixin_app_class = Class::Handle( | 1563 const Class& aliased_mixin_app_class = Class::Handle( |
| 1555 mixin_class.SuperClass()); | 1564 mixin_class.SuperClass()); |
| 1556 const Type& aliased_mixin_type = Type::Handle( | 1565 const Type& aliased_mixin_type = Type::Handle( |
| 1557 aliased_mixin_app_class.mixin()); | 1566 aliased_mixin_app_class.mixin()); |
| 1558 // 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 |
| 1559 // class name with a backtick added. | 1568 // class name with a backtick added. |
| 1560 String& inserted_class_name = String::Handle(mixin_app_class.Name()); | 1569 String& inserted_class_name = String::Handle(mixin_app_class.Name()); |
| 1561 inserted_class_name = String::Concat(inserted_class_name, | 1570 inserted_class_name = String::Concat(inserted_class_name, |
| 1562 Symbols::Backtick()); | 1571 Symbols::Backtick()); |
| 1563 inserted_class_name = Symbols::New(inserted_class_name); | 1572 inserted_class_name = Symbols::New(inserted_class_name); |
| 1564 const Script& script = Script::Handle(mixin_app_class.script()); | 1573 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1565 const Library& library = Library::Handle(mixin_app_class.library()); | 1574 const Library& library = Library::Handle(mixin_app_class.library()); |
| 1566 const Class& inserted_class = Class::Handle(Class::New( | 1575 Class& inserted_class = Class::Handle(); |
| 1567 inserted_class_name, script, mixin_app_class.token_pos())); | 1576 inserted_class = library.LookupLocalClass(inserted_class_name); |
| 1568 inserted_class.set_library(library); | 1577 if (inserted_class.IsNull()) { |
| 1569 inserted_class.set_is_synthesized_class(); | 1578 inserted_class = Class::New( |
| 1579 inserted_class_name, script, mixin_app_class.token_pos()); | |
| 1580 inserted_class.set_is_synthesized_class(); | |
| 1581 library.AddClass(inserted_class); | |
| 1570 | 1582 |
| 1571 // The super type of the inserted class is identical to the super type of | 1583 if (FLAG_trace_class_finalization) { |
| 1572 // this mixin application class, except that it must refer to the type | 1584 OS::Print("Creating mixin typedef application %s\n", |
| 1573 // parameters of the inserted class rather than to those of the mixin | 1585 inserted_class.ToCString()); |
| 1574 // application class. | 1586 } |
| 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 | 1587 |
| 1581 // The mixin type must also be set before calling CloneMixinAppTypeParameters. | 1588 // 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. | 1589 // 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. | 1590 // parameters of the inserted class rather than to those of the mixin |
| 1591 // application class. | |
| 1592 // The type arguments of the super type will be set properly when calling | |
| 1593 // CloneMixinAppTypeParameters on the inserted class, as long as the super | |
| 1594 // type class is set properly. | |
| 1595 inserted_class.set_super_type(super_type); // Super class only is used. | |
| 1596 | |
| 1597 // The mixin type and interface type must also be set before calling | |
| 1598 // CloneMixinAppTypeParameters. | |
| 1599 // After FinalizeTypesInClass, they will refer to the type parameters of | |
| 1600 // the mixin class typedef. | |
| 1601 const Type& generic_mixin_type = Type::Handle( | |
| 1602 Type::New(Class::Handle(aliased_mixin_type.type_class()), | |
| 1603 Object::null_abstract_type_arguments(), | |
| 1604 aliased_mixin_type.token_pos())); | |
| 1605 inserted_class.set_mixin(generic_mixin_type); | |
| 1606 // The interface will be set in CloneMixinAppTypeParameters. | |
| 1607 } | |
| 1584 | 1608 |
| 1585 // Finalize the types and call CloneMixinAppTypeParameters. | 1609 // Finalize the types and call CloneMixinAppTypeParameters. |
| 1586 FinalizeTypesInClass(inserted_class); | 1610 FinalizeTypesInClass(inserted_class); |
| 1587 | 1611 |
| 1588 // 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 |
| 1589 // inserted class. The super type arguments are the concatenation of the | 1613 // inserted class. The super type arguments are the concatenation of the |
| 1590 // old super type arguments (propagating type arguments to the super class) | 1614 // old super type arguments (propagating type arguments to the super class) |
| 1591 // with new type arguments providing type arguments to the mixin. | 1615 // with new type arguments providing type arguments to the mixin. |
| 1592 // The appended type arguments are those of the aliased mixin type, except | 1616 // The appended type arguments are those of the super type of the mixin |
| 1617 // typedef that are forwarding to the aliased mixin type, except | |
| 1593 // 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 |
| 1594 // class rather than to those of the aliased mixin class. | 1619 // class rather than to those of the mixin typedef class. |
| 1595 // This type parameter substitution is performed by an instantiation step. | 1620 // This type parameter substitution is performed by an instantiation step. |
| 1596 // 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 |
| 1597 // 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 |
| 1598 // to the super class. | 1623 // to the super class. |
| 1599 Class& super_class = Class::Handle(super_type.type_class()); | 1624 Class& super_class = Class::Handle(super_type.type_class()); |
| 1600 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); | 1625 ASSERT(mixin_app_class.SuperClass() == super_class.raw()); |
| 1601 while (super_class.IsMixinApplication()) { | 1626 while (super_class.IsMixinApplication()) { |
| 1602 super_class = super_class.SuperClass(); | 1627 super_class = super_class.SuperClass(); |
| 1603 } | 1628 } |
| 1604 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1629 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( | 1643 const Class& aliased_mixin_type_class = Class::Handle( |
| 1619 aliased_mixin_type.type_class()); | 1644 aliased_mixin_type.type_class()); |
| 1620 const intptr_t num_aliased_mixin_type_params = | 1645 const intptr_t num_aliased_mixin_type_params = |
| 1621 aliased_mixin_type_class.NumTypeParameters(); | 1646 aliased_mixin_type_class.NumTypeParameters(); |
| 1622 const intptr_t num_aliased_mixin_type_args = | 1647 const intptr_t num_aliased_mixin_type_args = |
| 1623 aliased_mixin_type_class.NumTypeArguments(); | 1648 aliased_mixin_type_class.NumTypeArguments(); |
| 1624 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; | 1649 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; |
| 1625 ASSERT(inserted_class.NumTypeParameters() == | 1650 ASSERT(inserted_class.NumTypeParameters() == |
| 1626 (num_super_type_params + num_aliased_mixin_type_params)); | 1651 (num_super_type_params + num_aliased_mixin_type_params)); |
| 1627 // The aliased_mixin_type may be raw. | 1652 // The aliased_mixin_type may be raw. |
| 1628 const AbstractTypeArguments& aliased_mixin_type_args = | 1653 const AbstractTypeArguments& mixin_class_super_type_args = |
| 1629 AbstractTypeArguments::Handle(aliased_mixin_type.arguments()); | 1654 AbstractTypeArguments::Handle( |
| 1655 AbstractType::Handle(mixin_class.super_type()).arguments()); | |
| 1630 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); | 1656 TypeArguments& new_mixin_type_args = TypeArguments::Handle(); |
| 1631 if ((num_aliased_mixin_type_params > 0) && | 1657 if ((num_aliased_mixin_type_params > 0) && |
| 1632 !aliased_mixin_type_args.IsNull()) { | 1658 !mixin_class_super_type_args.IsNull()) { |
| 1633 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); | 1659 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); |
| 1634 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1660 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
| 1635 type = aliased_mixin_type_args.TypeAt(offset + i); | 1661 type = mixin_class_super_type_args.TypeAt(offset + i); |
| 1636 new_mixin_type_args.SetTypeAt(i, type); | 1662 new_mixin_type_args.SetTypeAt(i, type); |
| 1637 } | 1663 } |
| 1638 } | 1664 } |
| 1639 if (!new_mixin_type_args.IsNull() && | 1665 if (!new_mixin_type_args.IsNull() && |
| 1640 !new_mixin_type_args.IsInstantiated()) { | 1666 !new_mixin_type_args.IsInstantiated()) { |
| 1641 Error& bound_error = Error::Handle(); | 1667 Error& bound_error = Error::Handle(); |
| 1642 new_mixin_type_args ^= | 1668 new_mixin_type_args ^= |
| 1643 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); | 1669 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error); |
| 1644 // TODO(regis): Handle bound error. | 1670 // TODO(regis): Handle bound error. |
| 1645 ASSERT(bound_error.IsNull()); | 1671 ASSERT(bound_error.IsNull()); |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2217 // Discard provided type arguments and treat type as raw. | 2243 // Discard provided type arguments and treat type as raw. |
| 2218 } | 2244 } |
| 2219 // Fill arguments with type dynamic. | 2245 // Fill arguments with type dynamic. |
| 2220 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2246 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 2221 arg = Type::DynamicType(); | 2247 arg = Type::DynamicType(); |
| 2222 collected_args.Add(arg); | 2248 collected_args.Add(arg); |
| 2223 } | 2249 } |
| 2224 } | 2250 } |
| 2225 | 2251 |
| 2226 | 2252 |
| 2227 RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls, | 2253 RawType* ClassFinalizer::ResolveMixinAppType( |
| 2228 const MixinAppType& mixin_app) { | 2254 const Class& cls, |
| 2229 // Resolve super type and all mixin types. | 2255 const MixinAppType& mixin_app_type) { |
| 2256 // Lookup or create mixin application classes in the library of cls | |
| 2257 // and resolve super type and mixin types. | |
| 2258 const Library& library = Library::Handle(cls.library()); | |
| 2259 ASSERT(!library.IsNull()); | |
| 2260 const Script& script = Script::Handle(cls.script()); | |
| 2261 ASSERT(!script.IsNull()); | |
| 2230 const GrowableObjectArray& type_args = | 2262 const GrowableObjectArray& type_args = |
| 2231 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2263 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2232 AbstractType& type = AbstractType::Handle(mixin_app.SuperType()); | 2264 AbstractType& mixin_super_type = |
| 2233 ResolveType(cls, type, kCanonicalizeWellFormed); | 2265 AbstractType::Handle(mixin_app_type.super_type()); |
| 2234 ASSERT(type.HasResolvedTypeClass()); | 2266 ResolveType(cls, mixin_super_type, kCanonicalizeWellFormed); |
| 2235 // TODO(hausner): May need to handle BoundedType here. | 2267 ASSERT(mixin_super_type.HasResolvedTypeClass()); |
| 2236 ASSERT(type.IsType()); | 2268 // TODO(regis): May need to handle BoundedType here. |
| 2237 CollectTypeArguments(cls, Type::Cast(type), type_args); | 2269 ASSERT(mixin_super_type.IsType()); |
| 2270 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | |
| 2271 AbstractType& mixin_type = AbstractType::Handle(); | |
| 2272 Type& generic_mixin_type = Type::Handle(); | |
| 2238 Class& mixin_app_class = Class::Handle(); | 2273 Class& mixin_app_class = Class::Handle(); |
| 2239 const intptr_t depth = mixin_app.Depth(); | 2274 String& mixin_app_class_name = String::Handle(); |
| 2275 String& mixin_type_class_name = String::Handle(); | |
| 2276 const intptr_t depth = mixin_app_type.Depth(); | |
| 2240 for (intptr_t i = 0; i < depth; i++) { | 2277 for (intptr_t i = 0; i < depth; i++) { |
| 2241 mixin_app_class = mixin_app.MixinAppAt(i); | 2278 mixin_type = mixin_app_type.MixinTypeAt(i); |
| 2242 type = mixin_app_class.mixin(); | 2279 ASSERT(!mixin_type.IsNull()); |
| 2243 ASSERT(!type.IsNull()); | 2280 ResolveType(cls, mixin_type, kCanonicalizeWellFormed); |
| 2244 ResolveType(cls, type, kCanonicalizeWellFormed); | 2281 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 2245 ASSERT(type.HasResolvedTypeClass()); | 2282 ASSERT(mixin_type.IsType()); |
| 2246 ASSERT(type.IsType()); | 2283 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
| 2247 CollectTypeArguments(cls, Type::Cast(type), type_args); | 2284 |
| 2285 // The name of the mixin application class is a combination of | |
| 2286 // the super class name and mixin class name. | |
| 2287 mixin_app_class_name = mixin_super_type.ClassName(); | |
| 2288 mixin_app_class_name = String::Concat(mixin_app_class_name, | |
| 2289 Symbols::Ampersand()); | |
| 2290 mixin_type_class_name = mixin_type.ClassName(); | |
| 2291 mixin_app_class_name = String::Concat(mixin_app_class_name, | |
| 2292 mixin_type_class_name); | |
| 2293 mixin_app_class_name = Symbols::New(mixin_app_class_name); | |
|
siva
2013/10/25 16:55:53
I am wondering if it makes sense to only make it a
regis
2013/10/25 18:34:25
Good point. I moved the line inside the if branch.
| |
| 2294 | |
| 2295 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | |
| 2296 if (mixin_app_class.IsNull()) { | |
| 2297 mixin_app_class = Class::New(mixin_app_class_name, | |
| 2298 script, | |
| 2299 mixin_type.token_pos()); | |
| 2300 mixin_app_class.set_super_type(mixin_super_type); | |
| 2301 generic_mixin_type = Type::New(Class::Handle(mixin_type.type_class()), | |
|
siva
2013/10/25 16:55:53
maybe have a mixin_type_class handle outside the l
regis
2013/10/25 18:34:25
Done.
| |
| 2302 Object::null_abstract_type_arguments(), | |
| 2303 mixin_type.token_pos()); | |
| 2304 mixin_app_class.set_mixin(generic_mixin_type); | |
| 2305 mixin_app_class.set_is_synthesized_class(); | |
| 2306 library.AddClass(mixin_app_class); | |
| 2307 | |
| 2308 // No need to add the new class to pending_classes, since it will be | |
| 2309 // processed via the super_type chain of a pending class. | |
| 2310 | |
| 2311 if (FLAG_trace_class_finalization) { | |
| 2312 OS::Print("Creating mixin application %s\n", | |
| 2313 mixin_app_class.ToCString()); | |
| 2314 } | |
| 2315 } | |
| 2316 // This mixin application class becomes the type class of the super type of | |
| 2317 // the next mixin application class. It is however too early to provide the | |
| 2318 // correct super type arguments. We use the raw type for now. | |
| 2319 mixin_super_type = Type::New(mixin_app_class, | |
| 2320 Object::null_abstract_type_arguments(), | |
| 2321 mixin_type.token_pos()); | |
| 2248 } | 2322 } |
| 2323 AbstractType& type_arg = AbstractType::Handle(); | |
| 2249 const TypeArguments& mixin_app_args = | 2324 const TypeArguments& mixin_app_args = |
| 2250 TypeArguments::Handle(TypeArguments::New(type_args.Length())); | 2325 TypeArguments::Handle(TypeArguments::New(type_args.Length())); |
| 2251 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2326 for (intptr_t i = 0; i < type_args.Length(); i++) { |
| 2252 type ^= type_args.At(i); | 2327 type_arg ^= type_args.At(i); |
| 2253 mixin_app_args.SetTypeAt(i, type); | 2328 mixin_app_args.SetTypeAt(i, type_arg); |
| 2254 } | 2329 } |
| 2255 if (FLAG_trace_class_finalization) { | 2330 if (FLAG_trace_class_finalization) { |
| 2256 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", | 2331 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", |
| 2257 mixin_app_args.ToCString()); | 2332 mixin_app_args.ToCString()); |
| 2258 } | 2333 } |
| 2259 // The mixin application class at depth k is a subclass of mixin application | 2334 // 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 | 2335 // 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 | 2336 // 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. | 2337 // collected type arguments from the super type and all mixin types. |
| 2263 // This super type replaces the MixinAppType object in the class that extends | 2338 // This super type replaces the MixinAppType object in the class that extends |
| 2264 // the mixin application. | 2339 // the mixin application. |
| 2265 return Type::New(mixin_app_class, mixin_app_args, mixin_app.token_pos()); | 2340 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); |
| 2266 } | 2341 } |
| 2267 | 2342 |
| 2268 | 2343 |
| 2269 // Recursively walks the graph of explicitly declared super type and | 2344 // Recursively walks the graph of explicitly declared super type and |
| 2270 // interfaces, resolving unresolved super types and interfaces. | 2345 // interfaces, resolving unresolved super types and interfaces. |
| 2271 // Reports an error if there is an interface reference that cannot be | 2346 // 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 | 2347 // 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 | 2348 // remembering interfaces we've visited in each path through the |
| 2274 // graph. If we visit an interface a second time on a given path, | 2349 // graph. If we visit an interface a second time on a given path, |
| 2275 // we found a loop. | 2350 // we found a loop. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2657 expected_name ^= String::New("_offset"); | 2732 expected_name ^= String::New("_offset"); |
| 2658 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2733 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2659 field ^= fields_array.At(2); | 2734 field ^= fields_array.At(2); |
| 2660 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2735 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2661 name ^= field.name(); | 2736 name ^= field.name(); |
| 2662 ASSERT(name.Equals("length")); | 2737 ASSERT(name.Equals("length")); |
| 2663 #endif | 2738 #endif |
| 2664 } | 2739 } |
| 2665 | 2740 |
| 2666 } // namespace dart | 2741 } // namespace dart |
| OLD | NEW |