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

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

Issue 24397002: Support mixin application typedef as mixin in the VM (issues 9383, 12773). (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.cc » ('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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 288 }
289 289
290 290
291 void ClassFinalizer::ResolveRedirectingFactoryTarget( 291 void ClassFinalizer::ResolveRedirectingFactoryTarget(
292 const Class& cls, 292 const Class& cls,
293 const Function& factory, 293 const Function& factory,
294 const GrowableObjectArray& visited_factories) { 294 const GrowableObjectArray& visited_factories) {
295 ASSERT(factory.IsRedirectingFactory()); 295 ASSERT(factory.IsRedirectingFactory());
296 296
297 // Check for redirection cycle. 297 // Check for redirection cycle.
298 for (int i = 0; i < visited_factories.Length(); i++) { 298 for (intptr_t i = 0; i < visited_factories.Length(); i++) {
299 if (visited_factories.At(i) == factory.raw()) { 299 if (visited_factories.At(i) == factory.raw()) {
300 // A redirection cycle is reported as a compile-time error. 300 // A redirection cycle is reported as a compile-time error.
301 const Script& script = Script::Handle(cls.script()); 301 const Script& script = Script::Handle(cls.script());
302 ReportError(Error::Handle(), // No previous error. 302 ReportError(Error::Handle(), // No previous error.
303 script, factory.token_pos(), 303 script, factory.token_pos(),
304 "factory '%s' illegally redirects to itself", 304 "factory '%s' illegally redirects to itself",
305 String::Handle(factory.name()).ToCString()); 305 String::Handle(factory.name()).ToCString());
306 } 306 }
307 } 307 }
308 visited_factories.Add(factory); 308 visited_factories.Add(factory);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 ResolveType(cls, type_argument, finalization); 499 ResolveType(cls, type_argument, finalization);
500 } 500 }
501 } 501 }
502 } 502 }
503 503
504 504
505 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 505 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
506 if (cls.IsMixinApplication()) { 506 if (cls.IsMixinApplication()) {
507 // Copy the type parameters to the mixin application. 507 // Copy the type parameters to the mixin application.
508 ApplyMixinType(cls); 508 ApplyMixinType(cls);
509 // Finalize the mixin type.
510 Type& mixin_type = Type::Handle(cls.mixin());
511 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed);
512 // TODO(regis): Check for a malbounded mixin_type.
513 cls.set_mixin(mixin_type);
509 } 514 }
510 // The type parameter bounds are not finalized here. 515 // The type parameter bounds are not finalized here.
511 const TypeArguments& type_parameters = 516 const TypeArguments& type_parameters =
512 TypeArguments::Handle(cls.type_parameters()); 517 TypeArguments::Handle(cls.type_parameters());
513 if (!type_parameters.IsNull()) { 518 if (!type_parameters.IsNull()) {
514 TypeParameter& type_parameter = TypeParameter::Handle(); 519 TypeParameter& type_parameter = TypeParameter::Handle();
515 const intptr_t num_types = type_parameters.Length(); 520 const intptr_t num_types = type_parameters.Length();
516 for (intptr_t i = 0; i < num_types; i++) { 521 for (intptr_t i = 0; i < num_types; i++) {
517 type_parameter ^= type_parameters.TypeAt(i); 522 type_parameter ^= type_parameters.TypeAt(i);
518 type_parameter ^= FinalizeType(cls, 523 type_parameter ^= FinalizeType(cls,
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 Function& overridden_function = Function::Handle(); 1199 Function& overridden_function = Function::Handle();
1195 const intptr_t num_functions = array.Length(); 1200 const intptr_t num_functions = array.Length();
1196 Error& error = Error::Handle(); 1201 Error& error = Error::Handle();
1197 for (intptr_t i = 0; i < num_functions; i++) { 1202 for (intptr_t i = 0; i < num_functions; i++) {
1198 function ^= array.At(i); 1203 function ^= array.At(i);
1199 ResolveAndFinalizeSignature(cls, function); 1204 ResolveAndFinalizeSignature(cls, function);
1200 name = function.name(); 1205 name = function.name();
1201 if (FLAG_error_on_bad_override && // Report signature conflicts only. 1206 if (FLAG_error_on_bad_override && // Report signature conflicts only.
1202 !function.is_static() && !function.IsConstructor()) { 1207 !function.is_static() && !function.IsConstructor()) {
1203 // A constructor cannot override anything. 1208 // A constructor cannot override anything.
1204 for (int i = 0; i < interfaces.Length(); i++) { 1209 for (intptr_t i = 0; i < interfaces.Length(); i++) {
1205 super_class ^= interfaces.At(i); 1210 super_class ^= interfaces.At(i);
1206 overridden_function = super_class.LookupDynamicFunction(name); 1211 overridden_function = super_class.LookupDynamicFunction(name);
1207 if (!overridden_function.IsNull() && 1212 if (!overridden_function.IsNull() &&
1208 !function.HasCompatibleParametersWith(overridden_function, 1213 !function.HasCompatibleParametersWith(overridden_function,
1209 &error)) { 1214 &error)) {
1210 const String& class_name = String::Handle(cls.Name()); 1215 const String& class_name = String::Handle(cls.Name());
1211 const String& super_class_name = String::Handle(super_class.Name()); 1216 const String& super_class_name = String::Handle(super_class.Name());
1212 const Script& script = Script::Handle(cls.script()); 1217 const Script& script = Script::Handle(cls.script());
1213 ReportError(error, script, function.token_pos(), 1218 ReportError(error, script, function.token_pos(),
1214 "class '%s' overrides method '%s' of super class '%s' " 1219 "class '%s' overrides method '%s' of super class '%s' "
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 } 1304 }
1300 } 1305 }
1301 } 1306 }
1302 } 1307 }
1303 1308
1304 1309
1305 // Copy the type parameters of the super and mixin classes to the 1310 // Copy the type parameters of the super and mixin classes to the
1306 // mixin application class. Change type arguments of super type and of 1311 // mixin application class. Change type arguments of super type and of
1307 // interfaces to refer to the respective type parameters of the mixin 1312 // interfaces to refer to the respective type parameters of the mixin
1308 // application class. 1313 // application class.
1309 void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) { 1314 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
1310 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); 1315 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
1311 1316 const AbstractType& super_type = AbstractType::Handle(
1312 const AbstractType& super_type = 1317 mixin_app_class.super_type());
1313 AbstractType::Handle(mixin_app_class.super_type());
1314 ASSERT(super_type.IsResolved()); 1318 ASSERT(super_type.IsResolved());
1315 const Class& super_class = Class::Handle(super_type.type_class()); 1319 const Class& super_class = Class::Handle(super_type.type_class());
1320 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1316 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 1321 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1317 const Class& mixin_class = Class::Handle(mixin_type.type_class()); 1322 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1318 const int num_super_parameters = super_class.NumTypeParameters(); 1323 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1319 const int num_mixin_parameters = mixin_class.NumTypeParameters(); 1324 // The mixin class cannot be Object and this was checked earlier.
1320 if ((num_super_parameters + num_mixin_parameters) == 0) { 1325 ASSERT(!mixin_class.IsObjectClass());
1321 return; 1326
1322 } 1327 // Add the mixin type to the interfaces that the mixin application
1323 1328 // class implements. This is necessary so that type tests work.
1324 // First, clone the super class type parameters. Rename them so that 1329 const Array& interfaces = Array::Handle(Array::New(1));
1325 // there can be no name conflict between the parameters of the super 1330 const Type& interface = Type::Handle(Type::New(
1326 // class and the mixin class. 1331 mixin_class,
1327 const TypeArguments& cloned_type_params = TypeArguments::Handle( 1332 Object::null_abstract_type_arguments(), // Set again below if generic.
1328 TypeArguments::New(num_super_parameters + num_mixin_parameters)); 1333 mixin_app_class.token_pos()));
1329 TypeParameter& param = TypeParameter::Handle(); 1334 ASSERT(!interface.IsFinalized());
1330 TypeParameter& cloned_param = TypeParameter::Handle(); 1335 interfaces.SetAt(0, interface);
1331 String& param_name = String::Handle(); 1336 mixin_app_class.set_interfaces(interfaces);
1332 AbstractType& param_bound = AbstractType::Handle(); 1337
1333 int cloned_index = 0; 1338 // If both the super type and the mixin type are non generic, the mixin
1334 if (num_super_parameters > 0) { 1339 // application class is non generic as well and we can skip type parameter
1335 const TypeArguments& super_params = 1340 // cloning.
1336 TypeArguments::Handle(super_class.type_parameters()); 1341 if ((num_super_type_params + num_mixin_type_params) > 0) {
1337 const TypeArguments& super_type_args = 1342 // First, clone the super class type parameters. Rename them so that
1338 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); 1343 // there can be no name conflict between the parameters of the super
1339 for (int i = 0; i < num_super_parameters; i++) { 1344 // class and the mixin class.
1340 param ^= super_params.TypeAt(i); 1345 const TypeArguments& cloned_type_params = TypeArguments::Handle(
1341 param_name = param.name(); 1346 TypeArguments::New(num_super_type_params + num_mixin_type_params));
1342 param_bound = param.bound(); 1347 TypeParameter& param = TypeParameter::Handle();
1343 // TODO(hausner): handle type bounds. 1348 TypeParameter& cloned_param = TypeParameter::Handle();
1344 if (!param_bound.IsObjectType()) { 1349 String& param_name = String::Handle();
1345 const Script& script = Script::Handle(mixin_app_class.script()); 1350 AbstractType& param_bound = AbstractType::Handle();
1346 ReportError(Error::Handle(), // No previous error. 1351 intptr_t cloned_index = 0;
1347 script, param.token_pos(), 1352 if (num_super_type_params > 0) {
1348 "type parameter '%s': type bounds not yet" 1353 const TypeArguments& super_type_params =
1349 " implemented for mixins\n", 1354 TypeArguments::Handle(super_class.type_parameters());
1350 param_name.ToCString()); 1355 const TypeArguments& super_type_args =
1356 TypeArguments::Handle(TypeArguments::New(num_super_type_params));
1357 for (intptr_t i = 0; i < num_super_type_params; i++) {
1358 param ^= super_type_params.TypeAt(i);
1359 param_name = param.name();
1360 param_bound = param.bound();
1361 // TODO(hausner): handle type bounds.
1362 if (!param_bound.IsObjectType()) {
1363 const Script& script = Script::Handle(mixin_app_class.script());
1364 ReportError(Error::Handle(), // No previous error.
1365 script, param.token_pos(),
1366 "type parameter '%s': type bounds not yet"
1367 " implemented for mixins\n",
1368 param_name.ToCString());
1369 }
1370 param_name = String::Concat(param_name, Symbols::Backtick());
1371 param_name = Symbols::New(param_name);
1372 cloned_param = TypeParameter::New(mixin_app_class,
1373 cloned_index,
1374 param_name,
1375 param_bound,
1376 param.token_pos());
1377 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1378 // Change the type arguments of the super type to refer to the
1379 // cloned type parameters of the mixin application class.
1380 super_type_args.SetTypeAt(cloned_index, cloned_param);
1381 cloned_index++;
1351 } 1382 }
1352 param_name = String::Concat(param_name, Symbols::Backtick()); 1383 // TODO(hausner): May need to handle BoundedType here.
1353 param_name = Symbols::New(param_name); 1384 ASSERT(super_type.IsType());
1354 cloned_param = TypeParameter::New(mixin_app_class, 1385 Type::Cast(super_type).set_arguments(super_type_args);
1355 cloned_index, 1386 ASSERT(!super_type.IsFinalized());
1356 param_name, 1387 }
1357 param_bound, 1388
1358 param.token_pos()); 1389 // Second, clone the type parameters of the mixin class.
1359 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1390 // We need to retain the parameter names of the mixin class
1360 // Change the type arguments of the super type to refer to the 1391 // since the code that will be compiled in the context of the
1361 // cloned type parameters of the mixin application class. 1392 // mixin application class may refer to the type parameters
1362 super_type_args.SetTypeAt(cloned_index, cloned_param); 1393 // with that name.
1363 cloned_index++; 1394 if (num_mixin_type_params > 0) {
1364 } 1395 const TypeArguments& mixin_params =
1365 // TODO(hausner): May need to handle BoundedType here. 1396 TypeArguments::Handle(mixin_class.type_parameters());
1366 ASSERT(super_type.IsType()); 1397 const TypeArguments& interface_type_args = TypeArguments::Handle(
1367 Type::Cast(super_type).set_arguments(super_type_args); 1398 TypeArguments::New(num_mixin_type_params));
1368 ASSERT(!super_type.IsFinalized()); 1399 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1369 } 1400 param ^= mixin_params.TypeAt(i);
1370 1401 param_name = param.name();
1371 // Second, clone the type parameters of the mixin class. 1402 param_bound = param.bound();
1372 // We need to retain the parameter names of the mixin class 1403
1373 // since the code that will be compiled in the context of the 1404 // TODO(hausner): handle type bounds.
1374 // mixin application class may refer to the type parameters 1405 if (!param_bound.IsObjectType()) {
1375 // with that name. 1406 const Script& script = Script::Handle(mixin_app_class.script());
1376 if (num_mixin_parameters > 0) { 1407 ReportError(Error::Handle(), // No previous error.
1377 const TypeArguments& mixin_params = 1408 script, param.token_pos(),
1378 TypeArguments::Handle(mixin_class.type_parameters()); 1409 "type parameter '%s': type bounds not yet"
1379 const TypeArguments& interface_type_args = TypeArguments::Handle( 1410 " implemented for mixins\n",
1380 TypeArguments::New(num_mixin_parameters)); 1411 param_name.ToCString());
1381 for (int i = 0; i < num_mixin_parameters; i++) { 1412 }
1382 param ^= mixin_params.TypeAt(i); 1413 cloned_param = TypeParameter::New(mixin_app_class,
1383 param_name = param.name(); 1414 cloned_index,
1384 param_bound = param.bound(); 1415 param_name,
1385 1416 param_bound,
1386 // TODO(hausner): handle type bounds. 1417 param.token_pos());
1387 if (!param_bound.IsObjectType()) { 1418 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1388 const Script& script = Script::Handle(mixin_app_class.script()); 1419 interface_type_args.SetTypeAt(i, cloned_param);
1389 ReportError(Error::Handle(), // No previous error. 1420 cloned_index++;
1390 script, param.token_pos(),
1391 "type parameter '%s': type bounds not yet"
1392 " implemented for mixins\n",
1393 param_name.ToCString());
1394 } 1421 }
1395 cloned_param = TypeParameter::New(mixin_app_class, 1422
1396 cloned_index, 1423 // Lastly, set the type arguments of the single interface type.
1397 param_name, 1424 ASSERT(!interface.IsFinalized());
1398 param_bound, 1425 interface.set_arguments(interface_type_args);
1399 param.token_pos()); 1426 }
1400 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1427 mixin_app_class.set_type_parameters(cloned_type_params);
1401 interface_type_args.SetTypeAt(i, cloned_param); 1428 }
1402 cloned_index++; 1429 // If the mixin class is a mixin application typedef class, we insert a new
1403 } 1430 // synthesized mixin application class in the super chain of this mixin
1404 1431 // application class. The new class will have the aliased mixin as actual
1405 // Lastly, change the type arguments of the single interface type to 1432 // mixin.
1406 // refer to the cloned type parameters of the mixin application class. 1433 if (mixin_class.is_mixin_typedef()) {
1407 Array& interface_types = Array::Handle(mixin_app_class.interfaces()); 1434 ApplyMixinTypedef(mixin_app_class);
1408 ASSERT(interface_types.Length() == 1); 1435 }
1409 AbstractType& interface_type = AbstractType::Handle();
1410 interface_type ^= interface_types.At(0);
1411 ASSERT(interface_type.IsResolved());
1412 // TODO(hausner): May need to handle BoundedType here.
1413 ASSERT(interface_type.IsType());
1414 Type::Cast(interface_type).set_arguments(interface_type_args);
1415 ASSERT(!interface_type.IsFinalized());
1416 }
1417 mixin_app_class.set_type_parameters(cloned_type_params);
1418 } 1436 }
1419 1437
1420 1438
1439 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) {
1440 // If this mixin typedef is aliasing another mixin typedef, another class
1441 // will be inserted via recursion. No need to check here.
1442 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1443 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1444 ASSERT(mixin_class.is_mixin_typedef());
1445 const Class& aliased_mixin_app_class = Class::Handle(
1446 mixin_class.SuperClass());
1447 const Type& aliased_mixin_type = Type::Handle(
1448 aliased_mixin_app_class.mixin());
1449 // The name of the inserted mixin application class is the name of mixin
1450 // class name with a backtick added.
1451 String& inserted_class_name = String::Handle(mixin_app_class.Name());
1452 inserted_class_name = String::Concat(inserted_class_name,
1453 Symbols::Backtick());
1454 inserted_class_name = Symbols::New(inserted_class_name);
1455 const Script& script = Script::Handle(mixin_app_class.script());
1456 const Library& library = Library::Handle(mixin_app_class.library());
1457 const Class& inserted_class = Class::Handle(Class::New(
1458 inserted_class_name, script, mixin_app_class.token_pos()));
1459 inserted_class.set_library(library);
1460 inserted_class.set_is_synthesized_class();
1461
1462 // The super type of the inserted class is identical to the super type of
1463 // this mixin application class, except that it must refer to the type
1464 // parameters of the inserted class rather than to those of the mixin
1465 // application class.
1466 // The type arguments of the super type will be set properly when calling
1467 // CloneMixinAppTypeParameters on the inserted class, as long as the super
1468 // type class is set properly.
1469 AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type());
1470 inserted_class.set_super_type(super_type); // Super class only is used.
1471
1472 // The mixin type must also be set before calling CloneMixinAppTypeParameters.
1473 // It refers to the type parameters of the mixin class typedef.
1474 inserted_class.set_mixin(aliased_mixin_type); // Mixin class only is used.
1475
1476 // Finalize the types and call CloneMixinAppTypeParameters.
1477 FinalizeTypesInClass(inserted_class);
1478
1479 // The super type of this mixin application class must point to the
1480 // inserted class. The super type arguments are the concatenation of the
1481 // old super type arguments (propagating type arguments to the super class)
1482 // with new type arguments providing type arguments to the mixin.
1483 // The appended type arguments are those of the aliased mixin type, except
1484 // that they must refer to the type parameters of the mixin application
1485 // class rather than to those of the aliased mixin class.
1486 // This type parameter substitution is performed by an instantiation step.
1487 // It is important that the type parameters of the mixin application class
1488 // are not finalized yet, because new type parameters may have been added
1489 // to the super class.
1490 Class& super_class = Class::Handle(super_type.type_class());
1491 ASSERT(mixin_app_class.SuperClass() == super_class.raw());
1492 while (super_class.IsMixinApplication()) {
1493 super_class = super_class.SuperClass();
1494 }
1495 const intptr_t num_super_type_params = super_class.NumTypeParameters();
1496 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
1497 intptr_t offset = aliased_mixin_app_class.NumTypeArguments();
1498 const TypeArguments& type_params =
1499 TypeArguments::Handle(mixin_app_class.type_parameters());
1500 TypeArguments& instantiator = TypeArguments::Handle(
1501 TypeArguments::New(offset + num_mixin_type_params));
1502 AbstractType& type = AbstractType::Handle();
1503 for (intptr_t i = 0; i < num_mixin_type_params; i++) {
1504 type = type_params.TypeAt(num_super_type_params + i);
1505 instantiator.SetTypeAt(offset + i, type);
1506 }
1507 ASSERT(aliased_mixin_type.IsFinalized());
1508 const Class& aliased_mixin_type_class = Class::Handle(
1509 aliased_mixin_type.type_class());
1510 const intptr_t num_aliased_mixin_type_params =
1511 aliased_mixin_type_class.NumTypeParameters();
1512 const intptr_t num_aliased_mixin_type_args =
1513 aliased_mixin_type_class.NumTypeArguments();
1514 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params;
1515 ASSERT(inserted_class.NumTypeParameters() ==
1516 (num_super_type_params + num_aliased_mixin_type_params));
1517 // The aliased_mixin_type may be raw.
1518 const AbstractTypeArguments& aliased_mixin_type_args =
1519 AbstractTypeArguments::Handle(aliased_mixin_type.arguments());
1520 TypeArguments& new_mixin_type_args = TypeArguments::Handle();
1521 if ((num_aliased_mixin_type_params > 0) &&
1522 !aliased_mixin_type_args.IsNull()) {
1523 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
1524 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1525 type = aliased_mixin_type_args.TypeAt(offset + i);
1526 new_mixin_type_args.SetTypeAt(i, type);
1527 }
1528 }
1529 if (!new_mixin_type_args.IsNull() &&
1530 !new_mixin_type_args.IsInstantiated()) {
1531 Error& bound_error = Error::Handle();
1532 new_mixin_type_args ^=
1533 new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
1534 // TODO(regis): Handle bound error.
1535 ASSERT(bound_error.IsNull());
1536 }
1537 TypeArguments& new_super_type_args = TypeArguments::Handle();
1538 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) {
1539 new_super_type_args = TypeArguments::New(num_super_type_params +
1540 num_aliased_mixin_type_params);
1541 for (intptr_t i = 0; i < num_super_type_params; i++) {
1542 type = type_params.TypeAt(i);
1543 new_super_type_args.SetTypeAt(i, type);
1544 }
1545 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
1546 if (new_mixin_type_args.IsNull()) {
1547 type = Type::DynamicType();
1548 } else {
1549 type = new_mixin_type_args.TypeAt(i);
1550 }
1551 new_super_type_args.SetTypeAt(num_super_type_params + i, type);
1552 }
1553 }
1554 super_type = Type::New(inserted_class,
1555 new_super_type_args,
1556 mixin_app_class.token_pos());
1557 mixin_app_class.set_super_type(super_type);
1558 // Mark this mixin application class as being a typedef.
1559 mixin_app_class.set_is_mixin_typedef();
1560 ASSERT(!mixin_app_class.is_type_finalized());
1561 if (FLAG_trace_class_finalization) {
1562 OS::Print("Inserting class %s to mixin typedef application %s "
1563 "with super type '%s'\n",
1564 inserted_class.ToCString(),
1565 mixin_app_class.ToCString(),
1566 String::Handle(super_type.Name()).ToCString());
1567 }
1568 }
1569
1570
1421 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) { 1571 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) {
1422 if (mixin_app_class.is_mixin_type_applied()) { 1572 if (mixin_app_class.is_mixin_type_applied()) {
1423 return; 1573 return;
1424 } 1574 }
1425 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 1575 Type& mixin_type = Type::Handle(mixin_app_class.mixin());
1426 ASSERT(!mixin_type.IsNull()); 1576 ASSERT(!mixin_type.IsNull());
1427 ASSERT(mixin_type.HasResolvedTypeClass()); 1577 ASSERT(mixin_type.HasResolvedTypeClass());
1428 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 1578 const Class& mixin_class = Class::Handle(mixin_type.type_class());
1579 if (mixin_class.IsNullClass()) {
1580 const Script& script = Script::Handle(mixin_app_class.script());
1581 ReportError(Error::Handle(), // No previous error.
1582 script, mixin_app_class.token_pos(),
1583 "illegal mixin of 'Null'");
1584 }
1585 // Check for illegal self references.
1586 GrowableArray<intptr_t> visited_mixins;
1587 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) {
1588 const Script& script = Script::Handle(mixin_class.script());
1589 const String& class_name = String::Handle(mixin_class.Name());
1590 ReportError(Error::Handle(), // No previous error.
1591 script, mixin_class.token_pos(),
1592 "mixin class '%s' illegally refers to itself",
1593 class_name.ToCString());
1594 }
1429 1595
1430 if (FLAG_trace_class_finalization) { 1596 if (FLAG_trace_class_finalization) {
1431 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", 1597 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
1432 String::Handle(mixin_type.Name()).ToCString(), 1598 String::Handle(mixin_type.Name()).ToCString(),
1433 mixin_app_class.ToCString(), 1599 mixin_app_class.ToCString(),
1434 mixin_app_class.token_pos()); 1600 mixin_app_class.token_pos());
1435 } 1601 }
1436 1602
1437 // Check that the super class of the mixin class is extending 1603 // Check that the super class of the mixin class is class Object.
1438 // class Object. 1604 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass());
1439 const AbstractType& mixin_super_type = 1605 // Skip over mixin application typedef classes, which are aliases (but are
1440 AbstractType::Handle(mixin_cls.super_type()); 1606 // implemented as subclasses) of the mixin application classes they name.
1441 if (!mixin_super_type.IsObjectType()) { 1607 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_typedef()) {
1608 while (mixin_super_class.is_mixin_typedef()) {
1609 mixin_super_class = mixin_super_class.SuperClass();
1610 }
1611 mixin_super_class = mixin_super_class.SuperClass();
1612 }
1613 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) {
1442 const Script& script = Script::Handle(mixin_app_class.script()); 1614 const Script& script = Script::Handle(mixin_app_class.script());
1443 const String& class_name = String::Handle(mixin_cls.Name()); 1615 const String& class_name = String::Handle(mixin_class.Name());
1444 ReportError(Error::Handle(), // No previous error. 1616 ReportError(Error::Handle(), // No previous error.
1445 script, mixin_app_class.token_pos(), 1617 script, mixin_app_class.token_pos(),
1446 "mixin class '%s' must extend class Object", 1618 "mixin class '%s' must extend class 'Object'",
1447 class_name.ToCString()); 1619 class_name.ToCString());
1448 } 1620 }
1449 1621
1450 // Copy type parameters to mixin application class. 1622 // Copy type parameters to mixin application class.
1451 CloneTypeParameters(mixin_app_class); 1623 CloneMixinAppTypeParameters(mixin_app_class);
1452 1624
1453 if (FLAG_trace_class_finalization) { 1625 if (FLAG_trace_class_finalization) {
1454 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", 1626 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n",
1455 String::Handle(mixin_type.Name()).ToCString(), 1627 String::Handle(mixin_type.Name()).ToCString(),
1456 String::Handle(mixin_app_class.Name()).ToCString(), 1628 String::Handle(mixin_app_class.Name()).ToCString(),
1457 TypeArguments::Handle( 1629 TypeArguments::Handle(
1458 mixin_app_class.type_parameters()).ToCString(), 1630 mixin_app_class.type_parameters()).ToCString(),
1459 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); 1631 AbstractType::Handle(mixin_app_class.super_type()).ToCString());
1460 } 1632 }
1461 mixin_app_class.set_is_mixin_type_applied(); 1633 mixin_app_class.set_is_mixin_type_applied();
(...skipping 29 matching lines...) Expand all
1491 false, // Not abstract. 1663 false, // Not abstract.
1492 false, // Not external. 1664 false, // Not external.
1493 mixin_app, 1665 mixin_app,
1494 mixin_app.token_pos())); 1666 mixin_app.token_pos()));
1495 1667
1496 clone.set_num_fixed_parameters(func.num_fixed_parameters()); 1668 clone.set_num_fixed_parameters(func.num_fixed_parameters());
1497 clone.SetNumOptionalParameters(func.NumOptionalParameters(), 1669 clone.SetNumOptionalParameters(func.NumOptionalParameters(),
1498 func.HasOptionalPositionalParameters()); 1670 func.HasOptionalPositionalParameters());
1499 clone.set_result_type(dynamic_type); 1671 clone.set_result_type(dynamic_type);
1500 1672
1501 const int num_parameters = func.NumParameters(); 1673 const intptr_t num_parameters = func.NumParameters();
1502 // The cloned ctor shares the parameter names array with the 1674 // The cloned ctor shares the parameter names array with the
1503 // original. 1675 // original.
1504 const Array& parameter_names = Array::Handle(func.parameter_names()); 1676 const Array& parameter_names = Array::Handle(func.parameter_names());
1505 ASSERT(parameter_names.Length() == num_parameters); 1677 ASSERT(parameter_names.Length() == num_parameters);
1506 clone.set_parameter_names(parameter_names); 1678 clone.set_parameter_names(parameter_names);
1507 // The parameter types of the cloned constructor are 'dynamic'. 1679 // The parameter types of the cloned constructor are 'dynamic'.
1508 clone.set_parameter_types(Array::Handle(Array::New(num_parameters))); 1680 clone.set_parameter_types(Array::Handle(Array::New(num_parameters)));
1509 for (intptr_t n = 0; n < num_parameters; n++) { 1681 for (intptr_t n = 0; n < num_parameters; n++) {
1510 clone.SetParameterTypeAt(n, dynamic_type); 1682 clone.SetParameterTypeAt(n, dynamic_type);
1511 } 1683 }
1512 cloned_funcs.Add(clone); 1684 cloned_funcs.Add(clone);
1513 } 1685 }
1514 } 1686 }
1515 } 1687 }
1516 1688
1517 1689
1518 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { 1690 void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
1519 Isolate* isolate = Isolate::Current(); 1691 Isolate* isolate = Isolate::Current();
1520 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); 1692 const Type& mixin_type = Type::Handle(isolate, cls.mixin());
1521 ASSERT(!mixin_type.IsNull()); 1693 ASSERT(!mixin_type.IsNull());
1522 ASSERT(mixin_type.HasResolvedTypeClass()); 1694 ASSERT(mixin_type.HasResolvedTypeClass());
1523 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); 1695 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
1524 mixin_cls.EnsureIsFinalized(isolate); 1696 mixin_cls.EnsureIsFinalized(isolate);
1697 // If the mixin is a mixin application typedef class, there are no members to
1698 // apply here. A new synthesized class representing the aliased mixin
1699 // application class was inserted in the super chain of this mixin application
1700 // class. Members of the actual mixin class will be applied when visiting
1701 // the mixin application class referring to the actual mixin.
1702 ASSERT(!mixin_cls.is_mixin_typedef() ||
1703 Class::Handle(isolate, cls.SuperClass()).IsMixinApplication());
1704 // A default constructor will be created for the typedef class.
1525 1705
1526 if (FLAG_trace_class_finalization) { 1706 if (FLAG_trace_class_finalization) {
1527 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n", 1707 OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n",
1528 mixin_cls.ToCString(), 1708 mixin_cls.ToCString(),
1529 cls.ToCString(), 1709 cls.ToCString(),
1530 cls.token_pos()); 1710 cls.token_pos());
1531 } 1711 }
1532 1712
1533 const GrowableObjectArray& cloned_funcs = 1713 const GrowableObjectArray& cloned_funcs =
1534 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 1714 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1535 1715
1536 CreateForwardingConstructors(cls, cloned_funcs); 1716 CreateForwardingConstructors(cls, cloned_funcs);
1537 1717
1538 Array& functions = Array::Handle(isolate); 1718 Array& functions = Array::Handle(isolate);
1539 Function& func = Function::Handle(isolate); 1719 Function& func = Function::Handle(isolate);
1540 // The parser creates the mixin application class with no functions. 1720 // The parser creates the mixin application class with no functions.
1541 ASSERT((functions = cls.functions(), functions.Length() == 0)); 1721 ASSERT((functions = cls.functions(), functions.Length() == 0));
1542 // Now clone the functions from the mixin class. 1722 // Now clone the functions from the mixin class.
1543 functions = mixin_cls.functions(); 1723 functions = mixin_cls.functions();
1544 const intptr_t num_functions = functions.Length(); 1724 const intptr_t num_functions = functions.Length();
1545 for (int i = 0; i < num_functions; i++) { 1725 for (intptr_t i = 0; i < num_functions; i++) {
1546 func ^= functions.At(i); 1726 func ^= functions.At(i);
1547 if (func.IsConstructor()) { 1727 if (func.IsConstructor()) {
1548 // A mixin class must not have explicit constructors. 1728 // A mixin class must not have explicit constructors.
1549 if (!func.IsImplicitConstructor()) { 1729 if (!func.IsImplicitConstructor()) {
1550 const Script& script = Script::Handle(isolate, cls.script()); 1730 const Script& script = Script::Handle(isolate, cls.script());
1551 ReportError(Error::Handle(), // No previous error. 1731 ReportError(Error::Handle(), // No previous error.
1552 script, cls.token_pos(), 1732 script, cls.token_pos(),
1553 "mixin class '%s' must not have constructors\n", 1733 "mixin class '%s' must not have constructors\n",
1554 String::Handle(isolate, mixin_cls.Name()).ToCString()); 1734 String::Handle(isolate, mixin_cls.Name()).ToCString());
1555 } 1735 }
1556 continue; // Skip the implicit constructor. 1736 continue; // Skip the implicit constructor.
1557 } 1737 }
1558 if (!func.is_static()) { 1738 if (!func.is_static()) {
1559 func = func.Clone(cls); 1739 func = func.Clone(cls);
1560 cloned_funcs.Add(func); 1740 cloned_funcs.Add(func);
1561 } 1741 }
1562 } 1742 }
1563 functions = Array::MakeArray(cloned_funcs); 1743 functions = Array::MakeArray(cloned_funcs);
1564 cls.SetFunctions(functions); 1744 cls.SetFunctions(functions);
1565 1745
1566 // Now clone the fields from the mixin class. There should be no 1746 // Now clone the fields from the mixin class. There should be no
1567 // existing fields in the mixin application class. 1747 // existing fields in the mixin application class.
1568 ASSERT(Array::Handle(cls.fields()).Length() == 0); 1748 ASSERT(Array::Handle(cls.fields()).Length() == 0);
1569 Array& fields = Array::Handle(isolate, mixin_cls.fields()); 1749 Array& fields = Array::Handle(isolate, mixin_cls.fields());
1570 Field& field = Field::Handle(isolate); 1750 Field& field = Field::Handle(isolate);
1571 const GrowableObjectArray& cloned_fields = 1751 const GrowableObjectArray& cloned_fields =
1572 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 1752 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1573 const intptr_t num_fields = fields.Length(); 1753 const intptr_t num_fields = fields.Length();
1574 for (int i = 0; i < num_fields; i++) { 1754 for (intptr_t i = 0; i < num_fields; i++) {
1575 field ^= fields.At(i); 1755 field ^= fields.At(i);
1576 if (!field.is_static()) { 1756 if (!field.is_static()) {
1577 field = field.Clone(cls); 1757 field = field.Clone(cls);
1578 cloned_fields.Add(field); 1758 cloned_fields.Add(field);
1579 } 1759 }
1580 } 1760 }
1581 fields = Array::MakeArray(cloned_fields); 1761 fields = Array::MakeArray(cloned_fields);
1582 cls.SetFields(fields); 1762 cls.SetFields(fields);
1583 1763
1584 if (FLAG_trace_class_finalization) { 1764 if (FLAG_trace_class_finalization) {
1585 OS::Print("done applying mixin members of %s to %s\n", 1765 OS::Print("Done applying mixin members of %s to %s\n",
1586 mixin_cls.ToCString(), 1766 mixin_cls.ToCString(),
1587 cls.ToCString()); 1767 cls.ToCString());
1588 } 1768 }
1589 } 1769 }
1590 1770
1591 1771
1592 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { 1772 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
1593 HANDLESCOPE(Isolate::Current()); 1773 HANDLESCOPE(Isolate::Current());
1594 if (cls.is_type_finalized()) { 1774 if (cls.is_type_finalized()) {
1595 return; 1775 return;
1596 } 1776 }
1597 if (FLAG_trace_class_finalization) { 1777 if (FLAG_trace_class_finalization) {
1598 OS::Print("Finalize types in %s\n", cls.ToCString()); 1778 OS::Print("Finalize types in %s\n", cls.ToCString());
1599 } 1779 }
1600 if (!IsSuperCycleFree(cls)) { 1780 if (!IsSuperCycleFree(cls)) {
1601 const String& name = String::Handle(cls.Name()); 1781 const String& name = String::Handle(cls.Name());
1602 const Script& script = Script::Handle(cls.script()); 1782 const Script& script = Script::Handle(cls.script());
1603 ReportError(Error::Handle(), // No previous error. 1783 ReportError(Error::Handle(), // No previous error.
1604 script, cls.token_pos(), 1784 script, cls.token_pos(),
1605 "class '%s' has a cycle in its superclass relationship", 1785 "class '%s' has a cycle in its superclass relationship",
1606 name.ToCString()); 1786 name.ToCString());
1607 } 1787 }
1608 // Finalize super class. 1788 // Finalize super class.
1609 const Class& super_class = Class::Handle(cls.SuperClass()); 1789 Class& super_class = Class::Handle(cls.SuperClass());
1610 if (!super_class.IsNull()) { 1790 if (!super_class.IsNull()) {
1611 FinalizeTypesInClass(super_class); 1791 FinalizeTypesInClass(super_class);
1612 } 1792 }
1613 // Finalize type parameters before finalizing the super type. 1793 // Finalize type parameters before finalizing the super type.
1614 FinalizeTypeParameters(cls); 1794 FinalizeTypeParameters(cls); // May change super type.
1795 super_class = cls.SuperClass();
1796 ASSERT(super_class.IsNull() || super_class.is_type_finalized());
1615 ResolveUpperBounds(cls); 1797 ResolveUpperBounds(cls);
1616 // Finalize super type. 1798 // Finalize super type.
1617 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 1799 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1618 if (!super_type.IsNull()) { 1800 if (!super_type.IsNull()) {
1619 // In case of a bound error in the super type in production mode, the 1801 // In case of a bound error in the super type in production mode, the
1620 // finalized super type will be a BoundedType with a malformed bound. 1802 // finalized super type will be a BoundedType with a malformed bound.
1621 // It should not be a problem if the class is written to a snapshot and 1803 // It should not be a problem if the class is written to a snapshot and
1622 // later executed in checked mode. Note that the finalized type argument 1804 // later executed in checked mode. Note that the finalized type argument
1623 // vector of any type of the base class will contain a BoundedType for the 1805 // vector of any type of the base class will contain a BoundedType for the
1624 // out of bound type argument. 1806 // out of bound type argument.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 ApplyMixinMembers(cls); 1909 ApplyMixinMembers(cls);
1728 } 1910 }
1729 // Ensure super class is finalized. 1911 // Ensure super class is finalized.
1730 const Class& super = Class::Handle(cls.SuperClass()); 1912 const Class& super = Class::Handle(cls.SuperClass());
1731 if (!super.IsNull()) { 1913 if (!super.IsNull()) {
1732 FinalizeClass(super); 1914 FinalizeClass(super);
1733 } 1915 }
1734 // Mark as parsed and finalized. 1916 // Mark as parsed and finalized.
1735 cls.Finalize(); 1917 cls.Finalize();
1736 // Mixin typedef classes may still lack their implicit constructor. 1918 // Mixin typedef classes may still lack their implicit constructor.
1737 // TODO(regis): Implement mixin typedefs with an alias class.
1738 if (cls.is_mixin_typedef() && 1919 if (cls.is_mixin_typedef() &&
1739 (cls.functions() == Object::empty_array().raw())) { 1920 (cls.functions() == Object::empty_array().raw())) {
1740 Parser::AddImplicitConstructor(cls); 1921 Parser::AddImplicitConstructor(cls);
1741 } 1922 }
1742 // Every class should have at least a constructor, unless it is a top level 1923 // Every class should have at least a constructor, unless it is a top level
1743 // class or a signature class. 1924 // class or a signature class.
1744 ASSERT(cls.IsTopLevel() || 1925 ASSERT(cls.IsTopLevel() ||
1745 cls.IsSignatureClass() || 1926 cls.IsSignatureClass() ||
1746 (Array::Handle(cls.functions()).Length() > 0)); 1927 (Array::Handle(cls.functions()).Length() > 0));
1747 // Resolve and finalize all member types. 1928 // Resolve and finalize all member types.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 } 1986 }
1806 1987
1807 1988
1808 // Returns false if the function type alias illegally refers to itself. 1989 // Returns false if the function type alias illegally refers to itself.
1809 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, 1990 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
1810 GrowableArray<intptr_t>* visited) { 1991 GrowableArray<intptr_t>* visited) {
1811 ASSERT(cls.IsSignatureClass()); 1992 ASSERT(cls.IsSignatureClass());
1812 ASSERT(!cls.is_type_finalized()); 1993 ASSERT(!cls.is_type_finalized());
1813 ASSERT(visited != NULL); 1994 ASSERT(visited != NULL);
1814 const intptr_t cls_index = cls.id(); 1995 const intptr_t cls_index = cls.id();
1815 for (int i = 0; i < visited->length(); i++) { 1996 for (intptr_t i = 0; i < visited->length(); i++) {
1816 if ((*visited)[i] == cls_index) { 1997 if ((*visited)[i] == cls_index) {
1817 // We have already visited alias 'cls'. We found a cycle. 1998 // We have already visited alias 'cls'. We found a cycle.
1818 return false; 1999 return false;
1819 } 2000 }
1820 } 2001 }
1821 2002
1822 // Visit the result type and parameter types of this signature type. 2003 // Visit the result type and parameter types of this signature type.
1823 visited->Add(cls.id()); 2004 visited->Add(cls.id());
1824 const Function& function = Function::Handle(cls.signature_function()); 2005 const Function& function = Function::Handle(cls.signature_function());
1825 // Check class of result type. 2006 // Check class of result type.
1826 AbstractType& type = AbstractType::Handle(function.result_type()); 2007 AbstractType& type = AbstractType::Handle(function.result_type());
1827 if (!IsParameterTypeCycleFree(cls, type, visited)) { 2008 if (!IsParameterTypeCycleFree(cls, type, visited)) {
1828 return false; 2009 return false;
1829 } 2010 }
1830 // Check classes of formal parameter types. 2011 // Check classes of formal parameter types.
1831 const intptr_t num_parameters = function.NumParameters(); 2012 const intptr_t num_parameters = function.NumParameters();
1832 for (intptr_t i = 0; i < num_parameters; i++) { 2013 for (intptr_t i = 0; i < num_parameters; i++) {
1833 type = function.ParameterTypeAt(i); 2014 type = function.ParameterTypeAt(i);
1834 if (!IsParameterTypeCycleFree(cls, type, visited)) { 2015 if (!IsParameterTypeCycleFree(cls, type, visited)) {
1835 return false; 2016 return false;
1836 } 2017 }
1837 } 2018 }
1838 visited->RemoveLast(); 2019 visited->RemoveLast();
1839 return true; 2020 return true;
1840 } 2021 }
1841 2022
1842 2023
2024 // Returns false if the mixin illegally refers to itself.
2025 bool ClassFinalizer::IsMixinCycleFree(const Class& cls,
2026 GrowableArray<intptr_t>* visited) {
2027 ASSERT(visited != NULL);
2028 const intptr_t cls_index = cls.id();
2029 for (intptr_t i = 0; i < visited->length(); i++) {
2030 if ((*visited)[i] == cls_index) {
2031 // We have already visited mixin 'cls'. We found a cycle.
2032 return false;
2033 }
2034 }
2035
2036 // Visit the super chain of cls.
2037 visited->Add(cls.id());
2038 Class& super_class = Class::Handle(cls.raw());
2039 do {
2040 if (super_class.IsMixinApplication()) {
2041 const Type& mixin_type = Type::Handle(super_class.mixin());
2042 ASSERT(!mixin_type.IsNull());
2043 ASSERT(mixin_type.HasResolvedTypeClass());
2044 const Class& mixin_class = Class::Handle(mixin_type.type_class());
2045 if (!IsMixinCycleFree(mixin_class, visited)) {
2046 return false;
2047 }
2048 }
2049 super_class = super_class.SuperClass();
2050 } while (!super_class.IsNull());
2051 visited->RemoveLast();
2052 return true;
2053 }
2054
2055
1843 void ClassFinalizer::CollectTypeArguments( 2056 void ClassFinalizer::CollectTypeArguments(
1844 const Class& cls, 2057 const Class& cls,
1845 const Type& type, 2058 const Type& type,
1846 const GrowableObjectArray& collected_args) { 2059 const GrowableObjectArray& collected_args) {
1847 ASSERT(type.HasResolvedTypeClass()); 2060 ASSERT(type.HasResolvedTypeClass());
1848 Class& type_class = Class::Handle(type.type_class()); 2061 Class& type_class = Class::Handle(type.type_class());
1849 AbstractTypeArguments& type_args = 2062 AbstractTypeArguments& type_args =
1850 AbstractTypeArguments::Handle(type.arguments()); 2063 AbstractTypeArguments::Handle(type.arguments());
1851 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 2064 const intptr_t num_type_parameters = type_class.NumTypeParameters();
1852 const intptr_t num_type_arguments = 2065 const intptr_t num_type_arguments =
1853 type_args.IsNull() ? 0 : type_args.Length(); 2066 type_args.IsNull() ? 0 : type_args.Length();
1854 AbstractType& arg = AbstractType::Handle(); 2067 AbstractType& arg = AbstractType::Handle();
1855 if (num_type_arguments > 0) { 2068 if (num_type_arguments > 0) {
1856 if (num_type_arguments == num_type_parameters) { 2069 if (num_type_arguments == num_type_parameters) {
1857 for (int i = 0; i < num_type_arguments; i++) { 2070 for (intptr_t i = 0; i < num_type_arguments; i++) {
1858 arg = type_args.TypeAt(i); 2071 arg = type_args.TypeAt(i);
1859 collected_args.Add(arg); 2072 collected_args.Add(arg);
1860 } 2073 }
1861 return; 2074 return;
1862 } 2075 }
1863 if (FLAG_error_on_bad_type) { 2076 if (FLAG_error_on_bad_type) {
1864 const Script& script = Script::Handle(cls.script()); 2077 const Script& script = Script::Handle(cls.script());
1865 const String& type_class_name = String::Handle(type_class.Name()); 2078 const String& type_class_name = String::Handle(type_class.Name());
1866 ReportError(Error::Handle(), // No previous error. 2079 ReportError(Error::Handle(), // No previous error.
1867 script, type.token_pos(), 2080 script, type.token_pos(),
1868 "wrong number of type arguments for class '%s'", 2081 "wrong number of type arguments for class '%s'",
1869 type_class_name.ToCString()); 2082 type_class_name.ToCString());
1870 } 2083 }
1871 // Discard provided type arguments and treat type as raw. 2084 // Discard provided type arguments and treat type as raw.
1872 } 2085 }
1873 // Fill arguments with type dynamic. 2086 // Fill arguments with type dynamic.
1874 for (int i = 0; i < num_type_parameters; i++) { 2087 for (intptr_t i = 0; i < num_type_parameters; i++) {
1875 arg = Type::DynamicType(); 2088 arg = Type::DynamicType();
1876 collected_args.Add(arg); 2089 collected_args.Add(arg);
1877 } 2090 }
1878 } 2091 }
1879 2092
1880 2093
1881 RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls, 2094 RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls,
1882 const MixinAppType& mixin_app) { 2095 const MixinAppType& mixin_app) {
1883 // Resolve super type and all mixin types. 2096 // Resolve super type and all mixin types.
1884 const GrowableObjectArray& type_args = 2097 const GrowableObjectArray& type_args =
1885 GrowableObjectArray::Handle(GrowableObjectArray::New()); 2098 GrowableObjectArray::Handle(GrowableObjectArray::New());
1886 AbstractType& type = AbstractType::Handle(mixin_app.SuperType()); 2099 AbstractType& type = AbstractType::Handle(mixin_app.SuperType());
1887 ResolveType(cls, type, kCanonicalizeWellFormed); 2100 ResolveType(cls, type, kCanonicalizeWellFormed);
1888 ASSERT(type.HasResolvedTypeClass()); 2101 ASSERT(type.HasResolvedTypeClass());
1889 // TODO(hausner): May need to handle BoundedType here. 2102 // TODO(hausner): May need to handle BoundedType here.
1890 ASSERT(type.IsType()); 2103 ASSERT(type.IsType());
1891 CollectTypeArguments(cls, Type::Cast(type), type_args); 2104 CollectTypeArguments(cls, Type::Cast(type), type_args);
1892 Class& mixin_app_class = Class::Handle(); 2105 Class& mixin_app_class = Class::Handle();
1893 const intptr_t depth = mixin_app.Depth(); 2106 const intptr_t depth = mixin_app.Depth();
1894 for (int i = 0; i < depth; i++) { 2107 for (intptr_t i = 0; i < depth; i++) {
1895 mixin_app_class = mixin_app.MixinAppAt(i); 2108 mixin_app_class = mixin_app.MixinAppAt(i);
1896 type = mixin_app_class.mixin(); 2109 type = mixin_app_class.mixin();
1897 ASSERT(!type.IsNull()); 2110 ASSERT(!type.IsNull());
1898 ResolveType(cls, type, kCanonicalizeWellFormed); 2111 ResolveType(cls, type, kCanonicalizeWellFormed);
1899 ASSERT(type.HasResolvedTypeClass()); 2112 ASSERT(type.HasResolvedTypeClass());
1900 ASSERT(type.IsType()); 2113 ASSERT(type.IsType());
1901 CollectTypeArguments(cls, Type::Cast(type), type_args); 2114 CollectTypeArguments(cls, Type::Cast(type), type_args);
1902 } 2115 }
1903 const TypeArguments& mixin_app_args = 2116 const TypeArguments& mixin_app_args =
1904 TypeArguments::Handle(TypeArguments::New(type_args.Length())); 2117 TypeArguments::Handle(TypeArguments::New(type_args.Length()));
1905 for (int i = 0; i < type_args.Length(); i++) { 2118 for (intptr_t i = 0; i < type_args.Length(); i++) {
1906 type ^= type_args.At(i); 2119 type ^= type_args.At(i);
1907 mixin_app_args.SetTypeAt(i, type); 2120 mixin_app_args.SetTypeAt(i, type);
1908 } 2121 }
1909 if (FLAG_trace_class_finalization) { 2122 if (FLAG_trace_class_finalization) {
1910 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", 2123 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n",
1911 mixin_app_args.ToCString()); 2124 mixin_app_args.ToCString());
1912 } 2125 }
1913 // The mixin application class at depth k is a subclass of mixin application 2126 // The mixin application class at depth k is a subclass of mixin application
1914 // class at depth k - 1. Build a new super type with the class at the highest 2127 // class at depth k - 1. Build a new super type with the class at the highest
1915 // depth (the last one processed by the loop above) as the type class and the 2128 // depth (the last one processed by the loop above) as the type class and the
(...skipping 11 matching lines...) Expand all
1927 // remembering interfaces we've visited in each path through the 2140 // remembering interfaces we've visited in each path through the
1928 // graph. If we visit an interface a second time on a given path, 2141 // graph. If we visit an interface a second time on a given path,
1929 // we found a loop. 2142 // we found a loop.
1930 void ClassFinalizer::ResolveSuperTypeAndInterfaces( 2143 void ClassFinalizer::ResolveSuperTypeAndInterfaces(
1931 const Class& cls, GrowableArray<intptr_t>* visited) { 2144 const Class& cls, GrowableArray<intptr_t>* visited) {
1932 ASSERT(visited != NULL); 2145 ASSERT(visited != NULL);
1933 if (FLAG_trace_class_finalization) { 2146 if (FLAG_trace_class_finalization) {
1934 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); 2147 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
1935 } 2148 }
1936 const intptr_t cls_index = cls.id(); 2149 const intptr_t cls_index = cls.id();
1937 for (int i = 0; i < visited->length(); i++) { 2150 for (intptr_t i = 0; i < visited->length(); i++) {
1938 if ((*visited)[i] == cls_index) { 2151 if ((*visited)[i] == cls_index) {
1939 // We have already visited class 'cls'. We found a cycle. 2152 // We have already visited class 'cls'. We found a cycle.
1940 const String& class_name = String::Handle(cls.Name()); 2153 const String& class_name = String::Handle(cls.Name());
1941 const Script& script = Script::Handle(cls.script()); 2154 const Script& script = Script::Handle(cls.script());
1942 ReportError(Error::Handle(), // No previous error. 2155 ReportError(Error::Handle(), // No previous error.
1943 script, cls.token_pos(), 2156 script, cls.token_pos(),
1944 "cyclic reference found for class '%s'", 2157 "cyclic reference found for class '%s'",
1945 class_name.ToCString()); 2158 class_name.ToCString());
1946 } 2159 }
1947 } 2160 }
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2316 expected_name ^= String::New("_offset"); 2529 expected_name ^= String::New("_offset");
2317 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2530 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2318 field ^= fields_array.At(2); 2531 field ^= fields_array.At(2);
2319 ASSERT(field.Offset() == TypedDataView::length_offset()); 2532 ASSERT(field.Offset() == TypedDataView::length_offset());
2320 name ^= field.name(); 2533 name ^= field.name();
2321 ASSERT(name.Equals("length")); 2534 ASSERT(name.Equals("length"));
2322 #endif 2535 #endif
2323 } 2536 }
2324 2537
2325 } // namespace dart 2538 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698