| 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" |
| (...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1491 /* is_native = */ false, cls, field.token_pos())); | 1491 /* is_native = */ false, cls, field.token_pos())); |
| 1492 getter.set_result_type(type); | 1492 getter.set_result_type(type); |
| 1493 getter.set_is_debuggable(false); | 1493 getter.set_is_debuggable(false); |
| 1494 getter.set_kernel_function(field.kernel_field()); | 1494 getter.set_kernel_function(field.kernel_field()); |
| 1495 cls.AddFunction(getter); | 1495 cls.AddFunction(getter); |
| 1496 field.SetStaticValue(Object::sentinel(), true); | 1496 field.SetStaticValue(Object::sentinel(), true); |
| 1497 } | 1497 } |
| 1498 } | 1498 } |
| 1499 } | 1499 } |
| 1500 } | 1500 } |
| 1501 // Collect interfaces, super interfaces, and super classes of this class. | 1501 // If we check for bad overrides, collect interfaces, super interfaces, and |
| 1502 // super classes of this class. |
| 1502 GrowableArray<const Class*> interfaces(zone, 4); | 1503 GrowableArray<const Class*> interfaces(zone, 4); |
| 1503 CollectInterfaces(cls, &interfaces); | 1504 if (Isolate::Current()->error_on_bad_override()) { |
| 1504 // Include superclasses in list of interfaces and super interfaces. | 1505 CollectInterfaces(cls, &interfaces); |
| 1505 super_class = cls.SuperClass(); | 1506 // Include superclasses in list of interfaces and super interfaces. |
| 1506 while (!super_class.IsNull()) { | 1507 super_class = cls.SuperClass(); |
| 1507 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw())); | 1508 while (!super_class.IsNull()) { |
| 1508 CollectInterfaces(super_class, &interfaces); | 1509 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw())); |
| 1509 super_class = super_class.SuperClass(); | 1510 CollectInterfaces(super_class, &interfaces); |
| 1511 super_class = super_class.SuperClass(); |
| 1512 } |
| 1510 } | 1513 } |
| 1511 // Resolve function signatures and check for conflicts in super classes and | 1514 // Resolve function signatures and check for conflicts in super classes and |
| 1512 // interfaces. | 1515 // interfaces. |
| 1513 array = cls.functions(); | 1516 array = cls.functions(); |
| 1514 Function& function = Function::Handle(zone); | 1517 Function& function = Function::Handle(zone); |
| 1515 Function& overridden_function = Function::Handle(zone); | 1518 Function& overridden_function = Function::Handle(zone); |
| 1516 const intptr_t num_functions = array.Length(); | 1519 const intptr_t num_functions = array.Length(); |
| 1517 Error& error = Error::Handle(zone); | 1520 Error& error = Error::Handle(zone); |
| 1518 for (intptr_t i = 0; i < num_functions; i++) { | 1521 for (intptr_t i = 0; i < num_functions; i++) { |
| 1519 function ^= array.At(i); | 1522 function ^= array.At(i); |
| 1520 FinalizeSignature(cls, function); | 1523 FinalizeSignature(cls, function); |
| 1521 name = function.name(); | 1524 name = function.name(); |
| 1522 // Report signature conflicts only. | 1525 // Report signature conflicts only. |
| 1523 if (Isolate::Current()->error_on_bad_override() && !function.is_static() && | 1526 if (Isolate::Current()->error_on_bad_override() && !function.is_static() && |
| 1524 !function.IsGenerativeConstructor()) { | 1527 !function.IsGenerativeConstructor()) { |
| 1525 // A constructor cannot override anything. | 1528 // A constructor cannot override anything. |
| 1526 for (intptr_t i = 0; i < interfaces.length(); i++) { | 1529 for (intptr_t i = 0; i < interfaces.length(); i++) { |
| 1527 const Class* super_class = interfaces.At(i); | 1530 const Class* interface = interfaces.At(i); |
| 1528 // Finalize superclass since overrides check relies on all members | 1531 // All interfaces should have been finalized since override checks |
| 1529 // of the superclass to be finalized. | 1532 // rely on all interface members to be finalized. |
| 1530 FinalizeClass(*super_class); | 1533 ASSERT(interface->is_finalized()); |
| 1531 overridden_function = super_class->LookupDynamicFunction(name); | 1534 overridden_function = interface->LookupDynamicFunction(name); |
| 1532 if (!overridden_function.IsNull() && | 1535 if (!overridden_function.IsNull() && |
| 1533 !function.HasCompatibleParametersWith(overridden_function, | 1536 !function.HasCompatibleParametersWith(overridden_function, |
| 1534 &error)) { | 1537 &error)) { |
| 1535 const String& class_name = String::Handle(zone, cls.Name()); | 1538 const String& class_name = String::Handle(zone, cls.Name()); |
| 1536 const String& super_cls_name = | 1539 const String& interface_name = |
| 1537 String::Handle(zone, super_class->Name()); | 1540 String::Handle(zone, interface->Name()); |
| 1538 ReportErrors(error, cls, function.token_pos(), | 1541 ReportErrors(error, cls, function.token_pos(), |
| 1539 "class '%s' overrides method '%s' of super " | 1542 "class '%s' overrides method '%s' of super class or " |
| 1540 "class '%s' with incompatible parameters", | 1543 "interface '%s' with incompatible parameters", |
| 1541 class_name.ToCString(), name.ToCString(), | 1544 class_name.ToCString(), name.ToCString(), |
| 1542 super_cls_name.ToCString()); | 1545 interface_name.ToCString()); |
| 1543 } | 1546 } |
| 1544 } | 1547 } |
| 1545 } | 1548 } |
| 1546 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { | 1549 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { |
| 1547 if (function.is_static()) { | 1550 if (function.is_static()) { |
| 1548 super_class = FindSuperOwnerOfFunction(cls, name); | 1551 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1549 if (!super_class.IsNull()) { | 1552 if (!super_class.IsNull()) { |
| 1550 const String& class_name = String::Handle(zone, cls.Name()); | 1553 const String& class_name = String::Handle(zone, cls.Name()); |
| 1551 const String& super_cls_name = | 1554 const String& super_cls_name = |
| 1552 String::Handle(zone, super_class.Name()); | 1555 String::Handle(zone, super_class.Name()); |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2472 THR_Print("Finalize %s\n", cls.ToCString()); | 2475 THR_Print("Finalize %s\n", cls.ToCString()); |
| 2473 } | 2476 } |
| 2474 if (cls.is_patch()) { | 2477 if (cls.is_patch()) { |
| 2475 // The fields and functions of a patch class are copied to the | 2478 // The fields and functions of a patch class are copied to the |
| 2476 // patched class after parsing. There is nothing to finalize. | 2479 // patched class after parsing. There is nothing to finalize. |
| 2477 ASSERT(Array::Handle(cls.functions()).Length() == 0); | 2480 ASSERT(Array::Handle(cls.functions()).Length() == 0); |
| 2478 ASSERT(Array::Handle(cls.fields()).Length() == 0); | 2481 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
| 2479 cls.set_is_finalized(); | 2482 cls.set_is_finalized(); |
| 2480 return; | 2483 return; |
| 2481 } | 2484 } |
| 2485 // Ensure super class is finalized. |
| 2486 const Class& super = Class::Handle(cls.SuperClass()); |
| 2487 if (!super.IsNull()) { |
| 2488 FinalizeClass(super); |
| 2489 } |
| 2490 // Ensure interfaces are finalized in case we check for bad overrides. |
| 2491 if (Isolate::Current()->error_on_bad_override()) { |
| 2492 GrowableArray<const Class*> interfaces(4); |
| 2493 CollectInterfaces(cls, &interfaces); |
| 2494 for (intptr_t i = 0; i < interfaces.length(); i++) { |
| 2495 FinalizeClass(*interfaces.At(i)); |
| 2496 } |
| 2497 } |
| 2482 if (cls.IsMixinApplication()) { | 2498 if (cls.IsMixinApplication()) { |
| 2483 // Copy instance methods and fields from the mixin class. | 2499 // Copy instance methods and fields from the mixin class. |
| 2484 // This has to happen before the check whether the methods of | 2500 // This has to happen before the check whether the methods of |
| 2485 // the class conflict with inherited methods. | 2501 // the class conflict with inherited methods. |
| 2486 ApplyMixinMembers(cls); | 2502 ApplyMixinMembers(cls); |
| 2487 } | 2503 } |
| 2488 // Ensure super class is finalized. | |
| 2489 const Class& super = Class::Handle(cls.SuperClass()); | |
| 2490 if (!super.IsNull()) { | |
| 2491 FinalizeClass(super); | |
| 2492 } | |
| 2493 // Mark as parsed and finalized. | 2504 // Mark as parsed and finalized. |
| 2494 cls.Finalize(); | 2505 cls.Finalize(); |
| 2495 // Mixin app alias classes may still lack their forwarding constructor. | 2506 // Mixin app alias classes may still lack their forwarding constructor. |
| 2496 if (cls.is_mixin_app_alias() && | 2507 if (cls.is_mixin_app_alias() && |
| 2497 (cls.functions() == Object::empty_array().raw())) { | 2508 (cls.functions() == Object::empty_array().raw())) { |
| 2498 const GrowableObjectArray& cloned_funcs = | 2509 const GrowableObjectArray& cloned_funcs = |
| 2499 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2510 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2500 | 2511 |
| 2501 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); | 2512 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); |
| 2502 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2513 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| (...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3379 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3390 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3380 field ^= fields_array.At(0); | 3391 field ^= fields_array.At(0); |
| 3381 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3392 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3382 name ^= field.name(); | 3393 name ^= field.name(); |
| 3383 expected_name ^= String::New("_data"); | 3394 expected_name ^= String::New("_data"); |
| 3384 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3395 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3385 #endif | 3396 #endif |
| 3386 } | 3397 } |
| 3387 | 3398 |
| 3388 } // namespace dart | 3399 } // namespace dart |
| OLD | NEW |