OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 interface_name.ToCString()); | 870 interface_name.ToCString()); |
871 } | 871 } |
872 } | 872 } |
873 | 873 |
874 // If the class/interface has no explicit interfaces, we are done. | 874 // If the class/interface has no explicit interfaces, we are done. |
875 Array& super_interfaces = Array::Handle(cls.interfaces()); | 875 Array& super_interfaces = Array::Handle(cls.interfaces()); |
876 if (super_interfaces.Length() == 0) { | 876 if (super_interfaces.Length() == 0) { |
877 return; | 877 return; |
878 } | 878 } |
879 | 879 |
| 880 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 881 // about allowed interfaces are lifted. |
| 882 const bool cls_belongs_to_core_lib = |
| 883 (cls.library() == Library::CoreLibrary()) || |
| 884 (cls.library() == Library::CoreImplLibrary()); |
| 885 |
| 886 // Resolve and check the interfaces of cls. |
880 visited->Add(&cls); | 887 visited->Add(&cls); |
881 Type& interface = Type::Handle(); | 888 Type& interface = Type::Handle(); |
882 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 889 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
883 interface ^= super_interfaces.At(i); | 890 interface ^= super_interfaces.At(i); |
884 interface = ResolveType(cls, interface); | 891 interface = ResolveType(cls, interface); |
885 super_interfaces.SetAt(i, interface); | 892 super_interfaces.SetAt(i, interface); |
886 if (interface.IsTypeParameter()) { | 893 if (interface.IsTypeParameter()) { |
887 ReportError("Type parameter '%s' cannot be used as interface\n", | 894 ReportError("Type parameter '%s' cannot be used as interface\n", |
888 String::Handle(interface.Name()).ToCString()); | 895 String::Handle(interface.Name()).ToCString()); |
889 } | 896 } |
890 const Class& interface_class = Class::Handle(interface.type_class()); | 897 const Class& interface_class = Class::Handle(interface.type_class()); |
891 if (!interface_class.is_interface()) { | 898 if (!interface_class.is_interface()) { |
892 ReportError("Class name '%s' used where interface expected\n", | 899 ReportError("Class '%s' is used where an interface is expected\n", |
893 String::Handle(interface_class.Name()).ToCString()); | 900 String::Handle(interface_class.Name()).ToCString()); |
894 } | 901 } |
895 // TODO(regis): Verify that unless cls is in core lib, it cannot implement | 902 // Verify that unless cls belongs to core lib, it cannot extend or implement |
896 // an instance of Number or String. Any other? bool? | 903 // any of bool, num, int, double, String, Function, Dynamic. |
897 | 904 // The exception is signature classes, which are compiler generated and |
| 905 // represent a function type, therefore implementing the Function interface. |
| 906 if (!cls_belongs_to_core_lib) { |
| 907 if (interface.IsBoolInterface() || |
| 908 interface.IsNumberInterface() || |
| 909 interface.IsIntInterface() || |
| 910 interface.IsDoubleInterface() || |
| 911 interface.IsStringInterface() || |
| 912 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || |
| 913 interface.IsDynamicType()) { |
| 914 ReportError("'%s' is not allowed to extend or implement '%s'\n", |
| 915 String::Handle(cls.Name()).ToCString(), |
| 916 String::Handle(interface_class.Name()).ToCString()); |
| 917 } |
| 918 // TODO(regis): We also need to prevent extending classes Smi, Mint, |
| 919 // BigInt, Double, OneByteString, TwoByteString, FourByteString. |
| 920 } |
898 // Now resolve the super interfaces. | 921 // Now resolve the super interfaces. |
899 ResolveInterfaces(interface_class, visited); | 922 ResolveInterfaces(interface_class, visited); |
900 } | 923 } |
901 visited->RemoveLast(); | 924 visited->RemoveLast(); |
902 } | 925 } |
903 | 926 |
904 | 927 |
905 // A class is marked as constant if it has one constant constructor. | 928 // A class is marked as constant if it has one constant constructor. |
906 // A constant class: | 929 // A constant class: |
907 // - may extend only const classes. | 930 // - may extend only const classes. |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 ASSERT(msg_buffer != NULL); | 1035 ASSERT(msg_buffer != NULL); |
1013 va_list args; | 1036 va_list args; |
1014 va_start(args, format); | 1037 va_start(args, format); |
1015 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1038 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
1016 va_end(args); | 1039 va_end(args); |
1017 isolate->long_jump_base()->Jump(1, msg_buffer); | 1040 isolate->long_jump_base()->Jump(1, msg_buffer); |
1018 UNREACHABLE(); | 1041 UNREACHABLE(); |
1019 } | 1042 } |
1020 | 1043 |
1021 } // namespace dart | 1044 } // namespace dart |
OLD | NEW |