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

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
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 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698