Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 42723003: Register synthesized mixin application classes in the library and reuse them (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698