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

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

Issue 10377095: Implement latest rules prohibiting some self referencing typedefs. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698