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

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

Issue 22685007: Implement updated method overriding rules in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
OLDNEW
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/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_bad_override, false,
18 "Report error for bad overrides.");
17 DEFINE_FLAG(bool, error_on_malformed_type, false, 19 DEFINE_FLAG(bool, error_on_malformed_type, false,
18 "Report error for malformed types."); 20 "Report error for malformed types.");
19 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 21 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
20 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 22 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
21 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 23 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
22 DECLARE_FLAG(bool, enable_type_checks); 24 DECLARE_FLAG(bool, enable_type_checks);
23 DECLARE_FLAG(bool, use_cha); 25 DECLARE_FLAG(bool, use_cha);
24 26
25 bool ClassFinalizer::AllClassesFinalized() { 27 bool ClassFinalizer::AllClassesFinalized() {
26 ObjectStore* object_store = Isolate::Current()->object_store(); 28 ObjectStore* object_store = Isolate::Current()->object_store();
(...skipping 16 matching lines...) Expand all
43 // Switch all functions' code to unoptimized. 45 // Switch all functions' code to unoptimized.
44 const ClassTable& class_table = *Isolate::Current()->class_table(); 46 const ClassTable& class_table = *Isolate::Current()->class_table();
45 Class& cls = Class::Handle(); 47 Class& cls = Class::Handle();
46 Array& array = Array::Handle(); 48 Array& array = Array::Handle();
47 Function& function = Function::Handle(); 49 Function& function = Function::Handle();
48 for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) { 50 for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) {
49 intptr_t cid = added_subclasses_to_cids[i]; 51 intptr_t cid = added_subclasses_to_cids[i];
50 cls = class_table.At(cid); 52 cls = class_table.At(cid);
51 ASSERT(!cls.IsNull()); 53 ASSERT(!cls.IsNull());
52 array = cls.functions(); 54 array = cls.functions();
53 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); 55 const intptr_t num_functions = array.IsNull() ? 0 : array.Length();
54 for (intptr_t f = 0; f < num_functions; f++) { 56 for (intptr_t f = 0; f < num_functions; f++) {
55 function ^= array.At(f); 57 function ^= array.At(f);
56 ASSERT(!function.IsNull()); 58 ASSERT(!function.IsNull());
57 if (function.HasOptimizedCode()) { 59 if (function.HasOptimizedCode()) {
58 function.SwitchToUnoptimizedCode(); 60 function.SwitchToUnoptimizedCode();
59 } 61 }
60 } 62 }
61 } 63 }
62 } 64 }
63 65
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); 135 GrowableObjectArray& class_array = GrowableObjectArray::Handle();
134 class_array = object_store->pending_classes(); 136 class_array = object_store->pending_classes();
135 ASSERT(!class_array.IsNull()); 137 ASSERT(!class_array.IsNull());
136 // Collect superclasses that were already finalized before this run of 138 // Collect superclasses that were already finalized before this run of
137 // finalization. 139 // finalization.
138 CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids); 140 CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids);
139 Class& cls = Class::Handle(); 141 Class& cls = Class::Handle();
140 // First resolve all superclasses. 142 // First resolve all superclasses.
141 for (intptr_t i = 0; i < class_array.Length(); i++) { 143 for (intptr_t i = 0; i < class_array.Length(); i++) {
142 cls ^= class_array.At(i); 144 cls ^= class_array.At(i);
143 if (FLAG_trace_class_finalization) {
144 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
145 }
146 GrowableArray<intptr_t> visited_interfaces; 145 GrowableArray<intptr_t> visited_interfaces;
147 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces); 146 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces);
148 } 147 }
149 // Finalize all classes. 148 // Finalize all classes.
150 for (intptr_t i = 0; i < class_array.Length(); i++) { 149 for (intptr_t i = 0; i < class_array.Length(); i++) {
151 cls ^= class_array.At(i); 150 cls ^= class_array.At(i);
152 FinalizeTypesInClass(cls); 151 FinalizeTypesInClass(cls);
153 } 152 }
154 if (FLAG_print_classes) { 153 if (FLAG_print_classes) {
155 for (intptr_t i = 0; i < class_array.Length(); i++) { 154 for (intptr_t i = 0; i < class_array.Length(); i++) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 const Class& cls, 300 const Class& cls,
302 const Function& factory, 301 const Function& factory,
303 const GrowableObjectArray& visited_factories) { 302 const GrowableObjectArray& visited_factories) {
304 ASSERT(factory.IsRedirectingFactory()); 303 ASSERT(factory.IsRedirectingFactory());
305 304
306 // Check for redirection cycle. 305 // Check for redirection cycle.
307 for (int i = 0; i < visited_factories.Length(); i++) { 306 for (int i = 0; i < visited_factories.Length(); i++) {
308 if (visited_factories.At(i) == factory.raw()) { 307 if (visited_factories.At(i) == factory.raw()) {
309 // A redirection cycle is reported as a compile-time error. 308 // A redirection cycle is reported as a compile-time error.
310 const Script& script = Script::Handle(cls.script()); 309 const Script& script = Script::Handle(cls.script());
311 ReportError(script, factory.token_pos(), 310 ReportError(Error::Handle(), // No previous error.
311 script, factory.token_pos(),
312 "factory '%s' illegally redirects to itself", 312 "factory '%s' illegally redirects to itself",
313 String::Handle(factory.name()).ToCString()); 313 String::Handle(factory.name()).ToCString());
314 } 314 }
315 } 315 }
316 visited_factories.Add(factory); 316 visited_factories.Add(factory);
317 317
318 // Check if target is already resolved. 318 // Check if target is already resolved.
319 Type& type = Type::Handle(factory.RedirectionType()); 319 Type& type = Type::Handle(factory.RedirectionType());
320 Function& target = Function::Handle(factory.RedirectionTarget()); 320 Function& target = Function::Handle(factory.RedirectionTarget());
321 if (type.IsMalformed()) { 321 if (type.IsMalformed()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 cls, 375 cls,
376 factory.token_pos(), 376 factory.token_pos(),
377 "class '%s' has no constructor or factory named '%s'", 377 "class '%s' has no constructor or factory named '%s'",
378 target_class_name.ToCString(), 378 target_class_name.ToCString(),
379 user_visible_target_name.ToCString()); 379 user_visible_target_name.ToCString());
380 factory.SetRedirectionType(type); 380 factory.SetRedirectionType(type);
381 ASSERT(factory.RedirectionTarget() == Function::null()); 381 ASSERT(factory.RedirectionTarget() == Function::null());
382 return; 382 return;
383 } 383 }
384 384
385 // Verify that the target is compatible with the redirecting factory. 385 if (FLAG_error_on_bad_override) {
386 if (!target.HasCompatibleParametersWith(factory)) { 386 // Verify that the target is compatible with the redirecting factory.
387 type = NewFinalizedMalformedType( 387 Error& error = Error::Handle();
388 Error::Handle(), // No previous error. 388 if (!target.HasCompatibleParametersWith(factory, &error)) {
389 cls, 389 type = NewFinalizedMalformedType(
390 factory.token_pos(), 390 error, target_class, target.token_pos(),
391 "constructor '%s' has incompatible parameters with " 391 "constructor '%s' has incompatible parameters with "
392 "redirecting factory '%s'", 392 "redirecting factory '%s'",
393 String::Handle(target.name()).ToCString(), 393 String::Handle(target.name()).ToCString(),
394 String::Handle(factory.name()).ToCString()); 394 String::Handle(factory.name()).ToCString());
395 factory.SetRedirectionType(type); 395 factory.SetRedirectionType(type);
396 ASSERT(factory.RedirectionTarget() == Function::null()); 396 ASSERT(factory.RedirectionTarget() == Function::null());
397 return; 397 return;
398 }
398 } 399 }
399 400
400 // Verify that the target is const if the redirecting factory is const. 401 // Verify that the target is const if the redirecting factory is const.
401 if (factory.is_const() && !target.is_const()) { 402 if (factory.is_const() && !target.is_const()) {
402 const Script& script = Script::Handle(cls.script()); 403 const Script& script = Script::Handle(target_class.script());
403 ReportError(script, factory.token_pos(), 404 ReportError(Error::Handle(), // No previous error.
405 script, target.token_pos(),
404 "constructor '%s' must be const as required by redirecting" 406 "constructor '%s' must be const as required by redirecting"
405 "const factory '%s'", 407 "const factory '%s'",
406 String::Handle(target.name()).ToCString(), 408 String::Handle(target.name()).ToCString(),
407 String::Handle(factory.name()).ToCString()); 409 String::Handle(factory.name()).ToCString());
408 } 410 }
409 411
410 // Update redirection data with resolved target. 412 // Update redirection data with resolved target.
411 factory.SetRedirectionTarget(target); 413 factory.SetRedirectionTarget(target);
412 // Not needed anymore. 414 // Not needed anymore.
413 factory.SetRedirectionIdentifier(Object::null_string()); 415 factory.SetRedirectionIdentifier(Object::null_string());
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 494 }
493 return; 495 return;
494 } 496 }
495 parameterized_type.set_type_class(type_class); 497 parameterized_type.set_type_class(type_class);
496 } 498 }
497 499
498 // Resolve type arguments, if any. 500 // Resolve type arguments, if any.
499 const AbstractTypeArguments& arguments = 501 const AbstractTypeArguments& arguments =
500 AbstractTypeArguments::Handle(type.arguments()); 502 AbstractTypeArguments::Handle(type.arguments());
501 if (!arguments.IsNull()) { 503 if (!arguments.IsNull()) {
502 intptr_t num_arguments = arguments.Length(); 504 const intptr_t num_arguments = arguments.Length();
503 AbstractType& type_argument = AbstractType::Handle(); 505 AbstractType& type_argument = AbstractType::Handle();
504 for (intptr_t i = 0; i < num_arguments; i++) { 506 for (intptr_t i = 0; i < num_arguments; i++) {
505 type_argument = arguments.TypeAt(i); 507 type_argument = arguments.TypeAt(i);
506 ResolveType(cls, type_argument, finalization); 508 ResolveType(cls, type_argument, finalization);
507 } 509 }
508 } 510 }
509 } 511 }
510 512
511 513
512 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 514 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 if (!type_class.is_type_finalized()) { 763 if (!type_class.is_type_finalized()) {
762 FinalizeTypeParameters(type_class); 764 FinalizeTypeParameters(type_class);
763 ResolveUpperBounds(type_class); 765 ResolveUpperBounds(type_class);
764 } 766 }
765 767
766 // Finalize the current type arguments of the type, which are still the 768 // Finalize the current type arguments of the type, which are still the
767 // parsed type arguments. 769 // parsed type arguments.
768 AbstractTypeArguments& arguments = 770 AbstractTypeArguments& arguments =
769 AbstractTypeArguments::Handle(parameterized_type.arguments()); 771 AbstractTypeArguments::Handle(parameterized_type.arguments());
770 if (!arguments.IsNull()) { 772 if (!arguments.IsNull()) {
771 intptr_t num_arguments = arguments.Length(); 773 const intptr_t num_arguments = arguments.Length();
772 AbstractType& type_argument = AbstractType::Handle(); 774 AbstractType& type_argument = AbstractType::Handle();
773 for (intptr_t i = 0; i < num_arguments; i++) { 775 for (intptr_t i = 0; i < num_arguments; i++) {
774 type_argument = arguments.TypeAt(i); 776 type_argument = arguments.TypeAt(i);
775 type_argument = FinalizeType(cls, type_argument, finalization); 777 type_argument = FinalizeType(cls, type_argument, finalization);
776 if (type_argument.IsMalformed()) { 778 if (type_argument.IsMalformed()) {
777 // Malformed type arguments are mapped to dynamic. 779 // Malformed type arguments are mapped to dynamic.
778 type_argument = Type::DynamicType(); 780 type_argument = Type::DynamicType();
779 } 781 }
780 arguments.SetTypeAt(i, type_argument); 782 arguments.SetTypeAt(i, type_argument);
781 } 783 }
782 } 784 }
783 785
784 // The finalized type argument vector needs num_type_arguments types. 786 // The finalized type argument vector needs num_type_arguments types.
785 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 787 const intptr_t num_type_arguments = type_class.NumTypeArguments();
786 // The type class has num_type_parameters type parameters. 788 // The type class has num_type_parameters type parameters.
787 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 789 const intptr_t num_type_parameters = type_class.NumTypeParameters();
788 790
789 // Initialize the type argument vector. 791 // Initialize the type argument vector.
790 // Check the number of parsed type arguments, if any. 792 // Check the number of parsed type arguments, if any.
791 // Specifying no type arguments indicates a raw type, which is not an error. 793 // Specifying no type arguments indicates a raw type, which is not an error.
792 // However, type parameter bounds are checked below, even for a raw type. 794 // However, type parameter bounds are checked below, even for a raw type.
793 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 795 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
794 // Wrong number of type arguments. The type is malformed. 796 // Wrong number of type arguments. The type is malformed.
795 if (FLAG_error_on_malformed_type) { 797 if (FLAG_error_on_malformed_type) {
796 const Script& script = Script::Handle(cls.script()); 798 const Script& script = Script::Handle(cls.script());
797 const String& type_class_name = String::Handle(type_class.Name()); 799 const String& type_class_name = String::Handle(type_class.Name());
798 ReportError(script, parameterized_type.token_pos(), 800 ReportError(Error::Handle(), // No previous error.
801 script, parameterized_type.token_pos(),
799 "wrong number of type arguments for class '%s'", 802 "wrong number of type arguments for class '%s'",
800 type_class_name.ToCString()); 803 type_class_name.ToCString());
801 } 804 }
802 // Make the type raw and continue without reporting any error. 805 // Make the type raw and continue without reporting any error.
803 // A static warning should have been reported. 806 // A static warning should have been reported.
804 arguments = AbstractTypeArguments::null(); 807 arguments = AbstractTypeArguments::null();
805 parameterized_type.set_arguments(arguments); 808 parameterized_type.set_arguments(arguments);
806 } 809 }
807 // The full type argument vector consists of the type arguments of the 810 // The full type argument vector consists of the type arguments of the
808 // super types of type_class, which may be initialized from the parsed 811 // super types of type_class, which may be initialized from the parsed
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 // class or in a subclass. 1024 // class or in a subclass.
1022 // - a static field, instance field, or static method (but not an instance 1025 // - a static field, instance field, or static method (but not an instance
1023 // method) having the same name as an instance member in a super class. 1026 // method) having the same name as an instance member in a super class.
1024 1027
1025 // Resolve type of fields and check for conflicts in super classes. 1028 // Resolve type of fields and check for conflicts in super classes.
1026 Array& array = Array::Handle(cls.fields()); 1029 Array& array = Array::Handle(cls.fields());
1027 Field& field = Field::Handle(); 1030 Field& field = Field::Handle();
1028 AbstractType& type = AbstractType::Handle(); 1031 AbstractType& type = AbstractType::Handle();
1029 String& name = String::Handle(); 1032 String& name = String::Handle();
1030 Class& super_class = Class::Handle(); 1033 Class& super_class = Class::Handle();
1031 intptr_t num_fields = array.Length(); 1034 const intptr_t num_fields = array.Length();
1032 for (intptr_t i = 0; i < num_fields; i++) { 1035 for (intptr_t i = 0; i < num_fields; i++) {
1033 field ^= array.At(i); 1036 field ^= array.At(i);
1034 type = field.type(); 1037 type = field.type();
1035 ResolveType(cls, type, kCanonicalize); 1038 ResolveType(cls, type, kCanonicalize);
1036 type = FinalizeType(cls, type, kCanonicalize); 1039 type = FinalizeType(cls, type, kCanonicalize);
1037 field.set_type(type); 1040 field.set_type(type);
1038 name = field.name(); 1041 name = field.name();
1039 if (field.is_static()) { 1042 if (field.is_static()) {
1040 super_class = FindSuperOwnerOfInstanceMember(cls, name); 1043 super_class = FindSuperOwnerOfInstanceMember(cls, name);
1041 if (!super_class.IsNull()) { 1044 if (!super_class.IsNull()) {
1042 const String& class_name = String::Handle(cls.Name()); 1045 const String& class_name = String::Handle(cls.Name());
1043 const String& super_class_name = String::Handle(super_class.Name()); 1046 const String& super_class_name = String::Handle(super_class.Name());
1044 const Script& script = Script::Handle(cls.script()); 1047 const Script& script = Script::Handle(cls.script());
1045 ReportError(script, field.token_pos(), 1048 ReportError(Error::Handle(), // No previous error.
1049 script, field.token_pos(),
1046 "static field '%s' of class '%s' conflicts with " 1050 "static field '%s' of class '%s' conflicts with "
1047 "instance member '%s' of super class '%s'", 1051 "instance member '%s' of super class '%s'",
1048 name.ToCString(), 1052 name.ToCString(),
1049 class_name.ToCString(), 1053 class_name.ToCString(),
1050 name.ToCString(), 1054 name.ToCString(),
1051 super_class_name.ToCString()); 1055 super_class_name.ToCString());
1052 } 1056 }
1053 } else { 1057 } else {
1054 // Instance field. Check whether the field overrides a method 1058 // Instance field. Check whether the field overrides a method
1055 // (but not getter). 1059 // (but not getter).
1056 super_class = FindSuperOwnerOfFunction(cls, name); 1060 super_class = FindSuperOwnerOfFunction(cls, name);
1057 if (!super_class.IsNull()) { 1061 if (!super_class.IsNull()) {
1058 const String& class_name = String::Handle(cls.Name()); 1062 const String& class_name = String::Handle(cls.Name());
1059 const String& super_class_name = String::Handle(super_class.Name()); 1063 const String& super_class_name = String::Handle(super_class.Name());
1060 const Script& script = Script::Handle(cls.script()); 1064 const Script& script = Script::Handle(cls.script());
1061 ReportError(script, field.token_pos(), 1065 ReportError(Error::Handle(), // No previous error.
1066 script, field.token_pos(),
1062 "field '%s' of class '%s' conflicts with method '%s' " 1067 "field '%s' of class '%s' conflicts with method '%s' "
1063 "of super class '%s'", 1068 "of super class '%s'",
1064 name.ToCString(), 1069 name.ToCString(),
1065 class_name.ToCString(), 1070 class_name.ToCString(),
1066 name.ToCString(), 1071 name.ToCString(),
1067 super_class_name.ToCString()); 1072 super_class_name.ToCString());
1068 } 1073 }
1069 } 1074 }
1070 if ((FLAG_enable_type_checks || FLAG_error_on_malformed_type) && 1075 if ((FLAG_enable_type_checks || FLAG_error_on_malformed_type) &&
1071 field.is_static() && field.is_const() && 1076 field.is_static() && field.is_const() &&
1072 (field.value() != Object::null()) && 1077 (field.value() != Object::null()) &&
1073 (field.value() != Object::sentinel().raw())) { 1078 (field.value() != Object::sentinel().raw())) {
1074 // The parser does not preset the value if the type is a type parameter or 1079 // The parser does not preset the value if the type is a type parameter or
1075 // is parameterized unless the value is null. 1080 // is parameterized unless the value is null.
1076 Error& malformed_error = Error::Handle(); 1081 Error& malformed_error = Error::Handle();
1077 if (type.IsMalformed()) { 1082 if (type.IsMalformed()) {
1078 malformed_error = type.malformed_error(); 1083 malformed_error = type.malformed_error();
1079 } else { 1084 } else {
1080 ASSERT(type.IsInstantiated()); 1085 ASSERT(type.IsInstantiated());
1081 } 1086 }
1082 const Instance& const_value = Instance::Handle(field.value()); 1087 const Instance& const_value = Instance::Handle(field.value());
1083 if (!malformed_error.IsNull() || 1088 if (!malformed_error.IsNull() ||
1084 (!type.IsDynamicType() && 1089 (!type.IsDynamicType() &&
1085 !const_value.IsInstanceOf(type, 1090 !const_value.IsInstanceOf(type,
1086 AbstractTypeArguments::Handle(), 1091 AbstractTypeArguments::Handle(),
1087 &malformed_error))) { 1092 &malformed_error))) {
1088 // If the failure is due to a malformed type error, display it instead. 1093 const AbstractType& const_value_type = AbstractType::Handle(
1089 if (!malformed_error.IsNull()) { 1094 const_value.GetType());
1090 ReportError(malformed_error); 1095 const String& const_value_type_name = String::Handle(
1091 } else { 1096 const_value_type.UserVisibleName());
1092 const AbstractType& const_value_type = AbstractType::Handle( 1097 const String& type_name = String::Handle(type.UserVisibleName());
1093 const_value.GetType()); 1098 const Script& script = Script::Handle(cls.script());
1094 const String& const_value_type_name = String::Handle( 1099 ReportError(malformed_error, script, field.token_pos(),
1095 const_value_type.UserVisibleName()); 1100 "error initializing const field '%s': type '%s' is not a "
1096 const String& type_name = String::Handle(type.UserVisibleName()); 1101 "subtype of type '%s'",
1097 const Script& script = Script::Handle(cls.script()); 1102 name.ToCString(),
1098 ReportError(script, field.token_pos(), 1103 const_value_type_name.ToCString(),
1099 "error initializing const field '%s': type '%s' is not a " 1104 type_name.ToCString());
1100 "subtype of type '%s'",
1101 name.ToCString(),
1102 const_value_type_name.ToCString(),
1103 type_name.ToCString());
1104 }
1105 } 1105 }
1106 } 1106 }
1107 } 1107 }
1108 // Collect interfaces, super interfaces, and super classes of this class. 1108 // Collect interfaces, super interfaces, and super classes of this class.
1109 const GrowableObjectArray& interfaces = 1109 const GrowableObjectArray& interfaces =
1110 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1110 GrowableObjectArray::Handle(GrowableObjectArray::New());
1111 CollectInterfaces(cls, interfaces); 1111 CollectInterfaces(cls, interfaces);
1112 // Include superclasses in list of interfaces and super interfaces. 1112 // Include superclasses in list of interfaces and super interfaces.
1113 super_class = cls.SuperClass(); 1113 super_class = cls.SuperClass();
1114 while (!super_class.IsNull()) { 1114 while (!super_class.IsNull()) {
1115 interfaces.Add(super_class); 1115 interfaces.Add(super_class);
1116 CollectInterfaces(super_class, interfaces); 1116 CollectInterfaces(super_class, interfaces);
1117 super_class = super_class.SuperClass(); 1117 super_class = super_class.SuperClass();
1118 } 1118 }
1119 // Resolve function signatures and check for conflicts in super classes and 1119 // Resolve function signatures and check for conflicts in super classes and
1120 // interfaces. 1120 // interfaces.
1121 array = cls.functions(); 1121 array = cls.functions();
1122 Function& function = Function::Handle(); 1122 Function& function = Function::Handle();
1123 Function& overridden_function = Function::Handle(); 1123 Function& overridden_function = Function::Handle();
1124 intptr_t num_functions = array.Length(); 1124 const intptr_t num_functions = array.Length();
1125 String& function_name = String::Handle(); 1125 String& function_name = String::Handle();
1126 Error& error = Error::Handle();
1126 for (intptr_t i = 0; i < num_functions; i++) { 1127 for (intptr_t i = 0; i < num_functions; i++) {
1127 function ^= array.At(i); 1128 function ^= array.At(i);
1128 ResolveAndFinalizeSignature(cls, function); 1129 ResolveAndFinalizeSignature(cls, function);
1129 function_name = function.name(); 1130 function_name = function.name();
1130 if (function.is_static()) { 1131 if (function.is_static()) {
1131 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); 1132 super_class = FindSuperOwnerOfInstanceMember(cls, function_name);
1132 if (!super_class.IsNull()) { 1133 if (!super_class.IsNull()) {
1133 const String& class_name = String::Handle(cls.Name()); 1134 const String& class_name = String::Handle(cls.Name());
1134 const String& super_class_name = String::Handle(super_class.Name()); 1135 const String& super_class_name = String::Handle(super_class.Name());
1135 const Script& script = Script::Handle(cls.script()); 1136 const Script& script = Script::Handle(cls.script());
1136 ReportError(script, function.token_pos(), 1137 ReportError(Error::Handle(), // No previous error.
1138 script, function.token_pos(),
1137 "static function '%s' of class '%s' conflicts with " 1139 "static function '%s' of class '%s' conflicts with "
1138 "instance member '%s' of super class '%s'", 1140 "instance member '%s' of super class '%s'",
1139 function_name.ToCString(), 1141 function_name.ToCString(),
1140 class_name.ToCString(), 1142 class_name.ToCString(),
1141 function_name.ToCString(), 1143 function_name.ToCString(),
1142 super_class_name.ToCString()); 1144 super_class_name.ToCString());
1143 } 1145 }
1144 // The function may be a still unresolved redirecting factory. Do not yet 1146 // The function may be a still unresolved redirecting factory. Do not yet
1145 // try to resolve it in order to avoid cycles in class finalization. 1147 // try to resolve it in order to avoid cycles in class finalization.
1146 } else { 1148 } else if (FLAG_error_on_bad_override && !function.IsConstructor()) {
1149 // A constructor cannot override anything.
1147 for (int i = 0; i < interfaces.Length(); i++) { 1150 for (int i = 0; i < interfaces.Length(); i++) {
1148 super_class ^= interfaces.At(i); 1151 super_class ^= interfaces.At(i);
1149 overridden_function = super_class.LookupDynamicFunction(function_name); 1152 overridden_function = super_class.LookupDynamicFunction(function_name);
1150 if (!overridden_function.IsNull() && 1153 if (!overridden_function.IsNull() &&
1151 !function.HasCompatibleParametersWith(overridden_function)) { 1154 !function.HasCompatibleParametersWith(overridden_function,
1155 &error)) {
1152 // Function types are purposely not checked for subtyping. 1156 // Function types are purposely not checked for subtyping.
1153 const String& class_name = String::Handle(cls.Name()); 1157 const String& class_name = String::Handle(cls.Name());
1154 const String& super_class_name = String::Handle(super_class.Name()); 1158 const String& super_class_name = String::Handle(super_class.Name());
1155 const Script& script = Script::Handle(cls.script()); 1159 const Script& script = Script::Handle(cls.script());
1156 ReportError(script, function.token_pos(), 1160 ReportError(error, script, function.token_pos(),
1157 "class '%s' overrides function '%s' of super class '%s' " 1161 "class '%s' overrides function '%s' of super class '%s' "
1158 "with incompatible parameters", 1162 "with incompatible parameters",
1159 class_name.ToCString(), 1163 class_name.ToCString(),
1160 function_name.ToCString(), 1164 function_name.ToCString(),
1161 super_class_name.ToCString()); 1165 super_class_name.ToCString());
1162 } 1166 }
1163 } 1167 }
1164 } 1168 }
1165 if (function.IsGetterFunction()) { 1169 if (function.IsGetterFunction()) {
1166 name = Field::NameFromGetter(function_name); 1170 name = Field::NameFromGetter(function_name);
1167 super_class = FindSuperOwnerOfFunction(cls, name); 1171 super_class = FindSuperOwnerOfFunction(cls, name);
1168 if (!super_class.IsNull()) { 1172 if (!super_class.IsNull()) {
1169 const String& class_name = String::Handle(cls.Name()); 1173 const String& class_name = String::Handle(cls.Name());
1170 const String& super_class_name = String::Handle(super_class.Name()); 1174 const String& super_class_name = String::Handle(super_class.Name());
1171 const Script& script = Script::Handle(cls.script()); 1175 const Script& script = Script::Handle(cls.script());
1172 ReportError(script, function.token_pos(), 1176 ReportError(Error::Handle(), // No previous error.
1177 script, function.token_pos(),
1173 "getter '%s' of class '%s' conflicts with " 1178 "getter '%s' of class '%s' conflicts with "
1174 "function '%s' of super class '%s'", 1179 "function '%s' of super class '%s'",
1175 name.ToCString(), 1180 name.ToCString(),
1176 class_name.ToCString(), 1181 class_name.ToCString(),
1177 name.ToCString(), 1182 name.ToCString(),
1178 super_class_name.ToCString()); 1183 super_class_name.ToCString());
1179 } 1184 }
1180 } else if (!function.IsSetterFunction()) { 1185 } else if (!function.IsSetterFunction()) {
1181 // A function cannot conflict with a setter, since they cannot 1186 // A function cannot conflict with a setter, since they cannot
1182 // have the same name. Thus, we do not need to check setters. 1187 // have the same name. Thus, we do not need to check setters.
1183 name = Field::GetterName(function_name); 1188 name = Field::GetterName(function_name);
1184 super_class = FindSuperOwnerOfFunction(cls, name); 1189 super_class = FindSuperOwnerOfFunction(cls, name);
1185 if (!super_class.IsNull()) { 1190 if (!super_class.IsNull()) {
1186 const String& class_name = String::Handle(cls.Name()); 1191 const String& class_name = String::Handle(cls.Name());
1187 const String& super_class_name = String::Handle(super_class.Name()); 1192 const String& super_class_name = String::Handle(super_class.Name());
1188 const Script& script = Script::Handle(cls.script()); 1193 const Script& script = Script::Handle(cls.script());
1189 ReportError(script, function.token_pos(), 1194 ReportError(Error::Handle(), // No previous error.
1195 script, function.token_pos(),
1190 "function '%s' of class '%s' conflicts with " 1196 "function '%s' of class '%s' conflicts with "
1191 "getter '%s' of super class '%s'", 1197 "getter '%s' of super class '%s'",
1192 function_name.ToCString(), 1198 function_name.ToCString(),
1193 class_name.ToCString(), 1199 class_name.ToCString(),
1194 function_name.ToCString(), 1200 function_name.ToCString(),
1195 super_class_name.ToCString()); 1201 super_class_name.ToCString());
1196 } 1202 }
1197 } 1203 }
1198 } 1204 }
1199 } 1205 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 TypeArguments::Handle(super_class.type_parameters()); 1239 TypeArguments::Handle(super_class.type_parameters());
1234 const TypeArguments& super_type_args = 1240 const TypeArguments& super_type_args =
1235 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); 1241 TypeArguments::Handle(TypeArguments::New(num_super_parameters));
1236 for (int i = 0; i < num_super_parameters; i++) { 1242 for (int i = 0; i < num_super_parameters; i++) {
1237 param ^= super_params.TypeAt(i); 1243 param ^= super_params.TypeAt(i);
1238 param_name = param.name(); 1244 param_name = param.name();
1239 param_bound = param.bound(); 1245 param_bound = param.bound();
1240 // TODO(hausner): handle type bounds. 1246 // TODO(hausner): handle type bounds.
1241 if (!param_bound.IsObjectType()) { 1247 if (!param_bound.IsObjectType()) {
1242 const Script& script = Script::Handle(mixapp_class.script()); 1248 const Script& script = Script::Handle(mixapp_class.script());
1243 ReportError(script, param.token_pos(), 1249 ReportError(Error::Handle(), // No previous error.
1250 script, param.token_pos(),
1244 "type parameter '%s': type bounds not yet" 1251 "type parameter '%s': type bounds not yet"
1245 " implemented for mixins\n", 1252 " implemented for mixins\n",
1246 param_name.ToCString()); 1253 param_name.ToCString());
1247 } 1254 }
1248 param_name = String::Concat(param_name, Symbols::Backtick()); 1255 param_name = String::Concat(param_name, Symbols::Backtick());
1249 param_name = Symbols::New(param_name); 1256 param_name = Symbols::New(param_name);
1250 cloned_param = TypeParameter::New(mixapp_class, 1257 cloned_param = TypeParameter::New(mixapp_class,
1251 cloned_index, 1258 cloned_index,
1252 param_name, 1259 param_name,
1253 param_bound, 1260 param_bound,
(...skipping 21 matching lines...) Expand all
1275 const TypeArguments& interface_type_args = TypeArguments::Handle( 1282 const TypeArguments& interface_type_args = TypeArguments::Handle(
1276 TypeArguments::New(num_mixin_parameters)); 1283 TypeArguments::New(num_mixin_parameters));
1277 for (int i = 0; i < num_mixin_parameters; i++) { 1284 for (int i = 0; i < num_mixin_parameters; i++) {
1278 param ^= mixin_params.TypeAt(i); 1285 param ^= mixin_params.TypeAt(i);
1279 param_name = param.name(); 1286 param_name = param.name();
1280 param_bound = param.bound(); 1287 param_bound = param.bound();
1281 1288
1282 // TODO(hausner): handle type bounds. 1289 // TODO(hausner): handle type bounds.
1283 if (!param_bound.IsObjectType()) { 1290 if (!param_bound.IsObjectType()) {
1284 const Script& script = Script::Handle(mixapp_class.script()); 1291 const Script& script = Script::Handle(mixapp_class.script());
1285 ReportError(script, param.token_pos(), 1292 ReportError(Error::Handle(), // No previous error.
1293 script, param.token_pos(),
1286 "type parameter '%s': type bounds not yet" 1294 "type parameter '%s': type bounds not yet"
1287 " implemented for mixins\n", 1295 " implemented for mixins\n",
1288 param_name.ToCString()); 1296 param_name.ToCString());
1289 } 1297 }
1290 cloned_param = TypeParameter::New(mixapp_class, 1298 cloned_param = TypeParameter::New(mixapp_class,
1291 cloned_index, 1299 cloned_index,
1292 param_name, 1300 param_name,
1293 param_bound, 1301 param_bound,
1294 param.token_pos()); 1302 param.token_pos());
1295 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1303 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
(...skipping 30 matching lines...) Expand all
1326 cls.token_pos()); 1334 cls.token_pos());
1327 } 1335 }
1328 1336
1329 // Check that the super class of the mixin class is extending 1337 // Check that the super class of the mixin class is extending
1330 // class Object. 1338 // class Object.
1331 const AbstractType& mixin_super_type = 1339 const AbstractType& mixin_super_type =
1332 AbstractType::Handle(mixin_cls.super_type()); 1340 AbstractType::Handle(mixin_cls.super_type());
1333 if (!mixin_super_type.IsObjectType()) { 1341 if (!mixin_super_type.IsObjectType()) {
1334 const Script& script = Script::Handle(cls.script()); 1342 const Script& script = Script::Handle(cls.script());
1335 const String& class_name = String::Handle(mixin_cls.Name()); 1343 const String& class_name = String::Handle(mixin_cls.Name());
1336 ReportError(script, cls.token_pos(), 1344 ReportError(Error::Handle(), // No previous error.
1345 script, cls.token_pos(),
1337 "mixin class %s must extend class Object", 1346 "mixin class %s must extend class Object",
1338 class_name.ToCString()); 1347 class_name.ToCString());
1339 } 1348 }
1340 1349
1341 // Copy type parameters to mixin application class. 1350 // Copy type parameters to mixin application class.
1342 CloneTypeParameters(cls); 1351 CloneTypeParameters(cls);
1343 1352
1344 if (FLAG_trace_class_finalization) { 1353 if (FLAG_trace_class_finalization) {
1345 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", 1354 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n",
1346 String::Handle(mixin_type.Name()).ToCString(), 1355 String::Handle(mixin_type.Name()).ToCString(),
1347 String::Handle(cls.Name()).ToCString(), 1356 String::Handle(cls.Name()).ToCString(),
1348 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1357 TypeArguments::Handle(cls.type_parameters()).ToCString(),
1349 AbstractType::Handle(cls.super_type()).ToCString()); 1358 AbstractType::Handle(cls.super_type()).ToCString());
1350 } 1359 }
1351 } 1360 }
1352 1361
1353 1362
1354 void ClassFinalizer::CreateForwardingConstructors( 1363 void ClassFinalizer::CreateForwardingConstructors(
1355 const Class& mixin_app, 1364 const Class& mixin_app,
1356 const GrowableObjectArray& cloned_funcs) { 1365 const GrowableObjectArray& cloned_funcs) {
1357 const String& mixin_name = String::Handle(mixin_app.Name()); 1366 const String& mixin_name = String::Handle(mixin_app.Name());
1358 const Class& super_class = Class::Handle(mixin_app.SuperClass()); 1367 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1359 const String& super_name = String::Handle(super_class.Name()); 1368 const String& super_name = String::Handle(super_class.Name());
1360 const Type& dynamic_type = Type::Handle(Type::DynamicType()); 1369 const Type& dynamic_type = Type::Handle(Type::DynamicType());
1361 const Array& functions = Array::Handle(super_class.functions()); 1370 const Array& functions = Array::Handle(super_class.functions());
1362 intptr_t num_functions = functions.Length(); 1371 const intptr_t num_functions = functions.Length();
1363 Function& func = Function::Handle(); 1372 Function& func = Function::Handle();
1364 for (intptr_t i = 0; i < num_functions; i++) { 1373 for (intptr_t i = 0; i < num_functions; i++) {
1365 func ^= functions.At(i); 1374 func ^= functions.At(i);
1366 if (func.IsConstructor()) { 1375 if (func.IsConstructor()) {
1367 // Build constructor name from mixin application class name 1376 // Build constructor name from mixin application class name
1368 // and name of cloned super class constructor. 1377 // and name of cloned super class constructor.
1369 String& ctor_name = String::Handle(func.name()); 1378 String& ctor_name = String::Handle(func.name());
1370 ctor_name = String::SubString(ctor_name, super_name.Length()); 1379 ctor_name = String::SubString(ctor_name, super_name.Length());
1371 String& clone_name = 1380 String& clone_name =
1372 String::Handle(String::Concat(mixin_name, ctor_name)); 1381 String::Handle(String::Concat(mixin_name, ctor_name));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 ASSERT((functions = cls.functions(), functions.Length() == 0)); 1439 ASSERT((functions = cls.functions(), functions.Length() == 0));
1431 // Now clone the functions from the mixin class. 1440 // Now clone the functions from the mixin class.
1432 functions = mixin_cls.functions(); 1441 functions = mixin_cls.functions();
1433 const intptr_t num_functions = functions.Length(); 1442 const intptr_t num_functions = functions.Length();
1434 for (int i = 0; i < num_functions; i++) { 1443 for (int i = 0; i < num_functions; i++) {
1435 func ^= functions.At(i); 1444 func ^= functions.At(i);
1436 if (func.IsConstructor()) { 1445 if (func.IsConstructor()) {
1437 // A mixin class must not have explicit constructors. 1446 // A mixin class must not have explicit constructors.
1438 if (!func.IsImplicitConstructor()) { 1447 if (!func.IsImplicitConstructor()) {
1439 const Script& script = Script::Handle(isolate, cls.script()); 1448 const Script& script = Script::Handle(isolate, cls.script());
1440 ReportError(script, cls.token_pos(), 1449 ReportError(Error::Handle(), // No previous error.
1450 script, cls.token_pos(),
1441 "mixin class %s must not have constructors\n", 1451 "mixin class %s must not have constructors\n",
1442 String::Handle(isolate, mixin_cls.Name()).ToCString()); 1452 String::Handle(isolate, mixin_cls.Name()).ToCString());
1443 } 1453 }
1444 continue; // Skip the implicit constructor. 1454 continue; // Skip the implicit constructor.
1445 } 1455 }
1446 if (!func.is_static()) { 1456 if (!func.is_static()) {
1447 func = func.Clone(cls); 1457 func = func.Clone(cls);
1448 cloned_funcs.Add(func); 1458 cloned_funcs.Add(func);
1449 } 1459 }
1450 } 1460 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 HANDLESCOPE(Isolate::Current()); 1492 HANDLESCOPE(Isolate::Current());
1483 if (cls.is_type_finalized()) { 1493 if (cls.is_type_finalized()) {
1484 return; 1494 return;
1485 } 1495 }
1486 if (FLAG_trace_class_finalization) { 1496 if (FLAG_trace_class_finalization) {
1487 OS::Print("Finalize types in %s\n", cls.ToCString()); 1497 OS::Print("Finalize types in %s\n", cls.ToCString());
1488 } 1498 }
1489 if (!IsSuperCycleFree(cls)) { 1499 if (!IsSuperCycleFree(cls)) {
1490 const String& name = String::Handle(cls.Name()); 1500 const String& name = String::Handle(cls.Name());
1491 const Script& script = Script::Handle(cls.script()); 1501 const Script& script = Script::Handle(cls.script());
1492 ReportError(script, cls.token_pos(), 1502 ReportError(Error::Handle(), // No previous error.
1503 script, cls.token_pos(),
1493 "class '%s' has a cycle in its superclass relationship", 1504 "class '%s' has a cycle in its superclass relationship",
1494 name.ToCString()); 1505 name.ToCString());
1495 } 1506 }
1496 // Finalize super class. 1507 // Finalize super class.
1497 const Class& super_class = Class::Handle(cls.SuperClass()); 1508 const Class& super_class = Class::Handle(cls.SuperClass());
1498 if (!super_class.IsNull()) { 1509 if (!super_class.IsNull()) {
1499 FinalizeTypesInClass(super_class); 1510 FinalizeTypesInClass(super_class);
1500 } 1511 }
1501 if (cls.mixin() != Type::null()) { 1512 if (cls.mixin() != Type::null()) {
1502 // Copy the type parameters to the mixin application. 1513 // Copy the type parameters to the mixin application.
(...skipping 13 matching lines...) Expand all
1516 // out of bound type argument. 1527 // out of bound type argument.
1517 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); 1528 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1518 cls.set_super_type(super_type); 1529 cls.set_super_type(super_type);
1519 } 1530 }
1520 if (cls.IsSignatureClass()) { 1531 if (cls.IsSignatureClass()) {
1521 // Check for illegal self references. 1532 // Check for illegal self references.
1522 GrowableArray<intptr_t> visited_aliases; 1533 GrowableArray<intptr_t> visited_aliases;
1523 if (!IsAliasCycleFree(cls, &visited_aliases)) { 1534 if (!IsAliasCycleFree(cls, &visited_aliases)) {
1524 const String& name = String::Handle(cls.Name()); 1535 const String& name = String::Handle(cls.Name());
1525 const Script& script = Script::Handle(cls.script()); 1536 const Script& script = Script::Handle(cls.script());
1526 ReportError(script, cls.token_pos(), 1537 ReportError(Error::Handle(), // No previous error.
1538 script, cls.token_pos(),
1527 "typedef '%s' illegally refers to itself", 1539 "typedef '%s' illegally refers to itself",
1528 name.ToCString()); 1540 name.ToCString());
1529 } 1541 }
1530 cls.set_is_type_finalized(); 1542 cls.set_is_type_finalized();
1531 // Signature classes extend Object. No need to add this class to the direct 1543 // Signature classes extend Object. No need to add this class to the direct
1532 // subclasses of Object. 1544 // subclasses of Object.
1533 ASSERT(super_type.IsNull() || super_type.IsObjectType()); 1545 ASSERT(super_type.IsNull() || super_type.IsObjectType());
1534 1546
1535 // The type parameters of signature classes may have bounds. 1547 // The type parameters of signature classes may have bounds.
1536 FinalizeUpperBounds(cls); 1548 FinalizeUpperBounds(cls);
(...skipping 17 matching lines...) Expand all
1554 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1566 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1555 interface_types.SetAt(i, interface_type); 1567 interface_types.SetAt(i, interface_type);
1556 1568
1557 // Check whether the interface is duplicated. We need to wait with 1569 // Check whether the interface is duplicated. We need to wait with
1558 // this check until the super type and interface types are finalized, 1570 // this check until the super type and interface types are finalized,
1559 // so that we can use Type::Equals() for the test. 1571 // so that we can use Type::Equals() for the test.
1560 ASSERT(interface_type.IsFinalized()); 1572 ASSERT(interface_type.IsFinalized());
1561 ASSERT(super_type.IsNull() || super_type.IsFinalized()); 1573 ASSERT(super_type.IsNull() || super_type.IsFinalized());
1562 if (!super_type.IsNull() && interface_type.Equals(super_type)) { 1574 if (!super_type.IsNull() && interface_type.Equals(super_type)) {
1563 const Script& script = Script::Handle(cls.script()); 1575 const Script& script = Script::Handle(cls.script());
1564 ReportError(script, cls.token_pos(), 1576 ReportError(Error::Handle(), // No previous error.
1577 script, cls.token_pos(),
1565 "super type '%s' may not be listed in " 1578 "super type '%s' may not be listed in "
1566 "implements clause of class '%s'", 1579 "implements clause of class '%s'",
1567 String::Handle(super_type.Name()).ToCString(), 1580 String::Handle(super_type.Name()).ToCString(),
1568 String::Handle(cls.Name()).ToCString()); 1581 String::Handle(cls.Name()).ToCString());
1569 } 1582 }
1570 for (intptr_t j = 0; j < i; j++) { 1583 for (intptr_t j = 0; j < i; j++) {
1571 seen_interf ^= interface_types.At(j); 1584 seen_interf ^= interface_types.At(j);
1572 if (interface_type.Equals(seen_interf)) { 1585 if (interface_type.Equals(seen_interf)) {
1573 const Script& script = Script::Handle(cls.script()); 1586 const Script& script = Script::Handle(cls.script());
1574 ReportError(script, cls.token_pos(), 1587 ReportError(Error::Handle(), // No previous error.
1588 script, cls.token_pos(),
1575 "interface '%s' appears twice in " 1589 "interface '%s' appears twice in "
1576 "implements clause of class '%s'", 1590 "implements clause of class '%s'",
1577 String::Handle(interface_type.Name()).ToCString(), 1591 String::Handle(interface_type.Name()).ToCString(),
1578 String::Handle(cls.Name()).ToCString()); 1592 String::Handle(cls.Name()).ToCString());
1579 } 1593 }
1580 } 1594 }
1581 } 1595 }
1582 // Mark as type finalized before resolving type parameter upper bounds 1596 // Mark as type finalized before resolving type parameter upper bounds
1583 // in order to break cycles. 1597 // in order to break cycles.
1584 cls.set_is_type_finalized(); 1598 cls.set_is_type_finalized();
1585 // Finalize bounds even if running in production mode, so that a snapshot 1599 // Finalize bounds even if running in production mode, so that a snapshot
1586 // contains them. 1600 // contains them.
1587 FinalizeUpperBounds(cls); 1601 FinalizeUpperBounds(cls);
1588 // Add this class to the direct subclasses of the superclass, unless the 1602 // Add this class to the direct subclasses of the superclass, unless the
1589 // superclass is Object. 1603 // superclass is Object.
1590 if (!super_type.IsNull() && !super_type.IsObjectType()) { 1604 if (!super_type.IsNull() && !super_type.IsObjectType()) {
1591 ASSERT(!super_class.IsNull()); 1605 ASSERT(!super_class.IsNull());
1592 super_class.AddDirectSubclass(cls); 1606 super_class.AddDirectSubclass(cls);
1593 } 1607 }
1594 // Top level classes are parsed eagerly so just finalize it. 1608 // A top level class is parsed eagerly so just finalize it.
1595 if (cls.IsTopLevel()) { 1609 if (cls.IsTopLevel()) {
1596 FinalizeClass(cls); 1610 FinalizeClass(cls);
1611 } else {
1612 // This class should not contain any fields or functions yet, because it has
1613 // not been compiled yet. Since 'ResolveAndFinalizeMemberTypes(cls)' has not
1614 // been called yet, unfinalized member types could choke the snapshotter.
1615 ASSERT(Array::Handle(cls.fields()).Length() == 0);
1616 ASSERT(Array::Handle(cls.functions()).Length() == 0);
1597 } 1617 }
1598 } 1618 }
1599 1619
1600 1620
1601 void ClassFinalizer::FinalizeClass(const Class& cls) { 1621 void ClassFinalizer::FinalizeClass(const Class& cls) {
1602 HANDLESCOPE(Isolate::Current()); 1622 HANDLESCOPE(Isolate::Current());
1603 if (cls.is_finalized()) { 1623 if (cls.is_finalized()) {
1604 return; 1624 return;
1605 } 1625 }
1606 if (FLAG_trace_class_finalization) { 1626 if (FLAG_trace_class_finalization) {
1607 OS::Print("Finalize %s\n", cls.ToCString()); 1627 OS::Print("Finalize %s\n", cls.ToCString());
1608 } 1628 }
1609 if (cls.mixin() != Type::null()) { 1629 if (cls.mixin() != Type::null()) {
1610 // Copy instance methods and fields from the mixin class. 1630 // Copy instance methods and fields from the mixin class.
1611 // This has to happen before the check whether the methods of 1631 // This has to happen before the check whether the methods of
1612 // the class conflict with inherited methods. 1632 // the class conflict with inherited methods.
1613 ApplyMixin(cls); 1633 ApplyMixin(cls);
1614 } 1634 }
1615 // Ensure super class is finalized. 1635 // Ensure super class is finalized.
1616 const Class& super = Class::Handle(cls.SuperClass()); 1636 const Class& super = Class::Handle(cls.SuperClass());
1617 if (!super.IsNull()) { 1637 if (!super.IsNull()) {
1618 FinalizeClass(super); 1638 FinalizeClass(super);
1619 } 1639 }
1620 // Mark as parsed and finalized. 1640 // Mark as parsed and finalized.
1621 cls.Finalize(); 1641 cls.Finalize();
1642 // Mixin typedef classes may still lack their implicit constructor.
1643 // TODO(regis): Implement mixin typedefs with an alias class.
1644 if (cls.is_synthesized_class() &&
1645 (Array::Handle(cls.functions()).Length() == 0)) {
siva 2013/08/12 02:56:43 could be written as: if (cls.is_synthesized_class
regis 2013/08/12 17:45:27 Done.
1646 Parser::AddImplicitConstructor(cls);
1647 }
1648 // Every class should have at least a constructor, unless it is a top level
1649 // class or a signature class.
1650 ASSERT(cls.IsTopLevel() ||
1651 cls.IsSignatureClass() ||
1652 (Array::Handle(cls.functions()).Length() > 0));
1622 // Resolve and finalize all member types. 1653 // Resolve and finalize all member types.
1623 ResolveAndFinalizeMemberTypes(cls); 1654 ResolveAndFinalizeMemberTypes(cls);
1624 // Run additional checks after all types are finalized. 1655 // Run additional checks after all types are finalized.
1625 if (cls.is_const()) { 1656 if (cls.is_const()) {
1626 CheckForLegalConstClass(cls); 1657 CheckForLegalConstClass(cls);
1627 } 1658 }
1628 } 1659 }
1629 1660
1630 1661
1631 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 1662 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 type = function.ParameterTypeAt(i); 1739 type = function.ParameterTypeAt(i);
1709 if (!IsParameterTypeCycleFree(cls, type, visited)) { 1740 if (!IsParameterTypeCycleFree(cls, type, visited)) {
1710 return false; 1741 return false;
1711 } 1742 }
1712 } 1743 }
1713 visited->RemoveLast(); 1744 visited->RemoveLast();
1714 return true; 1745 return true;
1715 } 1746 }
1716 1747
1717 1748
1718 void ClassFinalizer::CollectTypeArguments(const Class& cls, 1749 void ClassFinalizer::CollectTypeArguments(
1719 const Type& type, 1750 const Class& cls,
1720 const GrowableObjectArray& collected_args) { 1751 const Type& type,
1752 const GrowableObjectArray& collected_args) {
1721 ASSERT(type.HasResolvedTypeClass()); 1753 ASSERT(type.HasResolvedTypeClass());
1722 Class& type_class = Class::Handle(type.type_class()); 1754 Class& type_class = Class::Handle(type.type_class());
1723 AbstractTypeArguments& type_args = 1755 AbstractTypeArguments& type_args =
1724 AbstractTypeArguments::Handle(type.arguments()); 1756 AbstractTypeArguments::Handle(type.arguments());
1725 intptr_t num_type_parameters = type_class.NumTypeParameters(); 1757 const intptr_t num_type_parameters = type_class.NumTypeParameters();
1726 intptr_t num_type_arguments = type_args.IsNull() ? 0 : type_args.Length(); 1758 const intptr_t num_type_arguments =
1759 type_args.IsNull() ? 0 : type_args.Length();
1727 AbstractType& arg = AbstractType::Handle(); 1760 AbstractType& arg = AbstractType::Handle();
1728 if (num_type_arguments > 0) { 1761 if (num_type_arguments > 0) {
1729 if (num_type_arguments != num_type_parameters) { 1762 if (num_type_arguments != num_type_parameters) {
1730 const Script& script = Script::Handle(cls.script()); 1763 const Script& script = Script::Handle(cls.script());
1731 const String& type_class_name = String::Handle(type_class.Name()); 1764 const String& type_class_name = String::Handle(type_class.Name());
1732 ReportError(script, type.token_pos(), 1765 ReportError(Error::Handle(), // No previous error.
1733 "wrong number of type arguments for class '%s'", 1766 script, type.token_pos(),
1734 type_class_name.ToCString()); 1767 "wrong number of type arguments for class '%s'",
1768 type_class_name.ToCString());
1735 } 1769 }
1736 for (int i = 0; i < num_type_arguments; i++) { 1770 for (int i = 0; i < num_type_arguments; i++) {
1737 arg = type_args.TypeAt(i); 1771 arg = type_args.TypeAt(i);
1738 collected_args.Add(arg); 1772 collected_args.Add(arg);
1739 } 1773 }
1740 } else { 1774 } else {
1741 // Fill arguments with type dynamic. 1775 // Fill arguments with type dynamic.
1742 for (int i = 0; i < num_type_parameters; i++) { 1776 for (int i = 0; i < num_type_parameters; i++) {
1743 arg = Type::DynamicType(); 1777 arg = Type::DynamicType();
1744 collected_args.Add(arg); 1778 collected_args.Add(arg);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 // Recursively walks the graph of explicitly declared super type and 1831 // Recursively walks the graph of explicitly declared super type and
1798 // interfaces, resolving unresolved super types and interfaces. 1832 // interfaces, resolving unresolved super types and interfaces.
1799 // Reports an error if there is an interface reference that cannot be 1833 // Reports an error if there is an interface reference that cannot be
1800 // resolved, or if there is a cycle in the graph. We detect cycles by 1834 // resolved, or if there is a cycle in the graph. We detect cycles by
1801 // remembering interfaces we've visited in each path through the 1835 // remembering interfaces we've visited in each path through the
1802 // graph. If we visit an interface a second time on a given path, 1836 // graph. If we visit an interface a second time on a given path,
1803 // we found a loop. 1837 // we found a loop.
1804 void ClassFinalizer::ResolveSuperTypeAndInterfaces( 1838 void ClassFinalizer::ResolveSuperTypeAndInterfaces(
1805 const Class& cls, GrowableArray<intptr_t>* visited) { 1839 const Class& cls, GrowableArray<intptr_t>* visited) {
1806 ASSERT(visited != NULL); 1840 ASSERT(visited != NULL);
1841 if (FLAG_trace_class_finalization) {
1842 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
1843 }
1807 const intptr_t cls_index = cls.id(); 1844 const intptr_t cls_index = cls.id();
1808 for (int i = 0; i < visited->length(); i++) { 1845 for (int i = 0; i < visited->length(); i++) {
1809 if ((*visited)[i] == cls_index) { 1846 if ((*visited)[i] == cls_index) {
1810 // We have already visited class 'cls'. We found a cycle. 1847 // We have already visited class 'cls'. We found a cycle.
1811 const String& class_name = String::Handle(cls.Name()); 1848 const String& class_name = String::Handle(cls.Name());
1812 const Script& script = Script::Handle(cls.script()); 1849 const Script& script = Script::Handle(cls.script());
1813 ReportError(script, cls.token_pos(), 1850 ReportError(Error::Handle(), // No previous error.
1851 script, cls.token_pos(),
1814 "cyclic reference found for class '%s'", 1852 "cyclic reference found for class '%s'",
1815 class_name.ToCString()); 1853 class_name.ToCString());
1816 } 1854 }
1817 } 1855 }
1818 1856
1819 // If the class/interface has no explicit super class/interfaces 1857 // If the class/interface has no explicit super class/interfaces
1820 // and is not a mixin application, we are done. 1858 // and is not a mixin application, we are done.
1821 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 1859 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1822 Array& super_interfaces = Array::Handle(cls.interfaces()); 1860 Array& super_interfaces = Array::Handle(cls.interfaces());
1823 if ((super_type.IsNull() || super_type.IsObjectType()) && 1861 if ((super_type.IsNull() || super_type.IsObjectType()) &&
(...skipping 16 matching lines...) Expand all
1840 AbstractType& interface = AbstractType::Handle(); 1878 AbstractType& interface = AbstractType::Handle();
1841 Class& interface_class = Class::Handle(); 1879 Class& interface_class = Class::Handle();
1842 1880
1843 // Resolve super type. Failures lead to a longjmp. 1881 // Resolve super type. Failures lead to a longjmp.
1844 ResolveType(cls, super_type, kCanonicalizeWellFormed); 1882 ResolveType(cls, super_type, kCanonicalizeWellFormed);
1845 if (super_type.IsMalformed()) { 1883 if (super_type.IsMalformed()) {
1846 ReportError(Error::Handle(super_type.malformed_error())); 1884 ReportError(Error::Handle(super_type.malformed_error()));
1847 } 1885 }
1848 if (super_type.IsDynamicType()) { 1886 if (super_type.IsDynamicType()) {
1849 const Script& script = Script::Handle(cls.script()); 1887 const Script& script = Script::Handle(cls.script());
1850 ReportError(script, cls.token_pos(), 1888 ReportError(Error::Handle(), // No previous error.
1889 script, cls.token_pos(),
1851 "class '%s' may not extend 'dynamic'", 1890 "class '%s' may not extend 'dynamic'",
1852 String::Handle(cls.Name()).ToCString()); 1891 String::Handle(cls.Name()).ToCString());
1853 } 1892 }
1893 if (Class::Handle(super_type.type_class()).IsSignatureClass()) {
siva 2013/08/12 02:56:43 Why not move the assignment interface_class = sup
regis 2013/08/12 17:45:27 Done.
1894 const Script& script = Script::Handle(cls.script());
1895 ReportError(Error::Handle(), // No previous error.
1896 script, cls.token_pos(),
1897 "class '%s' may not extend function type alias '%s'",
1898 String::Handle(cls.Name()).ToCString(),
1899 String::Handle(super_type.UserVisibleName()).ToCString());
1900 }
1854 1901
1855 interface_class = super_type.type_class(); 1902 interface_class = super_type.type_class();
1856 // If cls belongs to core lib or to core lib's implementation, restrictions 1903 // If cls belongs to core lib or to core lib's implementation, restrictions
1857 // about allowed interfaces are lifted. 1904 // about allowed interfaces are lifted.
1858 if (!cls_belongs_to_core_lib) { 1905 if (!cls_belongs_to_core_lib) {
1859 // Prevent extending core implementation classes. 1906 // Prevent extending core implementation classes.
1860 bool is_error = false; 1907 bool is_error = false;
1861 switch (interface_class.id()) { 1908 switch (interface_class.id()) {
1862 case kNumberCid: 1909 case kNumberCid:
1863 case kIntegerCid: // Class Integer, not int. 1910 case kIntegerCid: // Class Integer, not int.
(...skipping 25 matching lines...) Expand all
1889 if (super_type.IsDoubleType() || 1936 if (super_type.IsDoubleType() ||
1890 super_type.IsIntType() || 1937 super_type.IsIntType() ||
1891 super_type.IsStringType()) { 1938 super_type.IsStringType()) {
1892 is_error = true; 1939 is_error = true;
1893 } 1940 }
1894 break; 1941 break;
1895 } 1942 }
1896 } 1943 }
1897 if (is_error) { 1944 if (is_error) {
1898 const Script& script = Script::Handle(cls.script()); 1945 const Script& script = Script::Handle(cls.script());
1899 ReportError(script, cls.token_pos(), 1946 ReportError(Error::Handle(), // No previous error.
1947 script, cls.token_pos(),
1900 "'%s' is not allowed to extend '%s'", 1948 "'%s' is not allowed to extend '%s'",
1901 String::Handle(cls.Name()).ToCString(), 1949 String::Handle(cls.Name()).ToCString(),
1902 String::Handle(interface_class.Name()).ToCString()); 1950 String::Handle(interface_class.Name()).ToCString());
1903 } 1951 }
1904 } 1952 }
1905 // Now resolve the super interfaces of the super type. 1953 // Now resolve the super interfaces of the super type.
1906 ResolveSuperTypeAndInterfaces(interface_class, visited); 1954 ResolveSuperTypeAndInterfaces(interface_class, visited);
1907 1955
1908 // Resolve interfaces. Failures lead to a longjmp. 1956 // Resolve interfaces. Failures lead to a longjmp.
1909 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 1957 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
1910 interface ^= super_interfaces.At(i); 1958 interface ^= super_interfaces.At(i);
1911 ResolveType(cls, interface, kCanonicalizeWellFormed); 1959 ResolveType(cls, interface, kCanonicalizeWellFormed);
1912 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. 1960 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser.
1913 if (interface.IsMalformed()) { 1961 if (interface.IsMalformed()) {
1914 ReportError(Error::Handle(interface.malformed_error())); 1962 ReportError(Error::Handle(interface.malformed_error()));
1915 } 1963 }
1916 if (interface.IsDynamicType()) { 1964 if (interface.IsDynamicType()) {
1917 const Script& script = Script::Handle(cls.script()); 1965 const Script& script = Script::Handle(cls.script());
1918 ReportError(script, cls.token_pos(), 1966 ReportError(Error::Handle(), // No previous error.
1967 script, cls.token_pos(),
1919 "'dynamic' may not be used as interface"); 1968 "'dynamic' may not be used as interface");
1920 } 1969 }
1921 interface_class = interface.type_class(); 1970 interface_class = interface.type_class();
1922 if (interface_class.IsSignatureClass()) { 1971 if (interface_class.IsSignatureClass()) {
1923 const Script& script = Script::Handle(cls.script()); 1972 const Script& script = Script::Handle(cls.script());
1924 ReportError(script, cls.token_pos(), 1973 ReportError(Error::Handle(), // No previous error.
1925 "'%s' is used where an interface or class name is expected", 1974 script, cls.token_pos(),
1975 "function type alias '%s' may not be used as interface",
1926 String::Handle(interface_class.Name()).ToCString()); 1976 String::Handle(interface_class.Name()).ToCString());
1927 } 1977 }
1928 // Verify that unless cls belongs to core lib, it cannot extend or implement 1978 // Verify that unless cls belongs to core lib, it cannot extend or implement
1929 // any of bool, num, int, double, String, Function, dynamic. 1979 // any of bool, num, int, double, String, Function, dynamic.
1930 // The exception is signature classes, which are compiler generated and 1980 // The exception is signature classes, which are compiler generated and
1931 // represent a function type, therefore implementing the Function interface. 1981 // represent a function type, therefore implementing the Function interface.
1932 if (!cls_belongs_to_core_lib) { 1982 if (!cls_belongs_to_core_lib) {
1933 if (interface.IsBoolType() || 1983 if (interface.IsBoolType() ||
1934 interface.IsNumberType() || 1984 interface.IsNumberType() ||
1935 interface.IsIntType() || 1985 interface.IsIntType() ||
1936 interface.IsDoubleType() || 1986 interface.IsDoubleType() ||
1937 interface.IsStringType() || 1987 interface.IsStringType() ||
1938 (interface.IsFunctionType() && !cls.IsSignatureClass()) || 1988 (interface.IsFunctionType() && !cls.IsSignatureClass()) ||
1939 interface.IsDynamicType()) { 1989 interface.IsDynamicType()) {
1940 const Script& script = Script::Handle(cls.script()); 1990 const Script& script = Script::Handle(cls.script());
1941 ReportError(script, cls.token_pos(), 1991 ReportError(Error::Handle(), // No previous error.
1992 script, cls.token_pos(),
1942 "'%s' is not allowed to extend or implement '%s'", 1993 "'%s' is not allowed to extend or implement '%s'",
1943 String::Handle(cls.Name()).ToCString(), 1994 String::Handle(cls.Name()).ToCString(),
1944 String::Handle(interface_class.Name()).ToCString()); 1995 String::Handle(interface_class.Name()).ToCString());
1945 } 1996 }
1946 } 1997 }
1947 interface_class.set_is_implemented(); 1998 interface_class.set_is_implemented();
1948 // Now resolve the super interfaces. 1999 // Now resolve the super interfaces.
1949 ResolveSuperTypeAndInterfaces(interface_class, visited); 2000 ResolveSuperTypeAndInterfaces(interface_class, visited);
1950 } 2001 }
1951 visited->RemoveLast(); 2002 visited->RemoveLast();
1952 } 2003 }
1953 2004
1954 2005
1955 // A class is marked as constant if it has one constant constructor. 2006 // A class is marked as constant if it has one constant constructor.
1956 // A constant class can only have final instance fields. 2007 // A constant class can only have final instance fields.
1957 // Note: we must check for cycles before checking for const properties. 2008 // Note: we must check for cycles before checking for const properties.
1958 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { 2009 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) {
1959 ASSERT(cls.is_const()); 2010 ASSERT(cls.is_const());
1960 const Array& fields_array = Array::Handle(cls.fields()); 2011 const Array& fields_array = Array::Handle(cls.fields());
1961 intptr_t len = fields_array.Length(); 2012 intptr_t len = fields_array.Length();
1962 Field& field = Field::Handle(); 2013 Field& field = Field::Handle();
1963 for (intptr_t i = 0; i < len; i++) { 2014 for (intptr_t i = 0; i < len; i++) {
1964 field ^= fields_array.At(i); 2015 field ^= fields_array.At(i);
1965 if (!field.is_static() && !field.is_final()) { 2016 if (!field.is_static() && !field.is_final()) {
1966 const String& class_name = String::Handle(cls.Name()); 2017 const String& class_name = String::Handle(cls.Name());
1967 const String& field_name = String::Handle(field.name()); 2018 const String& field_name = String::Handle(field.name());
1968 const Script& script = Script::Handle(cls.script()); 2019 const Script& script = Script::Handle(cls.script());
1969 ReportError(script, field.token_pos(), 2020 ReportError(Error::Handle(), // No previous error.
2021 script, field.token_pos(),
1970 "const class '%s' has non-final field '%s'", 2022 "const class '%s' has non-final field '%s'",
1971 class_name.ToCString(), field_name.ToCString()); 2023 class_name.ToCString(), field_name.ToCString());
1972 } 2024 }
1973 } 2025 }
1974 } 2026 }
1975 2027
1976 2028
1977 void ClassFinalizer::PrintClassInformation(const Class& cls) { 2029 void ClassFinalizer::PrintClassInformation(const Class& cls) {
1978 HANDLESCOPE(Isolate::Current()); 2030 HANDLESCOPE(Isolate::Current());
1979 const String& class_name = String::Handle(cls.Name()); 2031 const String& class_name = String::Handle(cls.Name());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 va_end(args); 2136 va_end(args);
2085 } 2137 }
2086 2138
2087 2139
2088 void ClassFinalizer::ReportError(const Error& error) { 2140 void ClassFinalizer::ReportError(const Error& error) {
2089 Isolate::Current()->long_jump_base()->Jump(1, error); 2141 Isolate::Current()->long_jump_base()->Jump(1, error);
2090 UNREACHABLE(); 2142 UNREACHABLE();
2091 } 2143 }
2092 2144
2093 2145
2094 void ClassFinalizer::ReportError(const Script& script, 2146 void ClassFinalizer::ReportError(const Error& prev_error,
2147 const Script& script,
2095 intptr_t token_pos, 2148 intptr_t token_pos,
2096 const char* format, ...) { 2149 const char* format, ...) {
2097 va_list args; 2150 va_list args;
2098 va_start(args, format); 2151 va_start(args, format);
2099 const Error& error = Error::Handle( 2152 Error& error = Error::Handle();
2100 Parser::FormatError(script, token_pos, "Error", format, args)); 2153 if (prev_error.IsNull()) {
2154 error ^= Parser::FormatError(script, token_pos, "Error", format, args);
2155 } else {
2156 error ^= Parser::FormatErrorWithAppend(
2157 prev_error, script, token_pos, "Error", format, args);
2158 }
2101 va_end(args); 2159 va_end(args);
2102 ReportError(error); 2160 ReportError(error);
2103 } 2161 }
2104 2162
2105 2163
2106 void ClassFinalizer::ReportError(const char* format, ...) { 2164 void ClassFinalizer::ReportError(const char* format, ...) {
2107 va_list args; 2165 va_list args;
2108 va_start(args, format); 2166 va_start(args, format);
2109 const Error& error = Error::Handle( 2167 const Error& error = Error::Handle(
2110 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 2168 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 expected_name ^= String::New("_offset"); 2224 expected_name ^= String::New("_offset");
2167 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2225 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2168 field ^= fields_array.At(2); 2226 field ^= fields_array.At(2);
2169 ASSERT(field.Offset() == TypedDataView::length_offset()); 2227 ASSERT(field.Offset() == TypedDataView::length_offset());
2170 name ^= field.name(); 2228 name ^= field.name();
2171 ASSERT(name.Equals("length")); 2229 ASSERT(name.Equals("length"));
2172 #endif 2230 #endif
2173 } 2231 }
2174 2232
2175 } // namespace dart 2233 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698