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

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

Issue 10871005: Make ClassFinalizer indifferent on whether we are generating a snapshot or not. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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/class_finalizer_test.cc » ('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"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 #include "vm/symbols.h" 13 #include "vm/symbols.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 DEFINE_FLAG(bool, error_on_malformed_type, false,
18 "Report error for malformed types.");
17 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 19 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
18 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 20 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
19 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 21 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
20 DEFINE_FLAG(bool, verify_implements, false,
21 "Verify that all classes implement their interface.");
22 DECLARE_FLAG(bool, enable_type_checks); 22 DECLARE_FLAG(bool, enable_type_checks);
23 23
24 24
25 bool ClassFinalizer::AllClassesFinalized() { 25 bool ClassFinalizer::AllClassesFinalized() {
26 ObjectStore* object_store = Isolate::Current()->object_store(); 26 ObjectStore* object_store = Isolate::Current()->object_store();
27 const GrowableObjectArray& classes = 27 const GrowableObjectArray& classes =
28 GrowableObjectArray::Handle(object_store->pending_classes()); 28 GrowableObjectArray::Handle(object_store->pending_classes());
29 return classes.Length() == 0; 29 return classes.Length() == 0;
30 } 30 }
31 31
32 32
33 // Class finalization occurs: 33 // Class finalization occurs:
34 // a) when bootstrap process completes (VerifyBootstrapClasses). 34 // a) when bootstrap process completes (VerifyBootstrapClasses).
35 // b) after the user classes are loaded (dart_api). 35 // b) after the user classes are loaded (dart_api).
36 bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) { 36 bool ClassFinalizer::FinalizePendingClasses() {
37 bool retval = true; 37 bool retval = true;
38 Isolate* isolate = Isolate::Current(); 38 Isolate* isolate = Isolate::Current();
39 ASSERT(isolate != NULL); 39 ASSERT(isolate != NULL);
40 ObjectStore* object_store = isolate->object_store(); 40 ObjectStore* object_store = isolate->object_store();
41 const Error& error = Error::Handle(object_store->sticky_error()); 41 const Error& error = Error::Handle(object_store->sticky_error());
42 if (!error.IsNull()) { 42 if (!error.IsNull()) {
43 return false; 43 return false;
44 } 44 }
45 GrowableObjectArray& class_array = GrowableObjectArray::Handle();
46 class_array = object_store->pending_classes();
47 ASSERT(!class_array.IsNull());
48 if (class_array.Length() == 0) {
49 return true;
50 }
45 LongJump* base = isolate->long_jump_base(); 51 LongJump* base = isolate->long_jump_base();
46 LongJump jump; 52 LongJump jump;
47 isolate->set_long_jump_base(&jump); 53 isolate->set_long_jump_base(&jump);
48 if (setjmp(*jump.Set()) == 0) { 54 if (setjmp(*jump.Set()) == 0) {
49 GrowableObjectArray& class_array = GrowableObjectArray::Handle();
50 class_array = object_store->pending_classes();
51 ASSERT(!class_array.IsNull());
52 Class& cls = Class::Handle(); 55 Class& cls = Class::Handle();
53 // First resolve all superclasses. 56 // First resolve all superclasses.
54 for (intptr_t i = 0; i < class_array.Length(); i++) { 57 for (intptr_t i = 0; i < class_array.Length(); i++) {
55 cls ^= class_array.At(i); 58 cls ^= class_array.At(i);
56 if (FLAG_trace_class_finalization) { 59 if (FLAG_trace_class_finalization) {
57 OS::Print("Resolving super and default: %s\n", cls.ToCString()); 60 OS::Print("Resolving super and default: %s\n", cls.ToCString());
58 } 61 }
59 ResolveSuperType(cls); 62 ResolveSuperType(cls);
60 if (cls.is_interface()) { 63 if (cls.is_interface()) {
61 ResolveFactoryClass(cls); 64 ResolveFactoryClass(cls);
62 } 65 }
63 } 66 }
64 // Finalize all classes. 67 // Finalize all classes.
65 for (intptr_t i = 0; i < class_array.Length(); i++) { 68 for (intptr_t i = 0; i < class_array.Length(); i++) {
66 cls ^= class_array.At(i); 69 cls ^= class_array.At(i);
67 FinalizeClass(cls, generating_snapshot); 70 FinalizeClass(cls);
68 } 71 }
69 if (FLAG_print_classes) { 72 if (FLAG_print_classes) {
70 for (intptr_t i = 0; i < class_array.Length(); i++) { 73 for (intptr_t i = 0; i < class_array.Length(); i++) {
71 cls ^= class_array.At(i); 74 cls ^= class_array.At(i);
72 PrintClassInformation(cls); 75 PrintClassInformation(cls);
73 } 76 }
74 } 77 }
75 if (FLAG_verify_implements) {
76 for (intptr_t i = 0; i < class_array.Length(); i++) {
77 cls ^= class_array.At(i);
78 if (!cls.is_interface()) {
79 VerifyClassImplements(cls);
80 }
81 }
82 }
83 // Clear pending classes array. 78 // Clear pending classes array.
84 class_array = GrowableObjectArray::New(); 79 class_array = GrowableObjectArray::New();
85 object_store->set_pending_classes(class_array); 80 object_store->set_pending_classes(class_array);
86 } else { 81 } else {
87 retval = false; 82 retval = false;
88 } 83 }
89 isolate->set_long_jump_base(base); 84 isolate->set_long_jump_base(base);
90 return retval; 85 return retval;
91 } 86 }
92 87
93 88
94 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. 89 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur.
95 // No cycles are allowed. 90 // No cycles are allowed.
96 void ClassFinalizer::CollectInterfaces(const Class& cls, 91 void ClassFinalizer::CollectInterfaces(const Class& cls,
97 const GrowableObjectArray& collected) { 92 const GrowableObjectArray& collected) {
98 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); 93 const Array& interface_array = Array::ZoneHandle(cls.interfaces());
99 AbstractType& interface = AbstractType::Handle(); 94 AbstractType& interface = AbstractType::Handle();
100 Class& interface_class = Class::Handle(); 95 Class& interface_class = Class::Handle();
101 for (intptr_t i = 0; i < interface_array.Length(); i++) { 96 for (intptr_t i = 0; i < interface_array.Length(); i++) {
102 interface ^= interface_array.At(i); 97 interface ^= interface_array.At(i);
103 interface_class = interface.type_class(); 98 interface_class = interface.type_class();
104 collected.Add(interface_class); 99 collected.Add(interface_class);
105 CollectInterfaces(interface_class, collected); 100 CollectInterfaces(interface_class, collected);
106 } 101 }
107 } 102 }
108 103
109 104
110 #if defined (DEBUG)
111 // Collect all interfaces of the class 'cls' and check that every function
112 // defined in each interface can be found in the class.
113 // No need to check instance fields since they have been turned into
114 // getters/setters.
115 void ClassFinalizer::VerifyClassImplements(const Class& cls) {
116 ASSERT(!cls.is_interface());
117 const GrowableObjectArray& interfaces =
118 GrowableObjectArray::Handle(GrowableObjectArray::New());
119 CollectInterfaces(cls, interfaces);
120 const String& class_name = String::Handle(cls.Name());
121 Class& interface_class = Class::Handle();
122 String& interface_name = String::Handle();
123 Array& interface_functions = Array::Handle();
124 for (int i = 0; i < interfaces.Length(); i++) {
125 interface_class ^= interfaces.At(i);
126 interface_name = interface_class.Name();
127 interface_functions = interface_class.functions();
128 for (intptr_t f = 0; f < interface_functions.Length(); f++) {
129 Function& interface_function = Function::Handle();
130 interface_function ^= interface_functions.At(f);
131 const String& function_name = String::Handle(interface_function.name());
132 // Check for constructor/factory.
133 if (function_name.StartsWith(interface_name)) {
134 // TODO(srdjan): convert 'InterfaceName.' to 'ClassName.' and check.
135 continue;
136 }
137 if (interface_function.kind() == RawFunction::kConstImplicitGetter) {
138 // This interface constants are not overridable.
139 continue;
140 }
141 // Lookup function in 'cls' and all its super classes.
142 Class& test_class = Class::Handle(cls.raw());
143 Function& class_function =
144 Function::Handle(test_class.LookupDynamicFunction(function_name));
145 while (class_function.IsNull()) {
146 test_class = test_class.SuperClass();
147 if (test_class.IsNull()) break;
148 class_function = test_class.LookupDynamicFunction(function_name);
149 }
150 if (class_function.IsNull()) {
151 OS::PrintErr("%s implements '%s' missing: '%s'\n",
152 class_name.ToCString(),
153 interface_name.ToCString(),
154 function_name.ToCString());
155 } else {
156 Error& malformed_error = Error::Handle();
157 if (!class_function.IsSubtypeOf(TypeArguments::Handle(),
158 interface_function,
159 TypeArguments::Handle(),
160 &malformed_error)) {
161 if (!malformed_error.IsNull()) {
162 OS::PrintErr("%s\n", malformed_error.ToErrorCString());
163 }
164 OS::PrintErr("The type of instance method '%s' in class '%s' is not "
165 "a subtype of the type of '%s' in interface '%s'\n",
166 function_name.ToCString(),
167 class_name.ToCString(),
168 function_name.ToCString(),
169 interface_name.ToCString());
170 }
171 }
172 }
173 }
174 }
175 #else
176
177 void ClassFinalizer::VerifyClassImplements(const Class& cls) {}
178
179 #endif
180
181
182 void ClassFinalizer::VerifyBootstrapClasses() { 105 void ClassFinalizer::VerifyBootstrapClasses() {
183 if (FLAG_trace_class_finalization) { 106 if (FLAG_trace_class_finalization) {
184 OS::Print("VerifyBootstrapClasses START.\n"); 107 OS::Print("VerifyBootstrapClasses START.\n");
185 } 108 }
186 ObjectStore* object_store = Isolate::Current()->object_store(); 109 ObjectStore* object_store = Isolate::Current()->object_store();
187 110
188 Class& cls = Class::Handle(); 111 Class& cls = Class::Handle();
189 #if defined(DEBUG) 112 #if defined(DEBUG)
190 // Basic checking. 113 // Basic checking.
191 cls = object_store->object_class(); 114 cls = object_store->object_class();
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 AbstractTypeArguments::Handle(parameterized_type.arguments()); 594 AbstractTypeArguments::Handle(parameterized_type.arguments());
672 if (!arguments.IsNull()) { 595 if (!arguments.IsNull()) {
673 intptr_t num_arguments = arguments.Length(); 596 intptr_t num_arguments = arguments.Length();
674 AbstractType& type_argument = AbstractType::Handle(); 597 AbstractType& type_argument = AbstractType::Handle();
675 for (intptr_t i = 0; i < num_arguments; i++) { 598 for (intptr_t i = 0; i < num_arguments; i++) {
676 type_argument = arguments.TypeAt(i); 599 type_argument = arguments.TypeAt(i);
677 type_argument = FinalizeType(cls, type_argument, finalization); 600 type_argument = FinalizeType(cls, type_argument, finalization);
678 if (type_argument.IsMalformed()) { 601 if (type_argument.IsMalformed()) {
679 // In production mode, malformed type arguments are mapped to Dynamic. 602 // In production mode, malformed type arguments are mapped to Dynamic.
680 // In checked mode, a type with malformed type arguments is malformed. 603 // In checked mode, a type with malformed type arguments is malformed.
681 if (FLAG_enable_type_checks) { 604 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
682 const Error& error = Error::Handle(type_argument.malformed_error()); 605 const Error& error = Error::Handle(type_argument.malformed_error());
683 const String& type_name = 606 const String& type_name =
684 String::Handle(parameterized_type.UserVisibleName()); 607 String::Handle(parameterized_type.UserVisibleName());
685 FinalizeMalformedType(error, cls, parameterized_type, finalization, 608 FinalizeMalformedType(error, cls, parameterized_type, finalization,
686 "type '%s' has malformed type argument", 609 "type '%s' has malformed type argument",
687 type_name.ToCString()); 610 type_name.ToCString());
688 return parameterized_type.raw(); 611 return parameterized_type.raw();
689 } else { 612 } else {
690 type_argument = Type::DynamicType(); 613 type_argument = Type::DynamicType();
691 } 614 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 if (type_class.IsCanonicalSignatureClass()) { 729 if (type_class.IsCanonicalSignatureClass()) {
807 ASSERT(type_class.is_finalized()); 730 ASSERT(type_class.is_finalized());
808 // Resolve and finalize the result and parameter types of the signature 731 // Resolve and finalize the result and parameter types of the signature
809 // function of this signature class. 732 // function of this signature class.
810 ASSERT(type_class.SignatureType() == type.raw()); 733 ASSERT(type_class.SignatureType() == type.raw());
811 ResolveAndFinalizeSignature( 734 ResolveAndFinalizeSignature(
812 type_class, Function::Handle(type_class.signature_function())); 735 type_class, Function::Handle(type_class.signature_function()));
813 } else { 736 } else {
814 // This type is a function type alias. Its class may need to be finalized 737 // This type is a function type alias. Its class may need to be finalized
815 // and checked for illegal self reference. 738 // and checked for illegal self reference.
816 FinalizeClass(type_class, false); 739 FinalizeClass(type_class);
817 // Finalizing the signature function here (as in the canonical case above) 740 // Finalizing the signature function here (as in the canonical case above)
818 // would not mark the canonical signature type as finalized. 741 // would not mark the canonical signature type as finalized.
819 const Type& signature_type = Type::Handle(type_class.SignatureType()); 742 const Type& signature_type = Type::Handle(type_class.SignatureType());
820 FinalizeType(cls, signature_type, finalization); 743 FinalizeType(cls, signature_type, finalization);
821 } 744 }
822 } 745 }
823 746
824 if (finalization >= kCanonicalize) { 747 if (finalization >= kCanonicalize) {
825 return parameterized_type.Canonicalize(); 748 return parameterized_type.Canonicalize();
826 } else { 749 } else {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 function_name.ToCString(), 995 function_name.ToCString(),
1073 class_name.ToCString(), 996 class_name.ToCString(),
1074 function_name.ToCString(), 997 function_name.ToCString(),
1075 super_class_name.ToCString()); 998 super_class_name.ToCString());
1076 } 999 }
1077 } 1000 }
1078 } 1001 }
1079 } 1002 }
1080 1003
1081 1004
1082 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { 1005 void ClassFinalizer::FinalizeClass(const Class& cls) {
1083 if (cls.is_finalized()) { 1006 if (cls.is_finalized()) {
1084 return; 1007 return;
1085 } 1008 }
1086 if (FLAG_trace_class_finalization) { 1009 if (FLAG_trace_class_finalization) {
1087 OS::Print("Finalize %s\n", cls.ToCString()); 1010 OS::Print("Finalize %s\n", cls.ToCString());
1088 } 1011 }
1089 if (!IsSuperCycleFree(cls)) { 1012 if (!IsSuperCycleFree(cls)) {
1090 const String& name = String::Handle(cls.Name()); 1013 const String& name = String::Handle(cls.Name());
1091 const Script& script = Script::Handle(cls.script()); 1014 const Script& script = Script::Handle(cls.script());
1092 ReportError(script, cls.token_pos(), 1015 ReportError(script, cls.token_pos(),
1093 "class '%s' has a cycle in its superclass relationship", 1016 "class '%s' has a cycle in its superclass relationship",
1094 name.ToCString()); 1017 name.ToCString());
1095 } 1018 }
1096 GrowableArray<intptr_t> visited_interfaces; 1019 GrowableArray<intptr_t> visited_interfaces;
1097 ResolveInterfaces(cls, &visited_interfaces); 1020 ResolveInterfaces(cls, &visited_interfaces);
1098 // Finalize super class. 1021 // Finalize super class.
1099 const Class& super_class = Class::Handle(cls.SuperClass()); 1022 const Class& super_class = Class::Handle(cls.SuperClass());
1100 if (!super_class.IsNull()) { 1023 if (!super_class.IsNull()) {
1101 FinalizeClass(super_class, generating_snapshot); 1024 FinalizeClass(super_class);
1102 } 1025 }
1103 // Finalize type parameters before finalizing the super type. 1026 // Finalize type parameters before finalizing the super type.
1104 FinalizeTypeParameters(cls); 1027 FinalizeTypeParameters(cls);
1105 // Finalize super type. 1028 // Finalize super type.
1106 Type& super_type = Type::Handle(cls.super_type()); 1029 Type& super_type = Type::Handle(cls.super_type());
1107 if (!super_type.IsNull()) { 1030 if (!super_type.IsNull()) {
1108 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed); 1031 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1109 cls.set_super_type(super_type); 1032 cls.set_super_type(super_type);
1110 } 1033 }
1111 // Signature classes are finalized upon creation, except function type 1034 // Signature classes are finalized upon creation, except function type
(...skipping 13 matching lines...) Expand all
1125 // Signature classes extend Object. No need to add this class to the direct 1048 // Signature classes extend Object. No need to add this class to the direct
1126 // subclasses of Object. 1049 // subclasses of Object.
1127 ASSERT(super_type.IsNull() || super_type.IsObjectType()); 1050 ASSERT(super_type.IsNull() || super_type.IsObjectType());
1128 return; 1051 return;
1129 } 1052 }
1130 // Finalize factory class, if any. 1053 // Finalize factory class, if any.
1131 if (cls.is_interface()) { 1054 if (cls.is_interface()) {
1132 if (cls.HasFactoryClass()) { 1055 if (cls.HasFactoryClass()) {
1133 const Class& factory_class = Class::Handle(cls.FactoryClass()); 1056 const Class& factory_class = Class::Handle(cls.FactoryClass());
1134 if (!factory_class.is_finalized()) { 1057 if (!factory_class.is_finalized()) {
1135 FinalizeClass(factory_class, generating_snapshot); 1058 FinalizeClass(factory_class);
1136 // Finalizing the factory class may indirectly finalize this interface. 1059 // Finalizing the factory class may indirectly finalize this interface.
1137 if (cls.is_finalized()) { 1060 if (cls.is_finalized()) {
1138 return; 1061 return;
1139 } 1062 }
1140 } 1063 }
1141 } 1064 }
1142 } 1065 }
1143 // Finalize interface types (but not necessarily interface classes). 1066 // Finalize interface types (but not necessarily interface classes).
1144 Array& interface_types = Array::Handle(cls.interfaces()); 1067 Array& interface_types = Array::Handle(cls.interfaces());
1145 AbstractType& interface_type = AbstractType::Handle(); 1068 AbstractType& interface_type = AbstractType::Handle();
1146 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1069 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1147 interface_type ^= interface_types.At(i); 1070 interface_type ^= interface_types.At(i);
1148 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1071 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1149 interface_types.SetAt(i, interface_type); 1072 interface_types.SetAt(i, interface_type);
1150 } 1073 }
1151 // Mark as finalized before resolving type parameter upper bounds and member 1074 // Mark as finalized before resolving type parameter upper bounds and member
1152 // types in order to break cycles. 1075 // types in order to break cycles.
1153 cls.Finalize(); 1076 cls.Finalize();
1154 ResolveAndFinalizeUpperBounds(cls); 1077 ResolveAndFinalizeUpperBounds(cls);
1155 ResolveAndFinalizeMemberTypes(cls); 1078 ResolveAndFinalizeMemberTypes(cls);
1156 // Run additional checks after all types are finalized. 1079 // Run additional checks after all types are finalized.
1157 if (cls.is_const()) { 1080 if (cls.is_const()) {
1158 CheckForLegalConstClass(cls); 1081 CheckForLegalConstClass(cls);
1159 } 1082 }
1160 // Check to ensure we don't have classes with native fields in libraries 1083 // Check to ensure we don't have classes with native fields in libraries
1161 // which do not have a native resolver. 1084 // which do not have a native resolver.
1162 if (!generating_snapshot && cls.num_native_fields() != 0) { 1085 if (cls.num_native_fields() != 0) {
1163 const Library& lib = Library::Handle(cls.library()); 1086 const Library& lib = Library::Handle(cls.library());
1164 if (lib.native_entry_resolver() == NULL) { 1087 if (lib.native_entry_resolver() == NULL) {
1165 const String& cls_name = String::Handle(cls.Name()); 1088 const String& cls_name = String::Handle(cls.Name());
1166 const String& lib_name = String::Handle(lib.url()); 1089 const String& lib_name = String::Handle(lib.url());
1167 const Script& script = Script::Handle(cls.script()); 1090 const Script& script = Script::Handle(cls.script());
1168 ReportError(script, cls.token_pos(), 1091 ReportError(script, cls.token_pos(),
1169 "class '%s' is trying to extend a native fields class, " 1092 "class '%s' is trying to extend a native fields class, "
1170 "but library '%s' has no native resolvers", 1093 "but library '%s' has no native resolvers",
1171 cls_name.ToCString(), lib_name.ToCString()); 1094 cls_name.ToCString(), lib_name.ToCString());
1172 } 1095 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 return false; 1170 return false;
1248 } 1171 }
1249 } 1172 }
1250 } 1173 }
1251 } 1174 }
1252 visited->RemoveLast(); 1175 visited->RemoveLast();
1253 return true; 1176 return true;
1254 } 1177 }
1255 1178
1256 1179
1257 bool ClassFinalizer::AddInterfaceIfUnique(
1258 const GrowableObjectArray& interface_list,
1259 const AbstractType& interface,
1260 AbstractType* conflicting) {
1261 String& interface_class_name = String::Handle(interface.ClassName());
1262 String& existing_interface_class_name = String::Handle();
1263 String& interface_name = String::Handle();
1264 String& existing_interface_name = String::Handle();
1265 AbstractType& other_interface = AbstractType::Handle();
1266 for (intptr_t i = 0; i < interface_list.Length(); i++) {
1267 other_interface ^= interface_list.At(i);
1268 existing_interface_class_name = other_interface.ClassName();
1269 if (interface_class_name.Equals(existing_interface_class_name)) {
1270 // Same interface class name, now check names of type arguments.
1271 interface_name = interface.Name();
1272 existing_interface_name = other_interface.Name();
1273 // TODO(regis): Revisit depending on the outcome of issue 4905685.
1274 if (!interface_name.Equals(existing_interface_name)) {
1275 *conflicting = other_interface.raw();
1276 return false;
1277 } else {
1278 return true;
1279 }
1280 }
1281 }
1282 interface_list.Add(interface);
1283 return true;
1284 }
1285
1286
1287 // Walks the graph of explicitly declared interfaces of classes and 1180 // Walks the graph of explicitly declared interfaces of classes and
1288 // interfaces recursively. Resolves unresolved interfaces. 1181 // interfaces recursively. Resolves unresolved interfaces.
1289 // Returns false if there is an interface reference that cannot be 1182 // Returns false if there is an interface reference that cannot be
1290 // resolved, or if there is a cycle in the graph. We detect cycles by 1183 // resolved, or if there is a cycle in the graph. We detect cycles by
1291 // remembering interfaces we've visited in each path through the 1184 // remembering interfaces we've visited in each path through the
1292 // graph. If we visit an interface a second time on a given path, 1185 // graph. If we visit an interface a second time on a given path,
1293 // we found a loop. 1186 // we found a loop.
1294 void ClassFinalizer::ResolveInterfaces(const Class& cls, 1187 void ClassFinalizer::ResolveInterfaces(const Class& cls,
1295 GrowableArray<intptr_t>* visited) { 1188 GrowableArray<intptr_t>* visited) {
1296 ASSERT(visited != NULL); 1189 ASSERT(visited != NULL);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, 1340 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
1448 const Class& cls, 1341 const Class& cls,
1449 const Type& type, 1342 const Type& type,
1450 FinalizationKind finalization, 1343 FinalizationKind finalization,
1451 const char* format, ...) { 1344 const char* format, ...) {
1452 va_list args; 1345 va_list args;
1453 va_start(args, format); 1346 va_start(args, format);
1454 LanguageError& error = LanguageError::Handle(); 1347 LanguageError& error = LanguageError::Handle();
1455 if (FLAG_enable_type_checks || 1348 if (FLAG_enable_type_checks ||
1456 !type.HasResolvedTypeClass() || 1349 !type.HasResolvedTypeClass() ||
1457 (finalization == kCanonicalizeWellFormed)) { 1350 (finalization == kCanonicalizeWellFormed) ||
1351 FLAG_error_on_malformed_type) {
1458 const Script& script = Script::Handle(cls.script()); 1352 const Script& script = Script::Handle(cls.script());
1459 if (prev_error.IsNull()) { 1353 if (prev_error.IsNull()) {
1460 error ^= Parser::FormatError( 1354 error ^= Parser::FormatError(
1461 script, type.token_pos(), "Error", format, args); 1355 script, type.token_pos(), "Error", format, args);
1462 } else { 1356 } else {
1463 error ^= Parser::FormatErrorWithAppend( 1357 error ^= Parser::FormatErrorWithAppend(
1464 prev_error, script, type.token_pos(), "Error", format, args); 1358 prev_error, script, type.token_pos(), "Error", format, args);
1465 } 1359 }
1466 if (finalization == kCanonicalizeWellFormed) { 1360 if ((finalization == kCanonicalizeWellFormed) ||
1361 FLAG_error_on_malformed_type) {
1467 ReportError(error); 1362 ReportError(error);
1468 } 1363 }
1469 } 1364 }
1470 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 1365 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
1471 // In check mode, always mark the type as malformed. 1366 // In check mode, always mark the type as malformed.
1472 // In production mode, mark the type as malformed only if its type class is 1367 // In production mode, mark the type as malformed only if its type class is
1473 // not resolved. 1368 // not resolved.
1474 type.set_malformed_error(error); 1369 type.set_malformed_error(error);
1475 } else { 1370 } else {
1476 // In production mode, do not mark the type with a resolved type class as 1371 // In production mode, do not mark the type with a resolved type class as
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 void ClassFinalizer::ReportError(const char* format, ...) { 1404 void ClassFinalizer::ReportError(const char* format, ...) {
1510 va_list args; 1405 va_list args;
1511 va_start(args, format); 1406 va_start(args, format);
1512 const Error& error = Error::Handle( 1407 const Error& error = Error::Handle(
1513 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1408 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1514 va_end(args); 1409 va_end(args);
1515 ReportError(error); 1410 ReportError(error);
1516 } 1411 }
1517 1412
1518 } // namespace dart 1413 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698