OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 // Input: C<String, double> expressed as | 556 // Input: C<String, double> expressed as |
557 // cls = C, arguments = [null, null, String, double], | 557 // cls = C, arguments = [null, null, String, double], |
558 // i.e. cls_args = [String, double], offset = 2, length = 2. | 558 // i.e. cls_args = [String, double], offset = 2, length = 2. |
559 // Output: arguments = [int, double, String, double] | 559 // Output: arguments = [int, double, String, double] |
560 void ClassFinalizer::FinalizeTypeArguments( | 560 void ClassFinalizer::FinalizeTypeArguments( |
561 const Class& cls, | 561 const Class& cls, |
562 const AbstractTypeArguments& arguments, | 562 const AbstractTypeArguments& arguments, |
563 FinalizationKind finalization) { | 563 FinalizationKind finalization) { |
564 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 564 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
565 if (!cls.is_finalized()) { | 565 if (!cls.is_finalized()) { |
566 const GrowableObjectArray& visited = | 566 GrowableArray<intptr_t> visited_interfaces; |
567 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 567 ResolveInterfaces(cls, &visited_interfaces); |
568 ResolveInterfaces(cls, visited); | |
569 FinalizeTypeParameters(cls); | 568 FinalizeTypeParameters(cls); |
570 } | 569 } |
571 Type& super_type = Type::Handle(cls.super_type()); | 570 Type& super_type = Type::Handle(cls.super_type()); |
572 if (!super_type.IsNull()) { | 571 if (!super_type.IsNull()) { |
573 const Class& super_class = Class::Handle(super_type.type_class()); | 572 const Class& super_class = Class::Handle(super_type.type_class()); |
574 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); | 573 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); |
575 if (super_type.IsBeingFinalized()) { | 574 if (super_type.IsBeingFinalized()) { |
576 // This type references itself via its type arguments. This is legal, but | 575 // This type references itself via its type arguments. This is legal, but |
577 // we must avoid endless recursion. We therefore map the innermost | 576 // we must avoid endless recursion. We therefore map the innermost |
578 // super type to Dynamic. | 577 // super type to Dynamic. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 // Mark type as being finalized in order to detect illegal self reference. | 661 // Mark type as being finalized in order to detect illegal self reference. |
663 parameterized_type.set_is_being_finalized(); | 662 parameterized_type.set_is_being_finalized(); |
664 | 663 |
665 // The type class does not need to be finalized in order to finalize the type, | 664 // The type class does not need to be finalized in order to finalize the type, |
666 // however, it must at least be resolved (this was done as part of resolving | 665 // however, it must at least be resolved (this was done as part of resolving |
667 // the type itself, a precondition to calling FinalizeType). | 666 // the type itself, a precondition to calling FinalizeType). |
668 // Also, the interfaces of the type class must be resolved and the type | 667 // Also, the interfaces of the type class must be resolved and the type |
669 // parameters of the type class must be finalized. | 668 // parameters of the type class must be finalized. |
670 Class& type_class = Class::Handle(parameterized_type.type_class()); | 669 Class& type_class = Class::Handle(parameterized_type.type_class()); |
671 if (!type_class.is_finalized()) { | 670 if (!type_class.is_finalized()) { |
672 const GrowableObjectArray& visited = | 671 GrowableArray<intptr_t> visited_interfaces; |
673 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 672 ResolveInterfaces(type_class, &visited_interfaces); |
674 ResolveInterfaces(type_class, visited); | |
675 FinalizeTypeParameters(type_class); | 673 FinalizeTypeParameters(type_class); |
676 } | 674 } |
677 | 675 |
678 // Finalize the current type arguments of the type, which are still the | 676 // Finalize the current type arguments of the type, which are still the |
679 // parsed type arguments. | 677 // parsed type arguments. |
680 AbstractTypeArguments& arguments = | 678 AbstractTypeArguments& arguments = |
681 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 679 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
682 if (!arguments.IsNull()) { | 680 if (!arguments.IsNull()) { |
683 intptr_t num_arguments = arguments.Length(); | 681 intptr_t num_arguments = arguments.Length(); |
684 for (intptr_t i = 0; i < num_arguments; i++) { | 682 for (intptr_t i = 0; i < num_arguments; i++) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 // FinalizeTypeArguments can modify 'full_arguments', | 743 // FinalizeTypeArguments can modify 'full_arguments', |
746 // canonicalize afterwards. | 744 // canonicalize afterwards. |
747 full_arguments ^= full_arguments.Canonicalize(); | 745 full_arguments ^= full_arguments.Canonicalize(); |
748 } | 746 } |
749 parameterized_type.set_arguments(full_arguments); | 747 parameterized_type.set_arguments(full_arguments); |
750 } else { | 748 } else { |
751 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 749 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
752 } | 750 } |
753 } | 751 } |
754 | 752 |
755 // Illegally self referencing types may get finalized indirectly. | 753 // Self referencing types may get finalized indirectly. |
756 if (parameterized_type.IsFinalized()) { | 754 if (!parameterized_type.IsFinalized()) { |
757 ASSERT(parameterized_type.IsMalformed()); | |
758 } else { | |
759 // Mark the type as finalized. | 755 // Mark the type as finalized. |
760 if (parameterized_type.IsInstantiated()) { | 756 if (parameterized_type.IsInstantiated()) { |
761 parameterized_type.set_is_finalized_instantiated(); | 757 parameterized_type.set_is_finalized_instantiated(); |
762 } else { | 758 } else { |
763 parameterized_type.set_is_finalized_uninstantiated(); | 759 parameterized_type.set_is_finalized_uninstantiated(); |
764 } | 760 } |
765 } | 761 } |
766 | 762 |
767 // Upper bounds of the finalized type arguments are only verified in checked | 763 // Upper bounds of the finalized type arguments are only verified in checked |
768 // mode, since bound errors are never reported by the vm in production mode. | 764 // mode, since bound errors are never reported by the vm in production mode. |
(...skipping 15 matching lines...) Expand all Loading... |
784 // when finalizing the malformed type. | 780 // when finalizing the malformed type. |
785 FinalizeMalformedType( | 781 FinalizeMalformedType( |
786 malformed_error, | 782 malformed_error, |
787 cls, parameterized_type, kFinalize, | 783 cls, parameterized_type, kFinalize, |
788 "type arguments of type '%s' are not within bounds", | 784 "type arguments of type '%s' are not within bounds", |
789 String::Handle(parameterized_type.Name()).ToCString()); | 785 String::Handle(parameterized_type.Name()).ToCString()); |
790 return parameterized_type.raw(); | 786 return parameterized_type.raw(); |
791 } | 787 } |
792 } | 788 } |
793 | 789 |
794 // If the type class is a signature class, we also finalize its signature | 790 // If the type class is a signature class, we are currently finalizing a |
795 // type, thereby finalizing the result type and parameter types of its | 791 // signature type, i.e. finalizing the result type and parameter types of the |
796 // signature function. | 792 // signature function of this signature type. |
797 // We do this after marking this type as finalized in order to allow a | 793 // We do this after marking this type as finalized in order to allow a |
798 // function type to refer to itself via its parameter types and result type. | 794 // function type to refer to itself via its parameter types and result type. |
799 if (type_class.IsSignatureClass()) { | 795 if (type_class.IsSignatureClass()) { |
800 // Signature classes are finalized upon creation. | 796 // Signature classes are finalized upon creation, except function type |
801 ASSERT(type_class.is_finalized()); | 797 // aliases. |
802 // Resolve and finalize the result and parameter types of the signature | 798 if (type_class.IsCanonicalSignatureClass()) { |
803 // function of this signature class. | 799 ASSERT(type_class.is_finalized()); |
804 ResolveAndFinalizeSignature( | 800 // Resolve and finalize the result and parameter types of the signature |
805 type_class, Function::Handle(type_class.signature_function())); | 801 // function of this signature class. |
| 802 ASSERT(type_class.SignatureType() == type.raw()); |
| 803 ResolveAndFinalizeSignature( |
| 804 type_class, Function::Handle(type_class.signature_function())); |
| 805 } else { |
| 806 // This type is a function type alias. Its class may need to be finalized |
| 807 // and checked for illegal self reference. |
| 808 FinalizeClass(type_class, false); |
| 809 // Finalizing the signature function here (as in the canonical case above) |
| 810 // would not mark the canonical signature type as finalized. |
| 811 const Type& signature_type = Type::Handle(type_class.SignatureType()); |
| 812 FinalizeType(cls, signature_type, finalization); |
| 813 } |
806 } | 814 } |
807 | 815 |
808 return parameterized_type.Canonicalize(); | 816 return parameterized_type.Canonicalize(); |
809 } | 817 } |
810 | 818 |
811 | 819 |
812 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 820 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
813 const Function& function) { | 821 const Function& function) { |
814 // Resolve result type. | 822 // Resolve result type. |
815 AbstractType& type = AbstractType::Handle(function.result_type()); | 823 AbstractType& type = AbstractType::Handle(function.result_type()); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 } | 1060 } |
1053 | 1061 |
1054 | 1062 |
1055 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { | 1063 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { |
1056 if (cls.is_finalized()) { | 1064 if (cls.is_finalized()) { |
1057 return; | 1065 return; |
1058 } | 1066 } |
1059 if (FLAG_trace_class_finalization) { | 1067 if (FLAG_trace_class_finalization) { |
1060 OS::Print("Finalize %s\n", cls.ToCString()); | 1068 OS::Print("Finalize %s\n", cls.ToCString()); |
1061 } | 1069 } |
1062 // Signature classes are finalized upon creation. | |
1063 ASSERT(!cls.IsSignatureClass()); | |
1064 if (!IsSuperCycleFree(cls)) { | 1070 if (!IsSuperCycleFree(cls)) { |
1065 const String& name = String::Handle(cls.Name()); | 1071 const String& name = String::Handle(cls.Name()); |
1066 const Script& script = Script::Handle(cls.script()); | 1072 const Script& script = Script::Handle(cls.script()); |
1067 ReportError(script, cls.token_index(), | 1073 ReportError(script, cls.token_index(), |
1068 "class '%s' has a cycle in its superclass relationship", | 1074 "class '%s' has a cycle in its superclass relationship", |
1069 name.ToCString()); | 1075 name.ToCString()); |
1070 } | 1076 } |
1071 const GrowableObjectArray& visited = | 1077 GrowableArray<intptr_t> visited_interfaces; |
1072 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1078 ResolveInterfaces(cls, &visited_interfaces); |
1073 ResolveInterfaces(cls, visited); | |
1074 // Finalize super class. | 1079 // Finalize super class. |
1075 const Class& super_class = Class::Handle(cls.SuperClass()); | 1080 const Class& super_class = Class::Handle(cls.SuperClass()); |
1076 if (!super_class.IsNull()) { | 1081 if (!super_class.IsNull()) { |
1077 FinalizeClass(super_class, generating_snapshot); | 1082 FinalizeClass(super_class, generating_snapshot); |
1078 } | 1083 } |
1079 // Finalize type parameters before finalizing the super type. | 1084 // Finalize type parameters before finalizing the super type. |
1080 FinalizeTypeParameters(cls); | 1085 FinalizeTypeParameters(cls); |
1081 // Finalize super type. | 1086 // Finalize super type. |
1082 Type& super_type = Type::Handle(cls.super_type()); | 1087 Type& super_type = Type::Handle(cls.super_type()); |
1083 if (!super_type.IsNull()) { | 1088 if (!super_type.IsNull()) { |
1084 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); | 1089 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); |
1085 cls.set_super_type(super_type); | 1090 cls.set_super_type(super_type); |
1086 } | 1091 } |
| 1092 // Signature classes are finalized upon creation, except function type |
| 1093 // aliases. |
| 1094 if (cls.IsSignatureClass()) { |
| 1095 ASSERT(!cls.IsCanonicalSignatureClass()); |
| 1096 // Check for illegal self references. |
| 1097 GrowableArray<intptr_t> visited_aliases; |
| 1098 if (!IsAliasCycleFree(cls, &visited_aliases)) { |
| 1099 const String& name = String::Handle(cls.Name()); |
| 1100 const Script& script = Script::Handle(cls.script()); |
| 1101 ReportError(script, cls.token_index(), |
| 1102 "typedef '%s' illegally refers to itself", |
| 1103 name.ToCString()); |
| 1104 } |
| 1105 // TODO(regis): Also check this: "It is a compile-time error if any default |
| 1106 // values are specified in the signature of a function type alias". |
| 1107 cls.Finalize(); |
| 1108 return; |
| 1109 } |
1087 // Finalize factory class, if any. | 1110 // Finalize factory class, if any. |
1088 if (cls.is_interface()) { | 1111 if (cls.is_interface()) { |
1089 if (cls.HasFactoryClass()) { | 1112 if (cls.HasFactoryClass()) { |
1090 const Class& factory_class = Class::Handle(cls.FactoryClass()); | 1113 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
1091 if (!factory_class.is_finalized()) { | 1114 if (!factory_class.is_finalized()) { |
1092 FinalizeClass(factory_class, generating_snapshot); | 1115 FinalizeClass(factory_class, generating_snapshot); |
1093 // Finalizing the factory class may indirectly finalize this interface. | 1116 // Finalizing the factory class may indirectly finalize this interface. |
1094 if (cls.is_finalized()) { | 1117 if (cls.is_finalized()) { |
1095 return; | 1118 return; |
1096 } | 1119 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 test2 = test2.SuperClass(); | 1169 test2 = test2.SuperClass(); |
1147 if (!test2.IsNull()) { | 1170 if (!test2.IsNull()) { |
1148 test2 = test2.SuperClass(); | 1171 test2 = test2.SuperClass(); |
1149 } | 1172 } |
1150 } | 1173 } |
1151 // No cycles. | 1174 // No cycles. |
1152 return true; | 1175 return true; |
1153 } | 1176 } |
1154 | 1177 |
1155 | 1178 |
| 1179 // Returns false if the function type alias illegally refers to itself. |
| 1180 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, |
| 1181 GrowableArray<intptr_t>* visited) { |
| 1182 ASSERT(cls.IsSignatureClass()); |
| 1183 ASSERT(!cls.IsCanonicalSignatureClass()); |
| 1184 ASSERT(!cls.is_finalized()); |
| 1185 ASSERT(visited != NULL); |
| 1186 const intptr_t cls_index = cls.index(); |
| 1187 for (int i = 0; i < visited->length(); i++) { |
| 1188 if ((*visited)[i] == cls_index) { |
| 1189 // We have already visited alias 'cls'. We found a cycle. |
| 1190 return false; |
| 1191 } |
| 1192 } |
| 1193 |
| 1194 // Visit the result type and parameter types of this signature type. |
| 1195 visited->Add(cls.index()); |
| 1196 const Function& function = Function::Handle(cls.signature_function()); |
| 1197 // Check class of result type. |
| 1198 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 1199 ResolveType(cls, type, kFinalize); |
| 1200 if (type.IsType() && !type.IsMalformed()) { |
| 1201 const Class& type_class = Class::Handle(type.type_class()); |
| 1202 if (!type_class.is_finalized() && |
| 1203 type_class.IsSignatureClass() && |
| 1204 !type_class.IsCanonicalSignatureClass()) { |
| 1205 if (!IsAliasCycleFree(type_class, visited)) { |
| 1206 return false; |
| 1207 } |
| 1208 } |
| 1209 } |
| 1210 // Check classes of formal parameter types. |
| 1211 const intptr_t num_parameters = function.NumberOfParameters(); |
| 1212 for (intptr_t i = 0; i < num_parameters; i++) { |
| 1213 type = function.ParameterTypeAt(i); |
| 1214 ResolveType(cls, type, kFinalize); |
| 1215 if (type.IsType() && !type.IsMalformed()) { |
| 1216 const Class& type_class = Class::Handle(type.type_class()); |
| 1217 if (!type_class.is_finalized() && |
| 1218 type_class.IsSignatureClass() && |
| 1219 !type_class.IsCanonicalSignatureClass()) { |
| 1220 if (!IsAliasCycleFree(type_class, visited)) { |
| 1221 return false; |
| 1222 } |
| 1223 } |
| 1224 } |
| 1225 } |
| 1226 visited->RemoveLast(); |
| 1227 return true; |
| 1228 } |
| 1229 |
| 1230 |
1156 bool ClassFinalizer::AddInterfaceIfUnique( | 1231 bool ClassFinalizer::AddInterfaceIfUnique( |
1157 const GrowableObjectArray& interface_list, | 1232 const GrowableObjectArray& interface_list, |
1158 const AbstractType& interface, | 1233 const AbstractType& interface, |
1159 AbstractType* conflicting) { | 1234 AbstractType* conflicting) { |
1160 String& interface_class_name = String::Handle(interface.ClassName()); | 1235 String& interface_class_name = String::Handle(interface.ClassName()); |
1161 String& existing_interface_class_name = String::Handle(); | 1236 String& existing_interface_class_name = String::Handle(); |
1162 String& interface_name = String::Handle(); | 1237 String& interface_name = String::Handle(); |
1163 String& existing_interface_name = String::Handle(); | 1238 String& existing_interface_name = String::Handle(); |
1164 AbstractType& other_interface = AbstractType::Handle(); | 1239 AbstractType& other_interface = AbstractType::Handle(); |
1165 for (intptr_t i = 0; i < interface_list.Length(); i++) { | 1240 for (intptr_t i = 0; i < interface_list.Length(); i++) { |
(...skipping 18 matching lines...) Expand all Loading... |
1184 | 1259 |
1185 | 1260 |
1186 // Walks the graph of explicitly declared interfaces of classes and | 1261 // Walks the graph of explicitly declared interfaces of classes and |
1187 // interfaces recursively. Resolves unresolved interfaces. | 1262 // interfaces recursively. Resolves unresolved interfaces. |
1188 // Returns false if there is an interface reference that cannot be | 1263 // Returns false if there is an interface reference that cannot be |
1189 // resolved, or if there is a cycle in the graph. We detect cycles by | 1264 // resolved, or if there is a cycle in the graph. We detect cycles by |
1190 // remembering interfaces we've visited in each path through the | 1265 // remembering interfaces we've visited in each path through the |
1191 // graph. If we visit an interface a second time on a given path, | 1266 // graph. If we visit an interface a second time on a given path, |
1192 // we found a loop. | 1267 // we found a loop. |
1193 void ClassFinalizer::ResolveInterfaces(const Class& cls, | 1268 void ClassFinalizer::ResolveInterfaces(const Class& cls, |
1194 const GrowableObjectArray& visited) { | 1269 GrowableArray<intptr_t>* visited) { |
1195 ASSERT(!visited.IsNull()); | 1270 ASSERT(visited != NULL); |
1196 Class& visited_cls = Class::Handle(); | 1271 const intptr_t cls_index = cls.index(); |
1197 for (int i = 0; i < visited.Length(); i++) { | 1272 for (int i = 0; i < visited->length(); i++) { |
1198 visited_cls ^= visited.At(i); | 1273 if ((*visited)[i] == cls_index) { |
1199 if (visited_cls.raw() == cls.raw()) { | |
1200 // We have already visited interface class 'cls'. We found a cycle. | 1274 // We have already visited interface class 'cls'. We found a cycle. |
1201 const String& interface_name = String::Handle(cls.Name()); | 1275 const String& interface_name = String::Handle(cls.Name()); |
1202 const Script& script = Script::Handle(cls.script()); | 1276 const Script& script = Script::Handle(cls.script()); |
1203 ReportError(script, cls.token_index(), | 1277 ReportError(script, cls.token_index(), |
1204 "cyclic reference found for interface '%s'", | 1278 "cyclic reference found for interface '%s'", |
1205 interface_name.ToCString()); | 1279 interface_name.ToCString()); |
1206 } | 1280 } |
1207 } | 1281 } |
1208 | 1282 |
1209 // If the class/interface has no explicit interfaces, we are done. | 1283 // If the class/interface has no explicit interfaces, we are done. |
1210 Array& super_interfaces = Array::Handle(cls.interfaces()); | 1284 Array& super_interfaces = Array::Handle(cls.interfaces()); |
1211 if (super_interfaces.Length() == 0) { | 1285 if (super_interfaces.Length() == 0) { |
1212 return; | 1286 return; |
1213 } | 1287 } |
1214 | 1288 |
1215 // If cls belongs to core lib or to core lib's implementation, restrictions | 1289 // If cls belongs to core lib or to core lib's implementation, restrictions |
1216 // about allowed interfaces are lifted. | 1290 // about allowed interfaces are lifted. |
1217 const bool cls_belongs_to_core_lib = | 1291 const bool cls_belongs_to_core_lib = |
1218 (cls.library() == Library::CoreLibrary()) || | 1292 (cls.library() == Library::CoreLibrary()) || |
1219 (cls.library() == Library::CoreImplLibrary()); | 1293 (cls.library() == Library::CoreImplLibrary()); |
1220 | 1294 |
1221 // Resolve and check the interfaces of cls. | 1295 // Resolve and check the interfaces of cls. |
1222 visited.Add(cls); | 1296 visited->Add(cls_index); |
1223 AbstractType& interface = AbstractType::Handle(); | 1297 AbstractType& interface = AbstractType::Handle(); |
1224 Class& interface_class = Class::Handle(); | 1298 Class& interface_class = Class::Handle(); |
1225 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1299 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
1226 interface ^= super_interfaces.At(i); | 1300 interface ^= super_interfaces.At(i); |
1227 ResolveType(cls, interface, kFinalizeWellFormed); | 1301 ResolveType(cls, interface, kFinalizeWellFormed); |
1228 if (interface.IsTypeParameter()) { | 1302 if (interface.IsTypeParameter()) { |
1229 const Script& script = Script::Handle(cls.script()); | 1303 const Script& script = Script::Handle(cls.script()); |
1230 ReportError(script, cls.token_index(), | 1304 ReportError(script, cls.token_index(), |
1231 "type parameter '%s' cannot be used as interface", | 1305 "type parameter '%s' cannot be used as interface", |
1232 String::Handle(interface.Name()).ToCString()); | 1306 String::Handle(interface.Name()).ToCString()); |
(...skipping 20 matching lines...) Expand all Loading... |
1253 const Script& script = Script::Handle(cls.script()); | 1327 const Script& script = Script::Handle(cls.script()); |
1254 ReportError(script, cls.token_index(), | 1328 ReportError(script, cls.token_index(), |
1255 "'%s' is not allowed to extend or implement '%s'", | 1329 "'%s' is not allowed to extend or implement '%s'", |
1256 String::Handle(cls.Name()).ToCString(), | 1330 String::Handle(cls.Name()).ToCString(), |
1257 String::Handle(interface_class.Name()).ToCString()); | 1331 String::Handle(interface_class.Name()).ToCString()); |
1258 } | 1332 } |
1259 } | 1333 } |
1260 // Now resolve the super interfaces. | 1334 // Now resolve the super interfaces. |
1261 ResolveInterfaces(interface_class, visited); | 1335 ResolveInterfaces(interface_class, visited); |
1262 } | 1336 } |
1263 visited.RemoveLast(); | 1337 visited->RemoveLast(); |
1264 } | 1338 } |
1265 | 1339 |
1266 | 1340 |
1267 // A class is marked as constant if it has one constant constructor. | 1341 // A class is marked as constant if it has one constant constructor. |
1268 // A constant class: | 1342 // A constant class: |
1269 // - may extend only const classes. | 1343 // - may extend only const classes. |
1270 // - has only const instance fields. | 1344 // - has only const instance fields. |
1271 // Note: we must check for cycles before checking for const properties. | 1345 // Note: we must check for cycles before checking for const properties. |
1272 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { | 1346 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { |
1273 ASSERT(cls.is_const()); | 1347 ASSERT(cls.is_const()); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 void ClassFinalizer::ReportError(const char* format, ...) { | 1483 void ClassFinalizer::ReportError(const char* format, ...) { |
1410 va_list args; | 1484 va_list args; |
1411 va_start(args, format); | 1485 va_start(args, format); |
1412 const Error& error = Error::Handle( | 1486 const Error& error = Error::Handle( |
1413 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1487 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
1414 va_end(args); | 1488 va_end(args); |
1415 ReportError(error); | 1489 ReportError(error); |
1416 } | 1490 } |
1417 | 1491 |
1418 } // namespace dart | 1492 } // namespace dart |
OLD | NEW |