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

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

Issue 23453024: Keep track of type parameter processing in mixin application classes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months 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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 AbstractType& type_argument = AbstractType::Handle(); 504 AbstractType& type_argument = AbstractType::Handle();
505 for (intptr_t i = 0; i < num_arguments; i++) { 505 for (intptr_t i = 0; i < num_arguments; i++) {
506 type_argument = arguments.TypeAt(i); 506 type_argument = arguments.TypeAt(i);
507 ResolveType(cls, type_argument, finalization); 507 ResolveType(cls, type_argument, finalization);
508 } 508 }
509 } 509 }
510 } 510 }
511 511
512 512
513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
514 if (cls.IsMixinApplication()) {
515 // Copy the type parameters to the mixin application.
516 ApplyMixinType(cls);
517 }
514 // The type parameter bounds are not finalized here. 518 // The type parameter bounds are not finalized here.
515 const TypeArguments& type_parameters = 519 const TypeArguments& type_parameters =
516 TypeArguments::Handle(cls.type_parameters()); 520 TypeArguments::Handle(cls.type_parameters());
517 if (!type_parameters.IsNull()) { 521 if (!type_parameters.IsNull()) {
518 TypeParameter& type_parameter = TypeParameter::Handle(); 522 TypeParameter& type_parameter = TypeParameter::Handle();
519 const intptr_t num_types = type_parameters.Length(); 523 const intptr_t num_types = type_parameters.Length();
520 for (intptr_t i = 0; i < num_types; i++) { 524 for (intptr_t i = 0; i < num_types; i++) {
521 type_parameter ^= type_parameters.TypeAt(i); 525 type_parameter ^= type_parameters.TypeAt(i);
522 type_parameter ^= FinalizeType(cls, 526 type_parameter ^= FinalizeType(cls,
523 type_parameter, 527 type_parameter,
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 } 1307 }
1304 } 1308 }
1305 } 1309 }
1306 } 1310 }
1307 1311
1308 1312
1309 // Copy the type parameters of the super and mixin classes to the 1313 // Copy the type parameters of the super and mixin classes to the
1310 // mixin application class. Change type arguments of super type and of 1314 // mixin application class. Change type arguments of super type and of
1311 // interfaces to refer to the respective type parameters of the mixin 1315 // interfaces to refer to the respective type parameters of the mixin
1312 // application class. 1316 // application class.
1313 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { 1317 void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) {
1314 ASSERT(mixapp_class.NumTypeParameters() == 0); 1318 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
1315 1319
1316 const AbstractType& super_type = 1320 const AbstractType& super_type =
1317 AbstractType::Handle(mixapp_class.super_type()); 1321 AbstractType::Handle(mixin_app_class.super_type());
1318 ASSERT(super_type.IsResolved()); 1322 ASSERT(super_type.IsResolved());
1319 const Class& super_class = Class::Handle(super_type.type_class()); 1323 const Class& super_class = Class::Handle(super_type.type_class());
1320 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); 1324 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1321 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1325 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1322 const int num_super_parameters = super_class.NumTypeParameters(); 1326 const int num_super_parameters = super_class.NumTypeParameters();
1323 const int num_mixin_parameters = mixin_class.NumTypeParameters(); 1327 const int num_mixin_parameters = mixin_class.NumTypeParameters();
1324 if ((num_super_parameters + num_mixin_parameters) == 0) { 1328 if ((num_super_parameters + num_mixin_parameters) == 0) {
1325 return; 1329 return;
1326 } 1330 }
1327 1331
1328 // First, clone the super class type parameters. Rename them so that 1332 // First, clone the super class type parameters. Rename them so that
1329 // there can be no name conflict between the parameters of the super 1333 // there can be no name conflict between the parameters of the super
1330 // class and the mixin class. 1334 // class and the mixin class.
1331 const TypeArguments& cloned_type_params = TypeArguments::Handle( 1335 const TypeArguments& cloned_type_params = TypeArguments::Handle(
1332 TypeArguments::New(num_super_parameters + num_mixin_parameters)); 1336 TypeArguments::New(num_super_parameters + num_mixin_parameters));
1333 TypeParameter& param = TypeParameter::Handle(); 1337 TypeParameter& param = TypeParameter::Handle();
1334 TypeParameter& cloned_param = TypeParameter::Handle(); 1338 TypeParameter& cloned_param = TypeParameter::Handle();
1335 String& param_name = String::Handle(); 1339 String& param_name = String::Handle();
1336 AbstractType& param_bound = AbstractType::Handle(); 1340 AbstractType& param_bound = AbstractType::Handle();
1337 int cloned_index = 0; 1341 int cloned_index = 0;
1338 if (num_super_parameters > 0) { 1342 if (num_super_parameters > 0) {
1339 const TypeArguments& super_params = 1343 const TypeArguments& super_params =
1340 TypeArguments::Handle(super_class.type_parameters()); 1344 TypeArguments::Handle(super_class.type_parameters());
1341 const TypeArguments& super_type_args = 1345 const TypeArguments& super_type_args =
1342 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); 1346 TypeArguments::Handle(TypeArguments::New(num_super_parameters));
1343 for (int i = 0; i < num_super_parameters; i++) { 1347 for (int i = 0; i < num_super_parameters; i++) {
1344 param ^= super_params.TypeAt(i); 1348 param ^= super_params.TypeAt(i);
1345 param_name = param.name(); 1349 param_name = param.name();
1346 param_bound = param.bound(); 1350 param_bound = param.bound();
1347 // TODO(hausner): handle type bounds. 1351 // TODO(hausner): handle type bounds.
1348 if (!param_bound.IsObjectType()) { 1352 if (!param_bound.IsObjectType()) {
1349 const Script& script = Script::Handle(mixapp_class.script()); 1353 const Script& script = Script::Handle(mixin_app_class.script());
1350 ReportError(Error::Handle(), // No previous error. 1354 ReportError(Error::Handle(), // No previous error.
1351 script, param.token_pos(), 1355 script, param.token_pos(),
1352 "type parameter '%s': type bounds not yet" 1356 "type parameter '%s': type bounds not yet"
1353 " implemented for mixins\n", 1357 " implemented for mixins\n",
1354 param_name.ToCString()); 1358 param_name.ToCString());
1355 } 1359 }
1356 param_name = String::Concat(param_name, Symbols::Backtick()); 1360 param_name = String::Concat(param_name, Symbols::Backtick());
1357 param_name = Symbols::New(param_name); 1361 param_name = Symbols::New(param_name);
1358 cloned_param = TypeParameter::New(mixapp_class, 1362 cloned_param = TypeParameter::New(mixin_app_class,
1359 cloned_index, 1363 cloned_index,
1360 param_name, 1364 param_name,
1361 param_bound, 1365 param_bound,
1362 param.token_pos()); 1366 param.token_pos());
1363 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1367 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1364 // Change the type arguments of the super type to refer to the 1368 // Change the type arguments of the super type to refer to the
1365 // cloned type parameters of the mixin application class. 1369 // cloned type parameters of the mixin application class.
1366 super_type_args.SetTypeAt(cloned_index, cloned_param); 1370 super_type_args.SetTypeAt(cloned_index, cloned_param);
1367 cloned_index++; 1371 cloned_index++;
1368 } 1372 }
(...skipping 13 matching lines...) Expand all
1382 TypeArguments::Handle(mixin_class.type_parameters()); 1386 TypeArguments::Handle(mixin_class.type_parameters());
1383 const TypeArguments& interface_type_args = TypeArguments::Handle( 1387 const TypeArguments& interface_type_args = TypeArguments::Handle(
1384 TypeArguments::New(num_mixin_parameters)); 1388 TypeArguments::New(num_mixin_parameters));
1385 for (int i = 0; i < num_mixin_parameters; i++) { 1389 for (int i = 0; i < num_mixin_parameters; i++) {
1386 param ^= mixin_params.TypeAt(i); 1390 param ^= mixin_params.TypeAt(i);
1387 param_name = param.name(); 1391 param_name = param.name();
1388 param_bound = param.bound(); 1392 param_bound = param.bound();
1389 1393
1390 // TODO(hausner): handle type bounds. 1394 // TODO(hausner): handle type bounds.
1391 if (!param_bound.IsObjectType()) { 1395 if (!param_bound.IsObjectType()) {
1392 const Script& script = Script::Handle(mixapp_class.script()); 1396 const Script& script = Script::Handle(mixin_app_class.script());
1393 ReportError(Error::Handle(), // No previous error. 1397 ReportError(Error::Handle(), // No previous error.
1394 script, param.token_pos(), 1398 script, param.token_pos(),
1395 "type parameter '%s': type bounds not yet" 1399 "type parameter '%s': type bounds not yet"
1396 " implemented for mixins\n", 1400 " implemented for mixins\n",
1397 param_name.ToCString()); 1401 param_name.ToCString());
1398 } 1402 }
1399 cloned_param = TypeParameter::New(mixapp_class, 1403 cloned_param = TypeParameter::New(mixin_app_class,
1400 cloned_index, 1404 cloned_index,
1401 param_name, 1405 param_name,
1402 param_bound, 1406 param_bound,
1403 param.token_pos()); 1407 param.token_pos());
1404 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1408 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1405 interface_type_args.SetTypeAt(i, cloned_param); 1409 interface_type_args.SetTypeAt(i, cloned_param);
1406 cloned_index++; 1410 cloned_index++;
1407 } 1411 }
1408 1412
1409 // Lastly, change the type arguments of the single interface type to 1413 // Lastly, change the type arguments of the single interface type to
1410 // refer to the cloned type parameters of the mixin application class. 1414 // refer to the cloned type parameters of the mixin application class.
1411 Array& interface_types = Array::Handle(mixapp_class.interfaces()); 1415 Array& interface_types = Array::Handle(mixin_app_class.interfaces());
1412 ASSERT(interface_types.Length() == 1); 1416 ASSERT(interface_types.Length() == 1);
1413 AbstractType& interface_type = AbstractType::Handle(); 1417 AbstractType& interface_type = AbstractType::Handle();
1414 interface_type ^= interface_types.At(0); 1418 interface_type ^= interface_types.At(0);
1415 ASSERT(interface_type.IsResolved()); 1419 ASSERT(interface_type.IsResolved());
1416 // TODO(hausner): May need to handle BoundedType here. 1420 // TODO(hausner): May need to handle BoundedType here.
1417 ASSERT(interface_type.IsType()); 1421 ASSERT(interface_type.IsType());
1418 Type::Cast(interface_type).set_arguments(interface_type_args); 1422 Type::Cast(interface_type).set_arguments(interface_type_args);
1419 ASSERT(!interface_type.IsFinalized()); 1423 ASSERT(!interface_type.IsFinalized());
1420 } 1424 }
1421 mixapp_class.set_type_parameters(cloned_type_params); 1425 mixin_app_class.set_type_parameters(cloned_type_params);
1422 } 1426 }
1423 1427
1424 1428
1425 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { 1429 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) {
1426 const Type& mixin_type = Type::Handle(cls.mixin()); 1430 if (mixin_app_class.is_mixin_type_applied()) {
1431 return;
1432 }
1433 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1427 ASSERT(!mixin_type.IsNull()); 1434 ASSERT(!mixin_type.IsNull());
1428 ASSERT(mixin_type.HasResolvedTypeClass()); 1435 ASSERT(mixin_type.HasResolvedTypeClass());
1429 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 1436 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
1430 1437
1431 if (FLAG_trace_class_finalization) { 1438 if (FLAG_trace_class_finalization) {
1432 OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n", 1439 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
1433 String::Handle(mixin_type.Name()).ToCString(), 1440 String::Handle(mixin_type.Name()).ToCString(),
1434 cls.ToCString(), 1441 mixin_app_class.ToCString(),
1435 cls.token_pos()); 1442 mixin_app_class.token_pos());
1436 } 1443 }
1437 1444
1438 // Check that the super class of the mixin class is extending 1445 // Check that the super class of the mixin class is extending
1439 // class Object. 1446 // class Object.
1440 const AbstractType& mixin_super_type = 1447 const AbstractType& mixin_super_type =
1441 AbstractType::Handle(mixin_cls.super_type()); 1448 AbstractType::Handle(mixin_cls.super_type());
1442 if (!mixin_super_type.IsObjectType()) { 1449 if (!mixin_super_type.IsObjectType()) {
1443 const Script& script = Script::Handle(cls.script()); 1450 const Script& script = Script::Handle(mixin_app_class.script());
1444 const String& class_name = String::Handle(mixin_cls.Name()); 1451 const String& class_name = String::Handle(mixin_cls.Name());
1445 ReportError(Error::Handle(), // No previous error. 1452 ReportError(Error::Handle(), // No previous error.
1446 script, cls.token_pos(), 1453 script, mixin_app_class.token_pos(),
1447 "mixin class %s must extend class Object", 1454 "mixin class '%s' must extend class Object",
1448 class_name.ToCString()); 1455 class_name.ToCString());
1449 } 1456 }
1450 1457
1451 // Copy type parameters to mixin application class. 1458 // Copy type parameters to mixin application class.
1452 CloneTypeParameters(cls); 1459 CloneTypeParameters(mixin_app_class);
1453 1460
1454 if (FLAG_trace_class_finalization) { 1461 if (FLAG_trace_class_finalization) {
1455 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", 1462 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n",
1456 String::Handle(mixin_type.Name()).ToCString(), 1463 String::Handle(mixin_type.Name()).ToCString(),
1457 String::Handle(cls.Name()).ToCString(), 1464 String::Handle(mixin_app_class.Name()).ToCString(),
1458 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1465 TypeArguments::Handle(
1459 AbstractType::Handle(cls.super_type()).ToCString()); 1466 mixin_app_class.type_parameters()).ToCString(),
1467 AbstractType::Handle(mixin_app_class.super_type()).ToCString());
1460 } 1468 }
1469 mixin_app_class.set_is_mixin_type_applied();
1461 } 1470 }
1462 1471
1463 1472
1464 void ClassFinalizer::CreateForwardingConstructors( 1473 void ClassFinalizer::CreateForwardingConstructors(
1465 const Class& mixin_app, 1474 const Class& mixin_app,
1466 const GrowableObjectArray& cloned_funcs) { 1475 const GrowableObjectArray& cloned_funcs) {
1467 const String& mixin_name = String::Handle(mixin_app.Name()); 1476 const String& mixin_name = String::Handle(mixin_app.Name());
1468 const Class& super_class = Class::Handle(mixin_app.SuperClass()); 1477 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1469 const String& super_name = String::Handle(super_class.Name()); 1478 const String& super_name = String::Handle(super_class.Name());
1470 const Type& dynamic_type = Type::Handle(Type::DynamicType()); 1479 const Type& dynamic_type = Type::Handle(Type::DynamicType());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 clone.set_parameter_types(Array::Handle(Array::New(num_parameters))); 1516 clone.set_parameter_types(Array::Handle(Array::New(num_parameters)));
1508 for (intptr_t n = 0; n < num_parameters; n++) { 1517 for (intptr_t n = 0; n < num_parameters; n++) {
1509 clone.SetParameterTypeAt(n, dynamic_type); 1518 clone.SetParameterTypeAt(n, dynamic_type);
1510 } 1519 }
1511 cloned_funcs.Add(clone); 1520 cloned_funcs.Add(clone);
1512 } 1521 }
1513 } 1522 }
1514 } 1523 }
1515 1524
1516 1525
1517 void ClassFinalizer::ApplyMixin(const Class& cls) { 1526 void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
1518 Isolate* isolate = Isolate::Current(); 1527 Isolate* isolate = Isolate::Current();
1519 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); 1528 const Type& mixin_type = Type::Handle(isolate, cls.mixin());
1520 ASSERT(!mixin_type.IsNull()); 1529 ASSERT(!mixin_type.IsNull());
1521 ASSERT(mixin_type.HasResolvedTypeClass()); 1530 ASSERT(mixin_type.HasResolvedTypeClass());
1522 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); 1531 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
1523 mixin_cls.EnsureIsFinalized(isolate); 1532 mixin_cls.EnsureIsFinalized(isolate);
1524 1533
1525 if (FLAG_trace_class_finalization) { 1534 if (FLAG_trace_class_finalization) {
1526 OS::Print("Applying mixin '%s' to '%s' at pos %" Pd "\n", 1535 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n",
1527 String::Handle(mixin_cls.Name()).ToCString(), 1536 mixin_cls.ToCString(),
1528 cls.ToCString(), 1537 cls.ToCString(),
1529 cls.token_pos()); 1538 cls.token_pos());
1530 } 1539 }
1531 1540
1532 const GrowableObjectArray& cloned_funcs = 1541 const GrowableObjectArray& cloned_funcs =
1533 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 1542 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1534 1543
1535 CreateForwardingConstructors(cls, cloned_funcs); 1544 CreateForwardingConstructors(cls, cloned_funcs);
1536 1545
1537 Array& functions = Array::Handle(isolate); 1546 Array& functions = Array::Handle(isolate);
1538 Function& func = Function::Handle(isolate); 1547 Function& func = Function::Handle(isolate);
1539 // The parser creates the mixin application class with no functions. 1548 // The parser creates the mixin application class with no functions.
1540 ASSERT((functions = cls.functions(), functions.Length() == 0)); 1549 ASSERT((functions = cls.functions(), functions.Length() == 0));
1541 // Now clone the functions from the mixin class. 1550 // Now clone the functions from the mixin class.
1542 functions = mixin_cls.functions(); 1551 functions = mixin_cls.functions();
1543 const intptr_t num_functions = functions.Length(); 1552 const intptr_t num_functions = functions.Length();
1544 for (int i = 0; i < num_functions; i++) { 1553 for (int i = 0; i < num_functions; i++) {
1545 func ^= functions.At(i); 1554 func ^= functions.At(i);
1546 if (func.IsConstructor()) { 1555 if (func.IsConstructor()) {
1547 // A mixin class must not have explicit constructors. 1556 // A mixin class must not have explicit constructors.
1548 if (!func.IsImplicitConstructor()) { 1557 if (!func.IsImplicitConstructor()) {
1549 const Script& script = Script::Handle(isolate, cls.script()); 1558 const Script& script = Script::Handle(isolate, cls.script());
1550 ReportError(Error::Handle(), // No previous error. 1559 ReportError(Error::Handle(), // No previous error.
1551 script, cls.token_pos(), 1560 script, cls.token_pos(),
1552 "mixin class %s must not have constructors\n", 1561 "mixin class '%s' must not have constructors\n",
1553 String::Handle(isolate, mixin_cls.Name()).ToCString()); 1562 String::Handle(isolate, mixin_cls.Name()).ToCString());
1554 } 1563 }
1555 continue; // Skip the implicit constructor. 1564 continue; // Skip the implicit constructor.
1556 } 1565 }
1557 if (!func.is_static()) { 1566 if (!func.is_static()) {
1558 func = func.Clone(cls); 1567 func = func.Clone(cls);
1559 cloned_funcs.Add(func); 1568 cloned_funcs.Add(func);
1560 } 1569 }
1561 } 1570 }
1562 functions = Array::MakeArray(cloned_funcs); 1571 functions = Array::MakeArray(cloned_funcs);
(...skipping 11 matching lines...) Expand all
1574 field ^= fields.At(i); 1583 field ^= fields.At(i);
1575 if (!field.is_static()) { 1584 if (!field.is_static()) {
1576 field = field.Clone(cls); 1585 field = field.Clone(cls);
1577 cloned_fields.Add(field); 1586 cloned_fields.Add(field);
1578 } 1587 }
1579 } 1588 }
1580 fields = Array::MakeArray(cloned_fields); 1589 fields = Array::MakeArray(cloned_fields);
1581 cls.SetFields(fields); 1590 cls.SetFields(fields);
1582 1591
1583 if (FLAG_trace_class_finalization) { 1592 if (FLAG_trace_class_finalization) {
1584 OS::Print("done mixin appl '%s' '%s' extending '%s'\n", 1593 OS::Print("done applying mixin members of %s to %s\n",
1585 String::Handle(cls.Name()).ToCString(), 1594 mixin_cls.ToCString(),
1586 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1595 cls.ToCString());
1587 AbstractType::Handle(cls.super_type()).ToCString());
1588 } 1596 }
1589 } 1597 }
1590 1598
1591 1599
1592 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { 1600 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
1593 HANDLESCOPE(Isolate::Current()); 1601 HANDLESCOPE(Isolate::Current());
1594 if (cls.is_type_finalized()) { 1602 if (cls.is_type_finalized()) {
1595 return; 1603 return;
1596 } 1604 }
1597 if (FLAG_trace_class_finalization) { 1605 if (FLAG_trace_class_finalization) {
1598 OS::Print("Finalize types in %s\n", cls.ToCString()); 1606 OS::Print("Finalize types in %s\n", cls.ToCString());
1599 } 1607 }
1600 if (!IsSuperCycleFree(cls)) { 1608 if (!IsSuperCycleFree(cls)) {
1601 const String& name = String::Handle(cls.Name()); 1609 const String& name = String::Handle(cls.Name());
1602 const Script& script = Script::Handle(cls.script()); 1610 const Script& script = Script::Handle(cls.script());
1603 ReportError(Error::Handle(), // No previous error. 1611 ReportError(Error::Handle(), // No previous error.
1604 script, cls.token_pos(), 1612 script, cls.token_pos(),
1605 "class '%s' has a cycle in its superclass relationship", 1613 "class '%s' has a cycle in its superclass relationship",
1606 name.ToCString()); 1614 name.ToCString());
1607 } 1615 }
1608 // Finalize super class. 1616 // Finalize super class.
1609 const Class& super_class = Class::Handle(cls.SuperClass()); 1617 const Class& super_class = Class::Handle(cls.SuperClass());
1610 if (!super_class.IsNull()) { 1618 if (!super_class.IsNull()) {
1611 FinalizeTypesInClass(super_class); 1619 FinalizeTypesInClass(super_class);
1612 } 1620 }
1613 if (cls.mixin() != Type::null()) {
1614 // Copy the type parameters to the mixin application.
1615 ApplyMixinTypes(cls);
1616 }
1617 // Finalize type parameters before finalizing the super type. 1621 // Finalize type parameters before finalizing the super type.
1618 FinalizeTypeParameters(cls); 1622 FinalizeTypeParameters(cls);
1619 ResolveUpperBounds(cls); 1623 ResolveUpperBounds(cls);
1620 // Finalize super type. 1624 // Finalize super type.
1621 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 1625 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1622 if (!super_type.IsNull()) { 1626 if (!super_type.IsNull()) {
1623 // In case of a bound error in the super type in production mode, the 1627 // In case of a bound error in the super type in production mode, the
1624 // finalized super type will be a BoundedType with a malformed bound. 1628 // finalized super type will be a BoundedType with a malformed bound.
1625 // It should not be a problem if the class is written to a snapshot and 1629 // It should not be a problem if the class is written to a snapshot and
1626 // later executed in checked mode. Note that the finalized type argument 1630 // later executed in checked mode. Note that the finalized type argument
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 1721
1718 1722
1719 void ClassFinalizer::FinalizeClass(const Class& cls) { 1723 void ClassFinalizer::FinalizeClass(const Class& cls) {
1720 HANDLESCOPE(Isolate::Current()); 1724 HANDLESCOPE(Isolate::Current());
1721 if (cls.is_finalized()) { 1725 if (cls.is_finalized()) {
1722 return; 1726 return;
1723 } 1727 }
1724 if (FLAG_trace_class_finalization) { 1728 if (FLAG_trace_class_finalization) {
1725 OS::Print("Finalize %s\n", cls.ToCString()); 1729 OS::Print("Finalize %s\n", cls.ToCString());
1726 } 1730 }
1727 if (cls.mixin() != Type::null()) { 1731 if (cls.IsMixinApplication()) {
1728 // Copy instance methods and fields from the mixin class. 1732 // Copy instance methods and fields from the mixin class.
1729 // This has to happen before the check whether the methods of 1733 // This has to happen before the check whether the methods of
1730 // the class conflict with inherited methods. 1734 // the class conflict with inherited methods.
1731 ApplyMixin(cls); 1735 ApplyMixinMembers(cls);
1732 } 1736 }
1733 // Ensure super class is finalized. 1737 // Ensure super class is finalized.
1734 const Class& super = Class::Handle(cls.SuperClass()); 1738 const Class& super = Class::Handle(cls.SuperClass());
1735 if (!super.IsNull()) { 1739 if (!super.IsNull()) {
1736 FinalizeClass(super); 1740 FinalizeClass(super);
1737 } 1741 }
1738 // Mark as parsed and finalized. 1742 // Mark as parsed and finalized.
1739 cls.Finalize(); 1743 cls.Finalize();
1740 // Mixin typedef classes may still lack their implicit constructor. 1744 // Mixin typedef classes may still lack their implicit constructor.
1741 // TODO(regis): Implement mixin typedefs with an alias class. 1745 // TODO(regis): Implement mixin typedefs with an alias class.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 AbstractTypeArguments& type_args = 1857 AbstractTypeArguments& type_args =
1854 AbstractTypeArguments::Handle(type.arguments()); 1858 AbstractTypeArguments::Handle(type.arguments());
1855 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 1859 const intptr_t num_type_parameters = type_class.NumTypeParameters();
1856 const intptr_t num_type_arguments = 1860 const intptr_t num_type_arguments =
1857 type_args.IsNull() ? 0 : type_args.Length(); 1861 type_args.IsNull() ? 0 : type_args.Length();
1858 AbstractType& arg = AbstractType::Handle(); 1862 AbstractType& arg = AbstractType::Handle();
1859 if (num_type_arguments > 0) { 1863 if (num_type_arguments > 0) {
1860 if (num_type_arguments != num_type_parameters) { 1864 if (num_type_arguments != num_type_parameters) {
1861 const Script& script = Script::Handle(cls.script()); 1865 const Script& script = Script::Handle(cls.script());
1862 const String& type_class_name = String::Handle(type_class.Name()); 1866 const String& type_class_name = String::Handle(type_class.Name());
1867 // TODO(regis): This should not be a compile time error anymore.
1863 ReportError(Error::Handle(), // No previous error. 1868 ReportError(Error::Handle(), // No previous error.
1864 script, type.token_pos(), 1869 script, type.token_pos(),
1865 "wrong number of type arguments for class '%s'", 1870 "wrong number of type arguments for class '%s'",
1866 type_class_name.ToCString()); 1871 type_class_name.ToCString());
1867 } 1872 }
1868 for (int i = 0; i < num_type_arguments; i++) { 1873 for (int i = 0; i < num_type_arguments; i++) {
1869 arg = type_args.TypeAt(i); 1874 arg = type_args.TypeAt(i);
1870 collected_args.Add(arg); 1875 collected_args.Add(arg);
1871 } 1876 }
1872 } else { 1877 } else {
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 expected_name ^= String::New("_offset"); 2327 expected_name ^= String::New("_offset");
2323 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2328 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2324 field ^= fields_array.At(2); 2329 field ^= fields_array.At(2);
2325 ASSERT(field.Offset() == TypedDataView::length_offset()); 2330 ASSERT(field.Offset() == TypedDataView::length_offset());
2326 name ^= field.name(); 2331 name ^= field.name();
2327 ASSERT(name.Equals("length")); 2332 ASSERT(name.Equals("length"));
2328 #endif 2333 #endif
2329 } 2334 }
2330 2335
2331 } // namespace dart 2336 } // 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