| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| 11 #include "vm/longjump.h" | 11 #include "vm/longjump.h" |
| 12 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 13 #include "vm/report.h" |
| 13 #include "vm/symbols.h" | 14 #include "vm/symbols.h" |
| 14 | 15 |
| 15 namespace dart { | 16 namespace dart { |
| 16 | 17 |
| 17 DEFINE_FLAG(bool, error_on_bad_override, false, | 18 DEFINE_FLAG(bool, error_on_bad_override, false, |
| 18 "Report error for bad overrides."); | 19 "Report error for bad overrides."); |
| 19 DEFINE_FLAG(bool, error_on_bad_type, false, | 20 DEFINE_FLAG(bool, error_on_bad_type, false, |
| 20 "Report error for malformed types."); | 21 "Report error for malformed types."); |
| 21 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 22 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 23 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 void ClassFinalizer::ResolveRedirectingFactoryTarget( | 272 void ClassFinalizer::ResolveRedirectingFactoryTarget( |
| 272 const Class& cls, | 273 const Class& cls, |
| 273 const Function& factory, | 274 const Function& factory, |
| 274 const GrowableObjectArray& visited_factories) { | 275 const GrowableObjectArray& visited_factories) { |
| 275 ASSERT(factory.IsRedirectingFactory()); | 276 ASSERT(factory.IsRedirectingFactory()); |
| 276 | 277 |
| 277 // Check for redirection cycle. | 278 // Check for redirection cycle. |
| 278 for (intptr_t i = 0; i < visited_factories.Length(); i++) { | 279 for (intptr_t i = 0; i < visited_factories.Length(); i++) { |
| 279 if (visited_factories.At(i) == factory.raw()) { | 280 if (visited_factories.At(i) == factory.raw()) { |
| 280 // A redirection cycle is reported as a compile-time error. | 281 // A redirection cycle is reported as a compile-time error. |
| 281 const Script& script = Script::Handle(cls.script()); | 282 ReportError(cls, factory.token_pos(), |
| 282 ReportError(Error::Handle(), // No previous error. | |
| 283 script, factory.token_pos(), | |
| 284 "factory '%s' illegally redirects to itself", | 283 "factory '%s' illegally redirects to itself", |
| 285 String::Handle(factory.name()).ToCString()); | 284 String::Handle(factory.name()).ToCString()); |
| 286 } | 285 } |
| 287 } | 286 } |
| 288 visited_factories.Add(factory); | 287 visited_factories.Add(factory); |
| 289 | 288 |
| 290 // Check if target is already resolved. | 289 // Check if target is already resolved. |
| 291 Type& type = Type::Handle(factory.RedirectionType()); | 290 Type& type = Type::Handle(factory.RedirectionType()); |
| 292 Function& target = Function::Handle(factory.RedirectionTarget()); | 291 Function& target = Function::Handle(factory.RedirectionTarget()); |
| 293 if (type.IsMalformedOrMalbounded()) { | 292 if (type.IsMalformedOrMalbounded()) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 String::Handle(target.name()).ToCString(), | 364 String::Handle(target.name()).ToCString(), |
| 366 String::Handle(factory.name()).ToCString()); | 365 String::Handle(factory.name()).ToCString()); |
| 367 factory.SetRedirectionType(type); | 366 factory.SetRedirectionType(type); |
| 368 ASSERT(factory.RedirectionTarget() == Function::null()); | 367 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 369 return; | 368 return; |
| 370 } | 369 } |
| 371 } | 370 } |
| 372 | 371 |
| 373 // Verify that the target is const if the redirecting factory is const. | 372 // Verify that the target is const if the redirecting factory is const. |
| 374 if (factory.is_const() && !target.is_const()) { | 373 if (factory.is_const() && !target.is_const()) { |
| 375 const Script& script = Script::Handle(target_class.script()); | 374 ReportError(target_class, target.token_pos(), |
| 376 ReportError(Error::Handle(), // No previous error. | 375 "constructor '%s' must be const as required by " |
| 377 script, target.token_pos(), | 376 "redirecting const factory '%s'", |
| 378 "constructor '%s' must be const as required by redirecting " | |
| 379 "const factory '%s'", | |
| 380 String::Handle(target.name()).ToCString(), | 377 String::Handle(target.name()).ToCString(), |
| 381 String::Handle(factory.name()).ToCString()); | 378 String::Handle(factory.name()).ToCString()); |
| 382 } | 379 } |
| 383 | 380 |
| 384 // Update redirection data with resolved target. | 381 // Update redirection data with resolved target. |
| 385 factory.SetRedirectionTarget(target); | 382 factory.SetRedirectionTarget(target); |
| 386 // Not needed anymore. | 383 // Not needed anymore. |
| 387 factory.SetRedirectionIdentifier(Object::null_string()); | 384 factory.SetRedirectionIdentifier(Object::null_string()); |
| 388 if (!target.IsRedirectingFactory()) { | 385 if (!target.IsRedirectingFactory()) { |
| 389 return; | 386 return; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 561 } |
| 565 if ((pending_type.raw() != type.raw()) && | 562 if ((pending_type.raw() != type.raw()) && |
| 566 (pending_type.type_class() == type_cls.raw())) { | 563 (pending_type.type_class() == type_cls.raw())) { |
| 567 pending_arguments = pending_type.arguments(); | 564 pending_arguments = pending_type.arguments(); |
| 568 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 565 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
| 569 first_type_param, | 566 first_type_param, |
| 570 num_type_params) && | 567 num_type_params) && |
| 571 !pending_arguments.IsSubvectorInstantiated(first_type_param, | 568 !pending_arguments.IsSubvectorInstantiated(first_type_param, |
| 572 num_type_params)) { | 569 num_type_params)) { |
| 573 // Reject the non-contractive recursive type. | 570 // Reject the non-contractive recursive type. |
| 574 const Script& script = Script::Handle(isolate, cls.script()); | |
| 575 const String& type_name = String::Handle(isolate, type.Name()); | 571 const String& type_name = String::Handle(isolate, type.Name()); |
| 576 ReportError(Error::Handle(isolate), // No previous error. | 572 ReportError(cls, type.token_pos(), |
| 577 script, type.token_pos(), | 573 "illegal recursive type '%s'", type_name.ToCString()); |
| 578 "illegal recursive type '%s'", | |
| 579 type_name.ToCString()); | |
| 580 } | 574 } |
| 581 } | 575 } |
| 582 } | 576 } |
| 583 } | 577 } |
| 584 | 578 |
| 585 | 579 |
| 586 // Finalize the type argument vector 'arguments' of the type defined by the | 580 // Finalize the type argument vector 'arguments' of the type defined by the |
| 587 // class 'cls' parameterized with the type arguments 'cls_args'. | 581 // class 'cls' parameterized with the type arguments 'cls_args'. |
| 588 // The vector 'cls_args' is already initialized as a subvector at the correct | 582 // The vector 'cls_args' is already initialized as a subvector at the correct |
| 589 // position in the passed in 'arguments' vector. | 583 // position in the passed in 'arguments' vector. |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 | 955 |
| 962 // Initialize the type argument vector. | 956 // Initialize the type argument vector. |
| 963 // Check the number of parsed type arguments, if any. | 957 // Check the number of parsed type arguments, if any. |
| 964 // Specifying no type arguments indicates a raw type, which is not an error. | 958 // Specifying no type arguments indicates a raw type, which is not an error. |
| 965 // However, type parameter bounds are checked below, even for a raw type. | 959 // However, type parameter bounds are checked below, even for a raw type. |
| 966 TypeArguments& arguments = | 960 TypeArguments& arguments = |
| 967 TypeArguments::Handle(isolate, parameterized_type.arguments()); | 961 TypeArguments::Handle(isolate, parameterized_type.arguments()); |
| 968 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 962 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 969 // Wrong number of type arguments. The type is mapped to the raw type. | 963 // Wrong number of type arguments. The type is mapped to the raw type. |
| 970 if (FLAG_error_on_bad_type) { | 964 if (FLAG_error_on_bad_type) { |
| 971 const Script& script = Script::Handle(isolate, cls.script()); | |
| 972 const String& type_class_name = | 965 const String& type_class_name = |
| 973 String::Handle(isolate, type_class.Name()); | 966 String::Handle(isolate, type_class.Name()); |
| 974 ReportError(Error::Handle(isolate), // No previous error. | 967 ReportError(cls, parameterized_type.token_pos(), |
| 975 script, parameterized_type.token_pos(), | |
| 976 "wrong number of type arguments for class '%s'", | 968 "wrong number of type arguments for class '%s'", |
| 977 type_class_name.ToCString()); | 969 type_class_name.ToCString()); |
| 978 } | 970 } |
| 979 // Make the type raw and continue without reporting any error. | 971 // Make the type raw and continue without reporting any error. |
| 980 // A static warning should have been reported. | 972 // A static warning should have been reported. |
| 981 arguments = TypeArguments::null(); | 973 arguments = TypeArguments::null(); |
| 982 parameterized_type.set_arguments(arguments); | 974 parameterized_type.set_arguments(arguments); |
| 983 } | 975 } |
| 984 | 976 |
| 985 // Mark the type as being finalized in order to detect self reference and | 977 // Mark the type as being finalized in order to detect self reference and |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 type = field.type(); | 1261 type = field.type(); |
| 1270 type = FinalizeType(cls, type, kCanonicalize); | 1262 type = FinalizeType(cls, type, kCanonicalize); |
| 1271 field.set_type(type); | 1263 field.set_type(type); |
| 1272 name = field.name(); | 1264 name = field.name(); |
| 1273 if (field.is_static()) { | 1265 if (field.is_static()) { |
| 1274 getter_name = Field::GetterSymbol(name); | 1266 getter_name = Field::GetterSymbol(name); |
| 1275 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1267 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
| 1276 if (!super_class.IsNull()) { | 1268 if (!super_class.IsNull()) { |
| 1277 const String& class_name = String::Handle(cls.Name()); | 1269 const String& class_name = String::Handle(cls.Name()); |
| 1278 const String& super_class_name = String::Handle(super_class.Name()); | 1270 const String& super_class_name = String::Handle(super_class.Name()); |
| 1279 const Script& script = Script::Handle(cls.script()); | 1271 ReportError(cls, field.token_pos(), |
| 1280 ReportError(Error::Handle(), // No previous error. | |
| 1281 script, field.token_pos(), | |
| 1282 "static field '%s' of class '%s' conflicts with " | 1272 "static field '%s' of class '%s' conflicts with " |
| 1283 "instance member '%s' of super class '%s'", | 1273 "instance member '%s' of super class '%s'", |
| 1284 name.ToCString(), | 1274 name.ToCString(), |
| 1285 class_name.ToCString(), | 1275 class_name.ToCString(), |
| 1286 name.ToCString(), | 1276 name.ToCString(), |
| 1287 super_class_name.ToCString()); | 1277 super_class_name.ToCString()); |
| 1288 } | 1278 } |
| 1289 // An implicit setter is not generated for a static field, therefore, we | 1279 // An implicit setter is not generated for a static field, therefore, we |
| 1290 // cannot rely on the code below handling the static setter case to report | 1280 // cannot rely on the code below handling the static setter case to report |
| 1291 // a conflict with an instance setter. So we check explicitly here. | 1281 // a conflict with an instance setter. So we check explicitly here. |
| 1292 setter_name = Field::SetterSymbol(name); | 1282 setter_name = Field::SetterSymbol(name); |
| 1293 super_class = FindSuperOwnerOfFunction(cls, setter_name); | 1283 super_class = FindSuperOwnerOfFunction(cls, setter_name); |
| 1294 if (!super_class.IsNull()) { | 1284 if (!super_class.IsNull()) { |
| 1295 const String& class_name = String::Handle(cls.Name()); | 1285 const String& class_name = String::Handle(cls.Name()); |
| 1296 const String& super_class_name = String::Handle(super_class.Name()); | 1286 const String& super_class_name = String::Handle(super_class.Name()); |
| 1297 const Script& script = Script::Handle(cls.script()); | 1287 ReportError(cls, field.token_pos(), |
| 1298 ReportError(Error::Handle(), // No previous error. | |
| 1299 script, field.token_pos(), | |
| 1300 "static field '%s' of class '%s' conflicts with " | 1288 "static field '%s' of class '%s' conflicts with " |
| 1301 "instance setter '%s=' of super class '%s'", | 1289 "instance setter '%s=' of super class '%s'", |
| 1302 name.ToCString(), | 1290 name.ToCString(), |
| 1303 class_name.ToCString(), | 1291 class_name.ToCString(), |
| 1304 name.ToCString(), | 1292 name.ToCString(), |
| 1305 super_class_name.ToCString()); | 1293 super_class_name.ToCString()); |
| 1306 } | 1294 } |
| 1307 | 1295 |
| 1308 } else { | 1296 } else { |
| 1309 // Instance field. Check whether the field overrides a method | 1297 // Instance field. Check whether the field overrides a method |
| 1310 // (but not getter). | 1298 // (but not getter). |
| 1311 super_class = FindSuperOwnerOfFunction(cls, name); | 1299 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1312 if (!super_class.IsNull()) { | 1300 if (!super_class.IsNull()) { |
| 1313 const String& class_name = String::Handle(cls.Name()); | 1301 const String& class_name = String::Handle(cls.Name()); |
| 1314 const String& super_class_name = String::Handle(super_class.Name()); | 1302 const String& super_class_name = String::Handle(super_class.Name()); |
| 1315 const Script& script = Script::Handle(cls.script()); | 1303 ReportError(cls, field.token_pos(), |
| 1316 ReportError(Error::Handle(), // No previous error. | |
| 1317 script, field.token_pos(), | |
| 1318 "field '%s' of class '%s' conflicts with method '%s' " | 1304 "field '%s' of class '%s' conflicts with method '%s' " |
| 1319 "of super class '%s'", | 1305 "of super class '%s'", |
| 1320 name.ToCString(), | 1306 name.ToCString(), |
| 1321 class_name.ToCString(), | 1307 class_name.ToCString(), |
| 1322 name.ToCString(), | 1308 name.ToCString(), |
| 1323 super_class_name.ToCString()); | 1309 super_class_name.ToCString()); |
| 1324 } | 1310 } |
| 1325 } | 1311 } |
| 1326 if (field.is_static() && | 1312 if (field.is_static() && |
| 1327 (field.value() != Object::null()) && | 1313 (field.value() != Object::null()) && |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1339 (!type.IsDynamicType() && | 1325 (!type.IsDynamicType() && |
| 1340 !const_value.IsInstanceOf(type, | 1326 !const_value.IsInstanceOf(type, |
| 1341 Object::null_type_arguments(), | 1327 Object::null_type_arguments(), |
| 1342 &error))) { | 1328 &error))) { |
| 1343 if (FLAG_error_on_bad_type) { | 1329 if (FLAG_error_on_bad_type) { |
| 1344 const AbstractType& const_value_type = AbstractType::Handle( | 1330 const AbstractType& const_value_type = AbstractType::Handle( |
| 1345 const_value.GetType()); | 1331 const_value.GetType()); |
| 1346 const String& const_value_type_name = String::Handle( | 1332 const String& const_value_type_name = String::Handle( |
| 1347 const_value_type.UserVisibleName()); | 1333 const_value_type.UserVisibleName()); |
| 1348 const String& type_name = String::Handle(type.UserVisibleName()); | 1334 const String& type_name = String::Handle(type.UserVisibleName()); |
| 1349 const Script& script = Script::Handle(cls.script()); | 1335 ReportErrors(error, cls, field.token_pos(), |
| 1350 ReportError(error, script, field.token_pos(), | 1336 "error initializing static %s field '%s': " |
| 1351 "error initializing static %s field '%s': " | 1337 "type '%s' is not a subtype of type '%s'", |
| 1352 "type '%s' is not a subtype of type '%s'", | 1338 field.is_const() ? "const" : "final", |
| 1353 field.is_const() ? "const" : "final", | 1339 name.ToCString(), |
| 1354 name.ToCString(), | 1340 const_value_type_name.ToCString(), |
| 1355 const_value_type_name.ToCString(), | 1341 type_name.ToCString()); |
| 1356 type_name.ToCString()); | |
| 1357 } else { | 1342 } else { |
| 1358 // Do not report an error yet, even in checked mode, since the field | 1343 // Do not report an error yet, even in checked mode, since the field |
| 1359 // may not actually be used. | 1344 // may not actually be used. |
| 1360 // Also, we may be generating a snapshot in production mode that will | 1345 // Also, we may be generating a snapshot in production mode that will |
| 1361 // later be executed in checked mode, in which case an error needs to | 1346 // later be executed in checked mode, in which case an error needs to |
| 1362 // be reported, should the field be accessed. | 1347 // be reported, should the field be accessed. |
| 1363 // Therefore, we undo the optimization performed by the parser, i.e. | 1348 // Therefore, we undo the optimization performed by the parser, i.e. |
| 1364 // we create an implicit static final getter and reset the field value | 1349 // we create an implicit static final getter and reset the field value |
| 1365 // to the sentinel value. | 1350 // to the sentinel value. |
| 1366 const Function& getter = Function::Handle( | 1351 const Function& getter = Function::Handle( |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 super_class ^= interfaces.At(i); | 1401 super_class ^= interfaces.At(i); |
| 1417 // Finalize superclass since overrides check relies on all members | 1402 // Finalize superclass since overrides check relies on all members |
| 1418 // of the superclass to be finalized. | 1403 // of the superclass to be finalized. |
| 1419 FinalizeClass(super_class); | 1404 FinalizeClass(super_class); |
| 1420 overridden_function = super_class.LookupDynamicFunction(name); | 1405 overridden_function = super_class.LookupDynamicFunction(name); |
| 1421 if (!overridden_function.IsNull() && | 1406 if (!overridden_function.IsNull() && |
| 1422 !function.HasCompatibleParametersWith(overridden_function, | 1407 !function.HasCompatibleParametersWith(overridden_function, |
| 1423 &error)) { | 1408 &error)) { |
| 1424 const String& class_name = String::Handle(cls.Name()); | 1409 const String& class_name = String::Handle(cls.Name()); |
| 1425 const String& super_class_name = String::Handle(super_class.Name()); | 1410 const String& super_class_name = String::Handle(super_class.Name()); |
| 1426 const Script& script = Script::Handle(cls.script()); | 1411 ReportErrors(error, cls, function.token_pos(), |
| 1427 ReportError(error, script, function.token_pos(), | 1412 "class '%s' overrides method '%s' of super " |
| 1428 "class '%s' overrides method '%s' of super class '%s' " | 1413 "class '%s' with incompatible parameters", |
| 1429 "with incompatible parameters", | 1414 class_name.ToCString(), |
| 1430 class_name.ToCString(), | 1415 name.ToCString(), |
| 1431 name.ToCString(), | 1416 super_class_name.ToCString()); |
| 1432 super_class_name.ToCString()); | |
| 1433 } | 1417 } |
| 1434 } | 1418 } |
| 1435 } | 1419 } |
| 1436 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { | 1420 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { |
| 1437 if (function.is_static()) { | 1421 if (function.is_static()) { |
| 1438 super_class = FindSuperOwnerOfFunction(cls, name); | 1422 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1439 if (!super_class.IsNull()) { | 1423 if (!super_class.IsNull()) { |
| 1440 const String& class_name = String::Handle(cls.Name()); | 1424 const String& class_name = String::Handle(cls.Name()); |
| 1441 const String& super_class_name = String::Handle(super_class.Name()); | 1425 const String& super_class_name = String::Handle(super_class.Name()); |
| 1442 const Script& script = Script::Handle(cls.script()); | 1426 ReportError(cls, function.token_pos(), |
| 1443 ReportError(Error::Handle(), // No previous error. | |
| 1444 script, function.token_pos(), | |
| 1445 "static setter '%s=' of class '%s' conflicts with " | 1427 "static setter '%s=' of class '%s' conflicts with " |
| 1446 "instance setter '%s=' of super class '%s'", | 1428 "instance setter '%s=' of super class '%s'", |
| 1447 name.ToCString(), | 1429 name.ToCString(), |
| 1448 class_name.ToCString(), | 1430 class_name.ToCString(), |
| 1449 name.ToCString(), | 1431 name.ToCString(), |
| 1450 super_class_name.ToCString()); | 1432 super_class_name.ToCString()); |
| 1451 } | 1433 } |
| 1452 } | 1434 } |
| 1453 continue; | 1435 continue; |
| 1454 } | 1436 } |
| 1455 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { | 1437 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { |
| 1456 getter_name = name.raw(); | 1438 getter_name = name.raw(); |
| 1457 name = Field::NameFromGetter(getter_name); | 1439 name = Field::NameFromGetter(getter_name); |
| 1458 } else { | 1440 } else { |
| 1459 getter_name = Field::GetterSymbol(name); | 1441 getter_name = Field::GetterSymbol(name); |
| 1460 } | 1442 } |
| 1461 if (function.is_static()) { | 1443 if (function.is_static()) { |
| 1462 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1444 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
| 1463 if (!super_class.IsNull()) { | 1445 if (!super_class.IsNull()) { |
| 1464 const String& class_name = String::Handle(cls.Name()); | 1446 const String& class_name = String::Handle(cls.Name()); |
| 1465 const String& super_class_name = String::Handle(super_class.Name()); | 1447 const String& super_class_name = String::Handle(super_class.Name()); |
| 1466 const Script& script = Script::Handle(cls.script()); | 1448 ReportError(cls, function.token_pos(), |
| 1467 ReportError(Error::Handle(), // No previous error. | |
| 1468 script, function.token_pos(), | |
| 1469 "static %s '%s' of class '%s' conflicts with " | 1449 "static %s '%s' of class '%s' conflicts with " |
| 1470 "instance member '%s' of super class '%s'", | 1450 "instance member '%s' of super class '%s'", |
| 1471 (function.IsGetterFunction() || | 1451 (function.IsGetterFunction() || |
| 1472 function.IsImplicitGetterFunction()) ? "getter" : "method", | 1452 function.IsImplicitGetterFunction()) ? "getter" : "method", |
| 1473 name.ToCString(), | 1453 name.ToCString(), |
| 1474 class_name.ToCString(), | 1454 class_name.ToCString(), |
| 1475 name.ToCString(), | 1455 name.ToCString(), |
| 1476 super_class_name.ToCString()); | 1456 super_class_name.ToCString()); |
| 1477 } | 1457 } |
| 1478 // The function may be a still unresolved redirecting factory. Do not yet | 1458 // The function may be a still unresolved redirecting factory. Do not yet |
| 1479 // try to resolve it in order to avoid cycles in class finalization. | 1459 // try to resolve it in order to avoid cycles in class finalization. |
| 1480 } else if (function.IsGetterFunction() || | 1460 } else if (function.IsGetterFunction() || |
| 1481 function.IsImplicitGetterFunction()) { | 1461 function.IsImplicitGetterFunction()) { |
| 1482 super_class = FindSuperOwnerOfFunction(cls, name); | 1462 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1483 if (!super_class.IsNull()) { | 1463 if (!super_class.IsNull()) { |
| 1484 const String& class_name = String::Handle(cls.Name()); | 1464 const String& class_name = String::Handle(cls.Name()); |
| 1485 const String& super_class_name = String::Handle(super_class.Name()); | 1465 const String& super_class_name = String::Handle(super_class.Name()); |
| 1486 const Script& script = Script::Handle(cls.script()); | 1466 ReportError(cls, function.token_pos(), |
| 1487 ReportError(Error::Handle(), // No previous error. | |
| 1488 script, function.token_pos(), | |
| 1489 "getter '%s' of class '%s' conflicts with " | 1467 "getter '%s' of class '%s' conflicts with " |
| 1490 "method '%s' of super class '%s'", | 1468 "method '%s' of super class '%s'", |
| 1491 name.ToCString(), | 1469 name.ToCString(), |
| 1492 class_name.ToCString(), | 1470 class_name.ToCString(), |
| 1493 name.ToCString(), | 1471 name.ToCString(), |
| 1494 super_class_name.ToCString()); | 1472 super_class_name.ToCString()); |
| 1495 } | 1473 } |
| 1496 } else if (!function.IsSetterFunction() && | 1474 } else if (!function.IsSetterFunction() && |
| 1497 !function.IsImplicitSetterFunction()) { | 1475 !function.IsImplicitSetterFunction()) { |
| 1498 // A function cannot conflict with a setter, since they cannot | 1476 // A function cannot conflict with a setter, since they cannot |
| 1499 // have the same name. Thus, we do not need to check setters. | 1477 // have the same name. Thus, we do not need to check setters. |
| 1500 super_class = FindSuperOwnerOfFunction(cls, getter_name); | 1478 super_class = FindSuperOwnerOfFunction(cls, getter_name); |
| 1501 if (!super_class.IsNull()) { | 1479 if (!super_class.IsNull()) { |
| 1502 const String& class_name = String::Handle(cls.Name()); | 1480 const String& class_name = String::Handle(cls.Name()); |
| 1503 const String& super_class_name = String::Handle(super_class.Name()); | 1481 const String& super_class_name = String::Handle(super_class.Name()); |
| 1504 const Script& script = Script::Handle(cls.script()); | 1482 ReportError(cls, function.token_pos(), |
| 1505 ReportError(Error::Handle(), // No previous error. | |
| 1506 script, function.token_pos(), | |
| 1507 "method '%s' of class '%s' conflicts with " | 1483 "method '%s' of class '%s' conflicts with " |
| 1508 "getter '%s' of super class '%s'", | 1484 "getter '%s' of super class '%s'", |
| 1509 name.ToCString(), | 1485 name.ToCString(), |
| 1510 class_name.ToCString(), | 1486 class_name.ToCString(), |
| 1511 name.ToCString(), | 1487 name.ToCString(), |
| 1512 super_class_name.ToCString()); | 1488 super_class_name.ToCString()); |
| 1513 } | 1489 } |
| 1514 } | 1490 } |
| 1515 } | 1491 } |
| 1516 } | 1492 } |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", | 1936 OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n", |
| 1961 String::Handle(mixin_type.Name()).ToCString(), | 1937 String::Handle(mixin_type.Name()).ToCString(), |
| 1962 mixin_app_class.ToCString(), | 1938 mixin_app_class.ToCString(), |
| 1963 mixin_app_class.token_pos()); | 1939 mixin_app_class.token_pos()); |
| 1964 } | 1940 } |
| 1965 | 1941 |
| 1966 // Check for illegal self references. This has to be done before checking | 1942 // Check for illegal self references. This has to be done before checking |
| 1967 // that the super class of the mixin class is class Object. | 1943 // that the super class of the mixin class is class Object. |
| 1968 GrowableArray<intptr_t> visited_mixins; | 1944 GrowableArray<intptr_t> visited_mixins; |
| 1969 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) { | 1945 if (!IsMixinCycleFree(mixin_class, &visited_mixins)) { |
| 1970 const Script& script = Script::Handle(mixin_class.script()); | |
| 1971 const String& class_name = String::Handle(mixin_class.Name()); | 1946 const String& class_name = String::Handle(mixin_class.Name()); |
| 1972 ReportError(Error::Handle(), // No previous error. | 1947 ReportError(mixin_class, mixin_class.token_pos(), |
| 1973 script, mixin_class.token_pos(), | |
| 1974 "mixin class '%s' illegally refers to itself", | 1948 "mixin class '%s' illegally refers to itself", |
| 1975 class_name.ToCString()); | 1949 class_name.ToCString()); |
| 1976 } | 1950 } |
| 1977 | 1951 |
| 1978 // Check that the super class of the mixin class is class Object. | 1952 // Check that the super class of the mixin class is class Object. |
| 1979 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass()); | 1953 Class& mixin_super_class = Class::Handle(mixin_class.SuperClass()); |
| 1980 // Skip over mixin application alias classes, which are implemented as | 1954 // Skip over mixin application alias classes, which are implemented as |
| 1981 // subclasses of the mixin application classes they name. | 1955 // subclasses of the mixin application classes they name. |
| 1982 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_app_alias()) { | 1956 if (!mixin_super_class.IsNull() && mixin_class.is_mixin_app_alias()) { |
| 1983 while (mixin_super_class.is_mixin_app_alias()) { | 1957 while (mixin_super_class.is_mixin_app_alias()) { |
| 1984 mixin_super_class = mixin_super_class.SuperClass(); | 1958 mixin_super_class = mixin_super_class.SuperClass(); |
| 1985 } | 1959 } |
| 1986 mixin_super_class = mixin_super_class.SuperClass(); | 1960 mixin_super_class = mixin_super_class.SuperClass(); |
| 1987 } | 1961 } |
| 1988 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) { | 1962 if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) { |
| 1989 const Script& script = Script::Handle(mixin_app_class.script()); | |
| 1990 const String& class_name = String::Handle(mixin_class.Name()); | 1963 const String& class_name = String::Handle(mixin_class.Name()); |
| 1991 ReportError(Error::Handle(), // No previous error. | 1964 ReportError(mixin_app_class, mixin_app_class.token_pos(), |
| 1992 script, mixin_app_class.token_pos(), | |
| 1993 "mixin class '%s' must extend class 'Object'", | 1965 "mixin class '%s' must extend class 'Object'", |
| 1994 class_name.ToCString()); | 1966 class_name.ToCString()); |
| 1995 } | 1967 } |
| 1996 | 1968 |
| 1997 // Copy type parameters to mixin application class. | 1969 // Copy type parameters to mixin application class. |
| 1998 CloneMixinAppTypeParameters(mixin_app_class); | 1970 CloneMixinAppTypeParameters(mixin_app_class); |
| 1999 | 1971 |
| 2000 // Verify that no restricted class is used as a mixin by checking the | 1972 // Verify that no restricted class is used as a mixin by checking the |
| 2001 // interfaces of the mixin application class, which implements its mixin. | 1973 // interfaces of the mixin application class, which implements its mixin. |
| 2002 GrowableArray<intptr_t> visited_interfaces; | 1974 GrowableArray<intptr_t> visited_interfaces; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2120 // The parser creates the mixin application class with no functions. | 2092 // The parser creates the mixin application class with no functions. |
| 2121 ASSERT((functions = cls.functions(), functions.Length() == 0)); | 2093 ASSERT((functions = cls.functions(), functions.Length() == 0)); |
| 2122 // Now clone the functions from the mixin class. | 2094 // Now clone the functions from the mixin class. |
| 2123 functions = mixin_cls.functions(); | 2095 functions = mixin_cls.functions(); |
| 2124 const intptr_t num_functions = functions.Length(); | 2096 const intptr_t num_functions = functions.Length(); |
| 2125 for (intptr_t i = 0; i < num_functions; i++) { | 2097 for (intptr_t i = 0; i < num_functions; i++) { |
| 2126 func ^= functions.At(i); | 2098 func ^= functions.At(i); |
| 2127 if (func.IsConstructor()) { | 2099 if (func.IsConstructor()) { |
| 2128 // A mixin class must not have explicit constructors. | 2100 // A mixin class must not have explicit constructors. |
| 2129 if (!func.IsImplicitConstructor()) { | 2101 if (!func.IsImplicitConstructor()) { |
| 2130 const Script& script = Script::Handle(isolate, cls.script()); | 2102 ReportError(cls, cls.token_pos(), |
| 2131 ReportError(Error::Handle(), // No previous error. | |
| 2132 script, cls.token_pos(), | |
| 2133 "mixin class '%s' must not have constructors\n", | 2103 "mixin class '%s' must not have constructors\n", |
| 2134 String::Handle(isolate, mixin_cls.Name()).ToCString()); | 2104 String::Handle(isolate, mixin_cls.Name()).ToCString()); |
| 2135 } | 2105 } |
| 2136 continue; // Skip the implicit constructor. | 2106 continue; // Skip the implicit constructor. |
| 2137 } | 2107 } |
| 2138 if (!func.is_static()) { | 2108 if (!func.is_static()) { |
| 2139 func = func.Clone(cls); | 2109 func = func.Clone(cls); |
| 2140 cloned_funcs.Add(func); | 2110 cloned_funcs.Add(func); |
| 2141 } | 2111 } |
| 2142 } | 2112 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2171 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { | 2141 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
| 2172 HANDLESCOPE(Isolate::Current()); | 2142 HANDLESCOPE(Isolate::Current()); |
| 2173 if (cls.is_type_finalized()) { | 2143 if (cls.is_type_finalized()) { |
| 2174 return; | 2144 return; |
| 2175 } | 2145 } |
| 2176 if (FLAG_trace_class_finalization) { | 2146 if (FLAG_trace_class_finalization) { |
| 2177 OS::Print("Finalize types in %s\n", cls.ToCString()); | 2147 OS::Print("Finalize types in %s\n", cls.ToCString()); |
| 2178 } | 2148 } |
| 2179 if (!IsSuperCycleFree(cls)) { | 2149 if (!IsSuperCycleFree(cls)) { |
| 2180 const String& name = String::Handle(cls.Name()); | 2150 const String& name = String::Handle(cls.Name()); |
| 2181 const Script& script = Script::Handle(cls.script()); | 2151 ReportError(cls, cls.token_pos(), |
| 2182 ReportError(Error::Handle(), // No previous error. | |
| 2183 script, cls.token_pos(), | |
| 2184 "class '%s' has a cycle in its superclass relationship", | 2152 "class '%s' has a cycle in its superclass relationship", |
| 2185 name.ToCString()); | 2153 name.ToCString()); |
| 2186 } | 2154 } |
| 2187 // Finalize super class. | 2155 // Finalize super class. |
| 2188 Class& super_class = Class::Handle(cls.SuperClass()); | 2156 Class& super_class = Class::Handle(cls.SuperClass()); |
| 2189 if (!super_class.IsNull()) { | 2157 if (!super_class.IsNull()) { |
| 2190 FinalizeTypesInClass(super_class); | 2158 FinalizeTypesInClass(super_class); |
| 2191 } | 2159 } |
| 2192 // Finalize type parameters before finalizing the super type. | 2160 // Finalize type parameters before finalizing the super type. |
| 2193 FinalizeTypeParameters(cls); // May change super type. | 2161 FinalizeTypeParameters(cls); // May change super type. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2205 // vector of any type of the base class will contain a BoundedType for the | 2173 // vector of any type of the base class will contain a BoundedType for the |
| 2206 // out of bound type argument. | 2174 // out of bound type argument. |
| 2207 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); | 2175 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); |
| 2208 cls.set_super_type(super_type); | 2176 cls.set_super_type(super_type); |
| 2209 } | 2177 } |
| 2210 if (cls.IsSignatureClass()) { | 2178 if (cls.IsSignatureClass()) { |
| 2211 // Check for illegal self references. | 2179 // Check for illegal self references. |
| 2212 GrowableArray<intptr_t> visited_aliases; | 2180 GrowableArray<intptr_t> visited_aliases; |
| 2213 if (!IsAliasCycleFree(cls, &visited_aliases)) { | 2181 if (!IsAliasCycleFree(cls, &visited_aliases)) { |
| 2214 const String& name = String::Handle(cls.Name()); | 2182 const String& name = String::Handle(cls.Name()); |
| 2215 const Script& script = Script::Handle(cls.script()); | 2183 ReportError(cls, cls.token_pos(), |
| 2216 ReportError(Error::Handle(), // No previous error. | |
| 2217 script, cls.token_pos(), | |
| 2218 "typedef '%s' illegally refers to itself", | 2184 "typedef '%s' illegally refers to itself", |
| 2219 name.ToCString()); | 2185 name.ToCString()); |
| 2220 } | 2186 } |
| 2221 cls.set_is_type_finalized(); | 2187 cls.set_is_type_finalized(); |
| 2222 | 2188 |
| 2223 // The type parameters of signature classes may have bounds. | 2189 // The type parameters of signature classes may have bounds. |
| 2224 FinalizeUpperBounds(cls); | 2190 FinalizeUpperBounds(cls); |
| 2225 | 2191 |
| 2226 // Resolve and finalize the result and parameter types of the signature | 2192 // Resolve and finalize the result and parameter types of the signature |
| 2227 // function of this signature class. | 2193 // function of this signature class. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2241 interface_type ^= interface_types.At(i); | 2207 interface_type ^= interface_types.At(i); |
| 2242 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); | 2208 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); |
| 2243 interface_types.SetAt(i, interface_type); | 2209 interface_types.SetAt(i, interface_type); |
| 2244 | 2210 |
| 2245 // Check whether the interface is duplicated. We need to wait with | 2211 // Check whether the interface is duplicated. We need to wait with |
| 2246 // this check until the super type and interface types are finalized, | 2212 // this check until the super type and interface types are finalized, |
| 2247 // so that we can use Type::Equals() for the test. | 2213 // so that we can use Type::Equals() for the test. |
| 2248 ASSERT(interface_type.IsFinalized()); | 2214 ASSERT(interface_type.IsFinalized()); |
| 2249 ASSERT(super_type.IsNull() || super_type.IsFinalized()); | 2215 ASSERT(super_type.IsNull() || super_type.IsFinalized()); |
| 2250 if (!super_type.IsNull() && interface_type.Equals(super_type)) { | 2216 if (!super_type.IsNull() && interface_type.Equals(super_type)) { |
| 2251 const Script& script = Script::Handle(cls.script()); | 2217 ReportError(cls, cls.token_pos(), |
| 2252 ReportError(Error::Handle(), // No previous error. | |
| 2253 script, cls.token_pos(), | |
| 2254 "super type '%s' may not be listed in " | 2218 "super type '%s' may not be listed in " |
| 2255 "implements clause of class '%s'", | 2219 "implements clause of class '%s'", |
| 2256 String::Handle(super_type.Name()).ToCString(), | 2220 String::Handle(super_type.Name()).ToCString(), |
| 2257 String::Handle(cls.Name()).ToCString()); | 2221 String::Handle(cls.Name()).ToCString()); |
| 2258 } | 2222 } |
| 2259 for (intptr_t j = 0; j < i; j++) { | 2223 for (intptr_t j = 0; j < i; j++) { |
| 2260 seen_interf ^= interface_types.At(j); | 2224 seen_interf ^= interface_types.At(j); |
| 2261 if (interface_type.Equals(seen_interf)) { | 2225 if (interface_type.Equals(seen_interf)) { |
| 2262 const Script& script = Script::Handle(cls.script()); | 2226 ReportError(cls, cls.token_pos(), |
| 2263 ReportError(Error::Handle(), // No previous error. | |
| 2264 script, cls.token_pos(), | |
| 2265 "interface '%s' appears twice in " | 2227 "interface '%s' appears twice in " |
| 2266 "implements clause of class '%s'", | 2228 "implements clause of class '%s'", |
| 2267 String::Handle(interface_type.Name()).ToCString(), | 2229 String::Handle(interface_type.Name()).ToCString(), |
| 2268 String::Handle(cls.Name()).ToCString()); | 2230 String::Handle(cls.Name()).ToCString()); |
| 2269 } | 2231 } |
| 2270 } | 2232 } |
| 2271 } | 2233 } |
| 2272 // Mark as type finalized before resolving type parameter upper bounds | 2234 // Mark as type finalized before resolving type parameter upper bounds |
| 2273 // in order to break cycles. | 2235 // in order to break cycles. |
| 2274 cls.set_is_type_finalized(); | 2236 cls.set_is_type_finalized(); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 if (num_type_arguments == num_type_parameters) { | 2455 if (num_type_arguments == num_type_parameters) { |
| 2494 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2456 for (intptr_t i = 0; i < num_type_arguments; i++) { |
| 2495 arg = type_args.TypeAt(i); | 2457 arg = type_args.TypeAt(i); |
| 2496 arg = arg.CloneUnfinalized(); | 2458 arg = arg.CloneUnfinalized(); |
| 2497 ASSERT(!arg.IsBeingFinalized()); | 2459 ASSERT(!arg.IsBeingFinalized()); |
| 2498 collected_args.Add(arg); | 2460 collected_args.Add(arg); |
| 2499 } | 2461 } |
| 2500 return; | 2462 return; |
| 2501 } | 2463 } |
| 2502 if (FLAG_error_on_bad_type) { | 2464 if (FLAG_error_on_bad_type) { |
| 2503 const Script& script = Script::Handle(cls.script()); | |
| 2504 const String& type_class_name = String::Handle(type_class.Name()); | 2465 const String& type_class_name = String::Handle(type_class.Name()); |
| 2505 ReportError(Error::Handle(), // No previous error. | 2466 ReportError(cls, type.token_pos(), |
| 2506 script, type.token_pos(), | |
| 2507 "wrong number of type arguments for class '%s'", | 2467 "wrong number of type arguments for class '%s'", |
| 2508 type_class_name.ToCString()); | 2468 type_class_name.ToCString()); |
| 2509 } | 2469 } |
| 2510 // Discard provided type arguments and treat type as raw. | 2470 // Discard provided type arguments and treat type as raw. |
| 2511 } | 2471 } |
| 2512 // Fill arguments with type dynamic. | 2472 // Fill arguments with type dynamic. |
| 2513 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2473 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 2514 arg = Type::DynamicType(); | 2474 arg = Type::DynamicType(); |
| 2515 collected_args.Add(arg); | 2475 collected_args.Add(arg); |
| 2516 } | 2476 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2665 ASSERT(visited != NULL); | 2625 ASSERT(visited != NULL); |
| 2666 if (FLAG_trace_class_finalization) { | 2626 if (FLAG_trace_class_finalization) { |
| 2667 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 2627 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
| 2668 } | 2628 } |
| 2669 Isolate* isolate = Isolate::Current(); | 2629 Isolate* isolate = Isolate::Current(); |
| 2670 const intptr_t cls_index = cls.id(); | 2630 const intptr_t cls_index = cls.id(); |
| 2671 for (intptr_t i = 0; i < visited->length(); i++) { | 2631 for (intptr_t i = 0; i < visited->length(); i++) { |
| 2672 if ((*visited)[i] == cls_index) { | 2632 if ((*visited)[i] == cls_index) { |
| 2673 // We have already visited class 'cls'. We found a cycle. | 2633 // We have already visited class 'cls'. We found a cycle. |
| 2674 const String& class_name = String::Handle(isolate, cls.Name()); | 2634 const String& class_name = String::Handle(isolate, cls.Name()); |
| 2675 const Script& script = Script::Handle(isolate, cls.script()); | 2635 ReportError(cls, cls.token_pos(), |
| 2676 ReportError(Error::Handle(isolate), // No previous error. | |
| 2677 script, cls.token_pos(), | |
| 2678 "cyclic reference found for class '%s'", | 2636 "cyclic reference found for class '%s'", |
| 2679 class_name.ToCString()); | 2637 class_name.ToCString()); |
| 2680 } | 2638 } |
| 2681 } | 2639 } |
| 2682 | 2640 |
| 2683 // If the class/interface has no explicit super class/interfaces | 2641 // If the class/interface has no explicit super class/interfaces |
| 2684 // and is not a mixin application, we are done. | 2642 // and is not a mixin application, we are done. |
| 2685 AbstractType& super_type = AbstractType::Handle(isolate, cls.super_type()); | 2643 AbstractType& super_type = AbstractType::Handle(isolate, cls.super_type()); |
| 2686 Array& super_interfaces = Array::Handle(isolate, cls.interfaces()); | 2644 Array& super_interfaces = Array::Handle(isolate, cls.interfaces()); |
| 2687 if ((super_type.IsNull() || super_type.IsObjectType()) && | 2645 if ((super_type.IsNull() || super_type.IsObjectType()) && |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2708 visited->Add(cls_index); | 2666 visited->Add(cls_index); |
| 2709 AbstractType& interface = AbstractType::Handle(isolate); | 2667 AbstractType& interface = AbstractType::Handle(isolate); |
| 2710 Class& interface_class = Class::Handle(isolate); | 2668 Class& interface_class = Class::Handle(isolate); |
| 2711 | 2669 |
| 2712 // Resolve super type. Failures lead to a longjmp. | 2670 // Resolve super type. Failures lead to a longjmp. |
| 2713 ResolveType(cls, super_type); | 2671 ResolveType(cls, super_type); |
| 2714 if (super_type.IsMalformedOrMalbounded()) { | 2672 if (super_type.IsMalformedOrMalbounded()) { |
| 2715 ReportError(Error::Handle(isolate, super_type.error())); | 2673 ReportError(Error::Handle(isolate, super_type.error())); |
| 2716 } | 2674 } |
| 2717 if (super_type.IsDynamicType()) { | 2675 if (super_type.IsDynamicType()) { |
| 2718 const Script& script = Script::Handle(isolate, cls.script()); | 2676 ReportError(cls, cls.token_pos(), |
| 2719 ReportError(Error::Handle(isolate), // No previous error. | |
| 2720 script, cls.token_pos(), | |
| 2721 "class '%s' may not extend 'dynamic'", | 2677 "class '%s' may not extend 'dynamic'", |
| 2722 String::Handle(isolate, cls.Name()).ToCString()); | 2678 String::Handle(isolate, cls.Name()).ToCString()); |
| 2723 } | 2679 } |
| 2724 interface_class = super_type.type_class(); | 2680 interface_class = super_type.type_class(); |
| 2725 if (interface_class.IsSignatureClass()) { | 2681 if (interface_class.IsSignatureClass()) { |
| 2726 const Script& script = Script::Handle(isolate, cls.script()); | 2682 ReportError(cls, cls.token_pos(), |
| 2727 ReportError(Error::Handle(isolate), // No previous error. | |
| 2728 script, cls.token_pos(), | |
| 2729 "class '%s' may not extend function type alias '%s'", | 2683 "class '%s' may not extend function type alias '%s'", |
| 2730 String::Handle(isolate, cls.Name()).ToCString(), | 2684 String::Handle(isolate, cls.Name()).ToCString(), |
| 2731 String::Handle(isolate, | 2685 String::Handle(isolate, |
| 2732 super_type.UserVisibleName()).ToCString()); | 2686 super_type.UserVisibleName()).ToCString()); |
| 2733 } | 2687 } |
| 2734 | 2688 |
| 2735 // If cls belongs to core lib or to core lib's implementation, restrictions | 2689 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 2736 // about allowed interfaces are lifted. | 2690 // about allowed interfaces are lifted. |
| 2737 if (!cls_belongs_to_core_lib) { | 2691 if (!cls_belongs_to_core_lib) { |
| 2738 // Prevent extending core implementation classes. | 2692 // Prevent extending core implementation classes. |
| 2739 bool is_error = false; | 2693 bool is_error = false; |
| 2740 switch (interface_class.id()) { | 2694 switch (interface_class.id()) { |
| 2741 case kNumberCid: | 2695 case kNumberCid: |
| 2742 case kIntegerCid: // Class Integer, not int. | 2696 case kIntegerCid: // Class Integer, not int. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2767 // Special case: classes for which we don't have a known class id. | 2721 // Special case: classes for which we don't have a known class id. |
| 2768 if (super_type.IsDoubleType() || | 2722 if (super_type.IsDoubleType() || |
| 2769 super_type.IsIntType() || | 2723 super_type.IsIntType() || |
| 2770 super_type.IsStringType()) { | 2724 super_type.IsStringType()) { |
| 2771 is_error = true; | 2725 is_error = true; |
| 2772 } | 2726 } |
| 2773 break; | 2727 break; |
| 2774 } | 2728 } |
| 2775 } | 2729 } |
| 2776 if (is_error) { | 2730 if (is_error) { |
| 2777 const Script& script = Script::Handle(isolate, cls.script()); | 2731 const String& interface_name = String::Handle(isolate, |
| 2778 ReportError(Error::Handle(isolate), // No previous error. | 2732 interface_class.Name()); |
| 2779 script, cls.token_pos(), | 2733 ReportError(cls, cls.token_pos(), |
| 2780 "'%s' is not allowed to extend '%s'", | 2734 "'%s' is not allowed to extend '%s'", |
| 2781 String::Handle(isolate, cls.Name()).ToCString(), | 2735 String::Handle(isolate, cls.Name()).ToCString(), |
| 2782 String::Handle(isolate, interface_class.Name()).ToCString()); | 2736 interface_name.ToCString()); |
| 2783 } | 2737 } |
| 2784 } | 2738 } |
| 2785 // Now resolve the super interfaces of the super type. | 2739 // Now resolve the super interfaces of the super type. |
| 2786 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2740 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 2787 | 2741 |
| 2788 // Resolve interfaces. Failures lead to a longjmp. | 2742 // Resolve interfaces. Failures lead to a longjmp. |
| 2789 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2743 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 2790 interface ^= super_interfaces.At(i); | 2744 interface ^= super_interfaces.At(i); |
| 2791 ResolveType(cls, interface); | 2745 ResolveType(cls, interface); |
| 2792 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2746 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| 2793 // A malbounded interface is only reported when involved in a type test. | 2747 // A malbounded interface is only reported when involved in a type test. |
| 2794 if (interface.IsMalformed()) { | 2748 if (interface.IsMalformed()) { |
| 2795 ReportError(Error::Handle(isolate, interface.error())); | 2749 ReportError(Error::Handle(isolate, interface.error())); |
| 2796 } | 2750 } |
| 2797 if (interface.IsDynamicType()) { | 2751 if (interface.IsDynamicType()) { |
| 2798 const Script& script = Script::Handle(isolate, cls.script()); | 2752 ReportError(cls, cls.token_pos(), |
| 2799 ReportError(Error::Handle(isolate), // No previous error. | |
| 2800 script, cls.token_pos(), | |
| 2801 "'dynamic' may not be used as interface"); | 2753 "'dynamic' may not be used as interface"); |
| 2802 } | 2754 } |
| 2803 interface_class = interface.type_class(); | 2755 interface_class = interface.type_class(); |
| 2804 if (interface_class.IsSignatureClass()) { | 2756 if (interface_class.IsSignatureClass()) { |
| 2805 const Script& script = Script::Handle(isolate, cls.script()); | 2757 const String& interface_name = String::Handle(isolate, |
| 2806 ReportError(Error::Handle(isolate), // No previous error. | 2758 interface_class.Name()); |
| 2807 script, cls.token_pos(), | 2759 ReportError(cls, cls.token_pos(), |
| 2808 "function type alias '%s' may not be used as interface", | 2760 "function type alias '%s' may not be used as interface", |
| 2809 String::Handle(isolate, interface_class.Name()).ToCString()); | 2761 interface_name.ToCString()); |
| 2810 } | 2762 } |
| 2811 // Verify that unless cls belongs to core lib, it cannot extend, implement, | 2763 // Verify that unless cls belongs to core lib, it cannot extend, implement, |
| 2812 // or mixin any of Null, bool, num, int, double, String, dynamic. | 2764 // or mixin any of Null, bool, num, int, double, String, dynamic. |
| 2813 if (!cls_belongs_to_core_lib) { | 2765 if (!cls_belongs_to_core_lib) { |
| 2814 if (interface.IsBoolType() || | 2766 if (interface.IsBoolType() || |
| 2815 interface.IsNullType() || | 2767 interface.IsNullType() || |
| 2816 interface.IsNumberType() || | 2768 interface.IsNumberType() || |
| 2817 interface.IsIntType() || | 2769 interface.IsIntType() || |
| 2818 interface.IsDoubleType() || | 2770 interface.IsDoubleType() || |
| 2819 interface.IsStringType() || | 2771 interface.IsStringType() || |
| 2820 interface.IsDynamicType()) { | 2772 interface.IsDynamicType()) { |
| 2821 const Script& script = Script::Handle(isolate, cls.script()); | |
| 2822 const String& interface_name = String::Handle(isolate, | 2773 const String& interface_name = String::Handle(isolate, |
| 2823 interface_class.Name()); | 2774 interface_class.Name()); |
| 2824 if (cls.IsMixinApplication()) { | 2775 if (cls.IsMixinApplication()) { |
| 2825 ReportError(Error::Handle(isolate), // No previous error. | 2776 ReportError(cls, cls.token_pos(), |
| 2826 script, cls.token_pos(), | |
| 2827 "illegal mixin of '%s'", | 2777 "illegal mixin of '%s'", |
| 2828 interface_name.ToCString()); | 2778 interface_name.ToCString()); |
| 2829 } else { | 2779 } else { |
| 2830 ReportError(Error::Handle(isolate), // No previous error. | 2780 ReportError(cls, cls.token_pos(), |
| 2831 script, cls.token_pos(), | |
| 2832 "'%s' is not allowed to extend or implement '%s'", | 2781 "'%s' is not allowed to extend or implement '%s'", |
| 2833 String::Handle(isolate, cls.Name()).ToCString(), | 2782 String::Handle(isolate, cls.Name()).ToCString(), |
| 2834 interface_name.ToCString()); | 2783 interface_name.ToCString()); |
| 2835 } | 2784 } |
| 2836 } | 2785 } |
| 2837 } | 2786 } |
| 2838 interface_class.set_is_implemented(); | 2787 interface_class.set_is_implemented(); |
| 2839 // Now resolve the super interfaces. | 2788 // Now resolve the super interfaces. |
| 2840 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2789 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 2841 } | 2790 } |
| 2842 visited->RemoveLast(); | 2791 visited->RemoveLast(); |
| 2843 cls.set_is_cycle_free(); | 2792 cls.set_is_cycle_free(); |
| 2844 } | 2793 } |
| 2845 | 2794 |
| 2846 | 2795 |
| 2847 // A class is marked as constant if it has one constant constructor. | 2796 // A class is marked as constant if it has one constant constructor. |
| 2848 // A constant class can only have final instance fields. | 2797 // A constant class can only have final instance fields. |
| 2849 // Note: we must check for cycles before checking for const properties. | 2798 // Note: we must check for cycles before checking for const properties. |
| 2850 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { | 2799 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { |
| 2851 ASSERT(cls.is_const()); | 2800 ASSERT(cls.is_const()); |
| 2852 const Array& fields_array = Array::Handle(cls.fields()); | 2801 const Array& fields_array = Array::Handle(cls.fields()); |
| 2853 intptr_t len = fields_array.Length(); | 2802 intptr_t len = fields_array.Length(); |
| 2854 Field& field = Field::Handle(); | 2803 Field& field = Field::Handle(); |
| 2855 for (intptr_t i = 0; i < len; i++) { | 2804 for (intptr_t i = 0; i < len; i++) { |
| 2856 field ^= fields_array.At(i); | 2805 field ^= fields_array.At(i); |
| 2857 if (!field.is_static() && !field.is_final()) { | 2806 if (!field.is_static() && !field.is_final()) { |
| 2858 const String& class_name = String::Handle(cls.Name()); | 2807 const String& class_name = String::Handle(cls.Name()); |
| 2859 const String& field_name = String::Handle(field.name()); | 2808 const String& field_name = String::Handle(field.name()); |
| 2860 const Script& script = Script::Handle(cls.script()); | 2809 ReportError(cls, field.token_pos(), |
| 2861 ReportError(Error::Handle(), // No previous error. | |
| 2862 script, field.token_pos(), | |
| 2863 "const class '%s' has non-final field '%s'", | 2810 "const class '%s' has non-final field '%s'", |
| 2864 class_name.ToCString(), field_name.ToCString()); | 2811 class_name.ToCString(), field_name.ToCString()); |
| 2865 } | 2812 } |
| 2866 } | 2813 } |
| 2867 } | 2814 } |
| 2868 | 2815 |
| 2869 | 2816 |
| 2870 void ClassFinalizer::PrintClassInformation(const Class& cls) { | 2817 void ClassFinalizer::PrintClassInformation(const Class& cls) { |
| 2871 HANDLESCOPE(Isolate::Current()); | 2818 HANDLESCOPE(Isolate::Current()); |
| 2872 const String& class_name = String::Handle(cls.Name()); | 2819 const String& class_name = String::Handle(cls.Name()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2907 const Array& fields_array = Array::Handle(cls.fields()); | 2854 const Array& fields_array = Array::Handle(cls.fields()); |
| 2908 Field& field = Field::Handle(); | 2855 Field& field = Field::Handle(); |
| 2909 len = fields_array.Length(); | 2856 len = fields_array.Length(); |
| 2910 for (intptr_t i = 0; i < len; i++) { | 2857 for (intptr_t i = 0; i < len; i++) { |
| 2911 field ^= fields_array.At(i); | 2858 field ^= fields_array.At(i); |
| 2912 OS::Print(" %s\n", field.ToCString()); | 2859 OS::Print(" %s\n", field.ToCString()); |
| 2913 } | 2860 } |
| 2914 } | 2861 } |
| 2915 | 2862 |
| 2916 // Either report an error or mark the type as malformed. | 2863 // Either report an error or mark the type as malformed. |
| 2917 void ClassFinalizer::ReportMalformedType(const Error& prev_error, | 2864 void ClassFinalizer::MarkTypeMalformed(const Error& prev_error, |
| 2918 const Script& script, | 2865 const Script& script, |
| 2919 const Type& type, | 2866 const Type& type, |
| 2920 const char* format, | 2867 const char* format, |
| 2921 va_list args) { | 2868 va_list args) { |
| 2922 LanguageError& error = LanguageError::Handle( | 2869 LanguageError& error = LanguageError::Handle( |
| 2923 LanguageError::NewFormattedV( | 2870 LanguageError::NewFormattedV( |
| 2924 prev_error, script, type.token_pos(), | 2871 prev_error, script, type.token_pos(), |
| 2925 LanguageError::kMalformedType, Heap::kOld, | 2872 Report::kMalformedType, Heap::kOld, |
| 2926 format, args)); | 2873 format, args)); |
| 2927 if (FLAG_error_on_bad_type) { | 2874 if (FLAG_error_on_bad_type) { |
| 2928 ReportError(error); | 2875 ReportError(error); |
| 2929 } | 2876 } |
| 2930 type.set_error(error); | 2877 type.set_error(error); |
| 2931 // Make the type raw, since it may not be possible to | 2878 // Make the type raw, since it may not be possible to |
| 2932 // properly finalize its type arguments. | 2879 // properly finalize its type arguments. |
| 2933 type.set_type_class(Class::Handle(Object::dynamic_class())); | 2880 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 2934 type.set_arguments(Object::null_type_arguments()); | 2881 type.set_arguments(Object::null_type_arguments()); |
| 2935 if (!type.IsFinalized()) { | 2882 if (!type.IsFinalized()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2948 intptr_t type_pos, | 2895 intptr_t type_pos, |
| 2949 const char* format, ...) { | 2896 const char* format, ...) { |
| 2950 va_list args; | 2897 va_list args; |
| 2951 va_start(args, format); | 2898 va_start(args, format); |
| 2952 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( | 2899 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( |
| 2953 UnresolvedClass::New(LibraryPrefix::Handle(), | 2900 UnresolvedClass::New(LibraryPrefix::Handle(), |
| 2954 Symbols::Empty(), | 2901 Symbols::Empty(), |
| 2955 type_pos)); | 2902 type_pos)); |
| 2956 const Type& type = Type::Handle( | 2903 const Type& type = Type::Handle( |
| 2957 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); | 2904 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); |
| 2958 ReportMalformedType(prev_error, script, type, format, args); | 2905 MarkTypeMalformed(prev_error, script, type, format, args); |
| 2959 va_end(args); | 2906 va_end(args); |
| 2960 ASSERT(type.IsMalformed()); | 2907 ASSERT(type.IsMalformed()); |
| 2961 ASSERT(type.IsFinalized()); | 2908 ASSERT(type.IsFinalized()); |
| 2962 return type.raw(); | 2909 return type.raw(); |
| 2963 } | 2910 } |
| 2964 | 2911 |
| 2965 | 2912 |
| 2966 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, | 2913 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
| 2967 const Script& script, | 2914 const Script& script, |
| 2968 const Type& type, | 2915 const Type& type, |
| 2969 const char* format, ...) { | 2916 const char* format, ...) { |
| 2970 va_list args; | 2917 va_list args; |
| 2971 va_start(args, format); | 2918 va_start(args, format); |
| 2972 ReportMalformedType(prev_error, script, type, format, args); | 2919 MarkTypeMalformed(prev_error, script, type, format, args); |
| 2973 va_end(args); | 2920 va_end(args); |
| 2974 } | 2921 } |
| 2975 | 2922 |
| 2976 | 2923 |
| 2977 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, | 2924 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, |
| 2978 const Script& script, | 2925 const Script& script, |
| 2979 const Type& type, | 2926 const Type& type, |
| 2980 const char* format, ...) { | 2927 const char* format, ...) { |
| 2981 va_list args; | 2928 va_list args; |
| 2982 va_start(args, format); | 2929 va_start(args, format); |
| 2983 LanguageError& error = LanguageError::Handle( | 2930 LanguageError& error = LanguageError::Handle( |
| 2984 LanguageError::NewFormattedV( | 2931 LanguageError::NewFormattedV( |
| 2985 prev_error, script, type.token_pos(), | 2932 prev_error, script, type.token_pos(), |
| 2986 LanguageError::kMalboundedType, Heap::kOld, | 2933 Report::kMalboundedType, Heap::kOld, |
| 2987 format, args)); | 2934 format, args)); |
| 2988 va_end(args); | 2935 va_end(args); |
| 2989 if (FLAG_error_on_bad_type) { | 2936 if (FLAG_error_on_bad_type) { |
| 2990 ReportError(error); | 2937 ReportError(error); |
| 2991 } | 2938 } |
| 2992 type.set_error(error); | 2939 type.set_error(error); |
| 2993 if (!type.IsFinalized()) { | 2940 if (!type.IsFinalized()) { |
| 2994 type.SetIsFinalized(); | 2941 type.SetIsFinalized(); |
| 2995 // Do not canonicalize malbounded types. | 2942 // Do not canonicalize malbounded types. |
| 2996 } | 2943 } |
| 2997 } | 2944 } |
| 2998 | 2945 |
| 2999 | 2946 |
| 3000 void ClassFinalizer::ReportError(const Error& error) { | 2947 void ClassFinalizer::ReportError(const Error& error) { |
| 3001 Isolate::Current()->long_jump_base()->Jump(1, error); | 2948 Report::LongJump(error); |
| 3002 UNREACHABLE(); | 2949 UNREACHABLE(); |
| 3003 } | 2950 } |
| 3004 | 2951 |
| 3005 | 2952 |
| 3006 void ClassFinalizer::ReportError(const Error& prev_error, | 2953 void ClassFinalizer::ReportErrors(const Error& prev_error, |
| 3007 const Script& script, | 2954 const Class& cls, |
| 2955 intptr_t token_pos, |
| 2956 const char* format, ...) { |
| 2957 va_list args; |
| 2958 va_start(args, format); |
| 2959 const Script& script = Script::Handle(cls.script()); |
| 2960 Report::LongJumpV(prev_error, script, token_pos, format, args); |
| 2961 va_end(args); |
| 2962 UNREACHABLE(); |
| 2963 } |
| 2964 |
| 2965 |
| 2966 void ClassFinalizer::ReportError(const Class& cls, |
| 3008 intptr_t token_pos, | 2967 intptr_t token_pos, |
| 3009 const char* format, ...) { | 2968 const char* format, ...) { |
| 3010 va_list args; | 2969 va_list args; |
| 3011 va_start(args, format); | 2970 va_start(args, format); |
| 3012 Error& error = Error::Handle( | 2971 const Script& script = Script::Handle(cls.script()); |
| 3013 LanguageError::NewFormattedV( | 2972 Report::MessageV(Report::kError, script, token_pos, format, args); |
| 3014 prev_error, script, token_pos, | |
| 3015 LanguageError::kError, Heap::kNew, | |
| 3016 format, args)); | |
| 3017 va_end(args); | 2973 va_end(args); |
| 3018 ReportError(error); | 2974 UNREACHABLE(); |
| 3019 } | 2975 } |
| 3020 | 2976 |
| 3021 | 2977 |
| 3022 void ClassFinalizer::VerifyImplicitFieldOffsets() { | 2978 void ClassFinalizer::VerifyImplicitFieldOffsets() { |
| 3023 #ifdef DEBUG | 2979 #ifdef DEBUG |
| 3024 Isolate* isolate = Isolate::Current(); | 2980 Isolate* isolate = Isolate::Current(); |
| 3025 const ClassTable& class_table = *(isolate->class_table()); | 2981 const ClassTable& class_table = *(isolate->class_table()); |
| 3026 Class& cls = Class::Handle(isolate); | 2982 Class& cls = Class::Handle(isolate); |
| 3027 Array& fields_array = Array::Handle(isolate); | 2983 Array& fields_array = Array::Handle(isolate); |
| 3028 Field& field = Field::Handle(isolate); | 2984 Field& field = Field::Handle(isolate); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3072 expected_name ^= String::New("_offset"); | 3028 expected_name ^= String::New("_offset"); |
| 3073 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3029 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3074 field ^= fields_array.At(2); | 3030 field ^= fields_array.At(2); |
| 3075 ASSERT(field.Offset() == TypedDataView::length_offset()); | 3031 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 3076 name ^= field.name(); | 3032 name ^= field.name(); |
| 3077 ASSERT(name.Equals("length")); | 3033 ASSERT(name.Equals("length")); |
| 3078 #endif | 3034 #endif |
| 3079 } | 3035 } |
| 3080 | 3036 |
| 3081 } // namespace dart | 3037 } // namespace dart |
| OLD | NEW |