| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 if (super_type.IsNull()) { | 292 if (super_type.IsNull()) { |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 // Resolve failures lead to a longjmp. | 295 // Resolve failures lead to a longjmp. |
| 296 ResolveType(cls, super_type); | 296 ResolveType(cls, super_type); |
| 297 const Class& super_class = Class::Handle(super_type.type_class()); | 297 const Class& super_class = Class::Handle(super_type.type_class()); |
| 298 if (cls.is_interface() != super_class.is_interface()) { | 298 if (cls.is_interface() != super_class.is_interface()) { |
| 299 String& class_name = String::Handle(cls.Name()); | 299 String& class_name = String::Handle(cls.Name()); |
| 300 String& super_class_name = String::Handle(super_class.Name()); | 300 String& super_class_name = String::Handle(super_class.Name()); |
| 301 const Script& script = Script::Handle(cls.script()); | 301 const Script& script = Script::Handle(cls.script()); |
| 302 ReportError(script, -1, | 302 ReportError(script, cls.token_index(), |
| 303 "class '%s' and superclass '%s' are not " | 303 "class '%s' and superclass '%s' are not " |
| 304 "both classes or both interfaces.\n", | 304 "both classes or both interfaces.\n", |
| 305 class_name.ToCString(), | 305 class_name.ToCString(), |
| 306 super_class_name.ToCString()); | 306 super_class_name.ToCString()); |
| 307 } | 307 } |
| 308 // If cls belongs to core lib or to core lib's implementation, restrictions | 308 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 309 // about allowed interfaces are lifted. | 309 // about allowed interfaces are lifted. |
| 310 if ((cls.library() != Library::CoreLibrary()) && | 310 if ((cls.library() != Library::CoreLibrary()) && |
| 311 (cls.library() != Library::CoreImplLibrary())) { | 311 (cls.library() != Library::CoreImplLibrary())) { |
| 312 // Prevent extending core implementation classes Bool, Double, ObjectArray, | 312 // Prevent extending core implementation classes Bool, Double, ObjectArray, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 330 (super_class.raw() == object_store->internal_byte_array_class()) || | 330 (super_class.raw() == object_store->internal_byte_array_class()) || |
| 331 (super_class.raw() == object_store->external_byte_array_class()) || | 331 (super_class.raw() == object_store->external_byte_array_class()) || |
| 332 (super_class.raw() == integer_implementation_class.raw()) || | 332 (super_class.raw() == integer_implementation_class.raw()) || |
| 333 (super_class.raw() == object_store->smi_class()) || | 333 (super_class.raw() == object_store->smi_class()) || |
| 334 (super_class.raw() == object_store->mint_class()) || | 334 (super_class.raw() == object_store->mint_class()) || |
| 335 (super_class.raw() == object_store->bigint_class()) || | 335 (super_class.raw() == object_store->bigint_class()) || |
| 336 (super_class.raw() == object_store->one_byte_string_class()) || | 336 (super_class.raw() == object_store->one_byte_string_class()) || |
| 337 (super_class.raw() == object_store->two_byte_string_class()) || | 337 (super_class.raw() == object_store->two_byte_string_class()) || |
| 338 (super_class.raw() == object_store->four_byte_string_class())) { | 338 (super_class.raw() == object_store->four_byte_string_class())) { |
| 339 const Script& script = Script::Handle(cls.script()); | 339 const Script& script = Script::Handle(cls.script()); |
| 340 ReportError(script, -1, | 340 ReportError(script, cls.token_index(), |
| 341 "'%s' is not allowed to extend '%s'\n", | 341 "'%s' is not allowed to extend '%s'\n", |
| 342 String::Handle(cls.Name()).ToCString(), | 342 String::Handle(cls.Name()).ToCString(), |
| 343 String::Handle(super_class.Name()).ToCString()); | 343 String::Handle(super_class.Name()).ToCString()); |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 return; | 346 return; |
| 347 } | 347 } |
| 348 | 348 |
| 349 | 349 |
| 350 void ClassFinalizer::ResolveDefaultClass(const Class& interface) { | 350 void ClassFinalizer::ResolveDefaultClass(const Class& interface) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 if (!type_extends.IsInstantiated()) { | 554 if (!type_extends.IsInstantiated()) { |
| 555 type_extends = type_extends.InstantiateFrom(arguments); | 555 type_extends = type_extends.InstantiateFrom(arguments); |
| 556 } | 556 } |
| 557 // TODO(regis): Where do we check the constraints when the type is | 557 // TODO(regis): Where do we check the constraints when the type is |
| 558 // generic? | 558 // generic? |
| 559 if (!type.IsSubtypeOf(type_extends)) { | 559 if (!type.IsSubtypeOf(type_extends)) { |
| 560 const String& type_argument_name = String::Handle(type.Name()); | 560 const String& type_argument_name = String::Handle(type.Name()); |
| 561 const String& class_name = String::Handle(cls.Name()); | 561 const String& class_name = String::Handle(cls.Name()); |
| 562 const String& extends_name = String::Handle(type_extends.Name()); | 562 const String& extends_name = String::Handle(type_extends.Name()); |
| 563 const Script& script = Script::Handle(cls.script()); | 563 const Script& script = Script::Handle(cls.script()); |
| 564 ReportError(script, -1, | 564 ReportError(script, type.token_index(), |
| 565 "type argument '%s' of class '%s' " | 565 "type argument '%s' of class '%s' " |
| 566 "does not extend type '%s'\n", | 566 "does not extend type '%s'\n", |
| 567 type_argument_name.ToCString(), | 567 type_argument_name.ToCString(), |
| 568 class_name.ToCString(), | 568 class_name.ToCString(), |
| 569 extends_name.ToCString()); | 569 extends_name.ToCString()); |
| 570 } | 570 } |
| 571 } | 571 } |
| 572 } | 572 } |
| 573 } | 573 } |
| 574 const Type& super_type = Type::Handle(cls.super_type()); | 574 const Type& super_type = Type::Handle(cls.super_type()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 603 type_parameter.set_is_finalized(); | 603 type_parameter.set_is_finalized(); |
| 604 // We do not canonicalize type parameters. | 604 // We do not canonicalize type parameters. |
| 605 return type_parameter.raw(); | 605 return type_parameter.raw(); |
| 606 } | 606 } |
| 607 | 607 |
| 608 // At this point, we can only have a parameterized_type. | 608 // At this point, we can only have a parameterized_type. |
| 609 Type& parameterized_type = Type::Handle(); | 609 Type& parameterized_type = Type::Handle(); |
| 610 parameterized_type ^= type.raw(); | 610 parameterized_type ^= type.raw(); |
| 611 | 611 |
| 612 if (parameterized_type.IsBeingFinalized()) { | 612 if (parameterized_type.IsBeingFinalized()) { |
| 613 ReportError("type '%s' illegally refers to itself\n", | 613 const Script& script = Script::Handle(cls.script()); |
| 614 ReportError(script, parameterized_type.token_index(), |
| 615 "type '%s' illegally refers to itself\n", |
| 614 String::Handle(parameterized_type.Name()).ToCString()); | 616 String::Handle(parameterized_type.Name()).ToCString()); |
| 615 } | 617 } |
| 616 | 618 |
| 617 // Mark type as being finalized in order to detect illegal self reference. | 619 // Mark type as being finalized in order to detect illegal self reference. |
| 618 parameterized_type.set_is_being_finalized(); | 620 parameterized_type.set_is_being_finalized(); |
| 619 | 621 |
| 620 // Finalize the current type arguments of the type, which are still the | 622 // Finalize the current type arguments of the type, which are still the |
| 621 // parsed type arguments. | 623 // parsed type arguments. |
| 622 AbstractTypeArguments& arguments = | 624 AbstractTypeArguments& arguments = |
| 623 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 625 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 652 // The finalized type argument vector needs num_type_arguments types. | 654 // The finalized type argument vector needs num_type_arguments types. |
| 653 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 655 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 654 // The type class has num_type_parameters type parameters. | 656 // The type class has num_type_parameters type parameters. |
| 655 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 657 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 656 | 658 |
| 657 // Initialize the type argument vector. | 659 // Initialize the type argument vector. |
| 658 // Check the number of parsed type arguments, if any. | 660 // Check the number of parsed type arguments, if any. |
| 659 // Specifying no type arguments indicates a raw type, which is not an error. | 661 // Specifying no type arguments indicates a raw type, which is not an error. |
| 660 // However, subtyping constraints are checked below, even for a raw type. | 662 // However, subtyping constraints are checked below, even for a raw type. |
| 661 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 663 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 662 // TODO(regis): We need to store the token_index in each type. | 664 const Script& script = Script::Handle(cls.script()); |
| 663 ReportError("wrong number of type arguments in type '%s'\n", | 665 ReportError(script, type.token_index(), |
| 666 "wrong number of type arguments in type '%s'\n", |
| 664 String::Handle(type.Name()).ToCString()); | 667 String::Handle(type.Name()).ToCString()); |
| 665 } | 668 } |
| 666 // The full type argument vector consists of the type arguments of the | 669 // The full type argument vector consists of the type arguments of the |
| 667 // super types of type_class, which may be initialized from the parsed | 670 // super types of type_class, which may be initialized from the parsed |
| 668 // type arguments, followed by the parsed type arguments. | 671 // type arguments, followed by the parsed type arguments. |
| 669 if (num_type_arguments > 0) { | 672 if (num_type_arguments > 0) { |
| 670 TypeArguments& full_arguments = TypeArguments::Handle( | 673 TypeArguments& full_arguments = TypeArguments::Handle( |
| 671 TypeArguments::New(num_type_arguments)); | 674 TypeArguments::New(num_type_arguments)); |
| 672 // Copy the parsed type arguments at the correct offset in the full type | 675 // Copy the parsed type arguments at the correct offset in the full type |
| 673 // argument vector. | 676 // argument vector. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 703 if (FLAG_enable_type_checks) { | 706 if (FLAG_enable_type_checks) { |
| 704 VerifyUpperBounds(type_class, full_arguments); | 707 VerifyUpperBounds(type_class, full_arguments); |
| 705 } | 708 } |
| 706 } else { | 709 } else { |
| 707 parameterized_type.set_is_finalized(); | 710 parameterized_type.set_is_finalized(); |
| 708 } | 711 } |
| 709 return parameterized_type.Canonicalize(); | 712 return parameterized_type.Canonicalize(); |
| 710 } | 713 } |
| 711 | 714 |
| 712 | 715 |
| 713 RawAbstractType* ClassFinalizer::FinalizeAndCanonicalizeType( | |
| 714 const Class& cls, | |
| 715 const AbstractType& type, | |
| 716 Error* error) { | |
| 717 Isolate* isolate = Isolate::Current(); | |
| 718 ASSERT(isolate != NULL); | |
| 719 LongJump* base = isolate->long_jump_base(); | |
| 720 LongJump jump; | |
| 721 isolate->set_long_jump_base(&jump); | |
| 722 if (setjmp(*jump.Set()) == 0) { | |
| 723 const AbstractType& finalized_type = | |
| 724 AbstractType::Handle(FinalizeType(cls, type)); | |
| 725 isolate->set_long_jump_base(base); | |
| 726 *error = Error::null(); | |
| 727 return finalized_type.raw(); | |
| 728 } else { | |
| 729 // Error occured: Get the error message. | |
| 730 isolate->set_long_jump_base(base); | |
| 731 *error = isolate->object_store()->sticky_error(); | |
| 732 return type.raw(); | |
| 733 } | |
| 734 UNREACHABLE(); | |
| 735 return NULL; | |
| 736 } | |
| 737 | |
| 738 | |
| 739 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 716 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 740 const Function& function) { | 717 const Function& function) { |
| 741 // Resolve result type. | 718 // Resolve result type. |
| 742 AbstractType& type = AbstractType::Handle(function.result_type()); | 719 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 743 ResolveType(cls, type); | 720 ResolveType(cls, type); |
| 744 type = FinalizeType(cls, type); | 721 type = FinalizeType(cls, type); |
| 745 function.set_result_type(type); | 722 function.set_result_type(type); |
| 746 // Resolve formal parameter types. | 723 // Resolve formal parameter types. |
| 747 const intptr_t num_parameters = function.NumberOfParameters(); | 724 const intptr_t num_parameters = function.NumberOfParameters(); |
| 748 for (intptr_t i = 0; i < num_parameters; i++) { | 725 for (intptr_t i = 0; i < num_parameters; i++) { |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 return; | 941 return; |
| 965 } | 942 } |
| 966 if (FLAG_trace_class_finalization) { | 943 if (FLAG_trace_class_finalization) { |
| 967 OS::Print("Finalize %s\n", cls.ToCString()); | 944 OS::Print("Finalize %s\n", cls.ToCString()); |
| 968 } | 945 } |
| 969 // Signature classes are finalized upon creation. | 946 // Signature classes are finalized upon creation. |
| 970 ASSERT(!cls.IsSignatureClass()); | 947 ASSERT(!cls.IsSignatureClass()); |
| 971 if (!IsSuperCycleFree(cls)) { | 948 if (!IsSuperCycleFree(cls)) { |
| 972 const String& name = String::Handle(cls.Name()); | 949 const String& name = String::Handle(cls.Name()); |
| 973 const Script& script = Script::Handle(cls.script()); | 950 const Script& script = Script::Handle(cls.script()); |
| 974 ReportError(script, -1, | 951 ReportError(script, cls.token_index(), |
| 975 "class '%s' has a cycle in its superclass relationship.\n", | 952 "class '%s' has a cycle in its superclass relationship.\n", |
| 976 name.ToCString()); | 953 name.ToCString()); |
| 977 } | 954 } |
| 978 GrowableArray<const Class*> visited; | 955 GrowableArray<const Class*> visited; |
| 979 ResolveInterfaces(cls, &visited); | 956 ResolveInterfaces(cls, &visited); |
| 980 Type& super_type = Type::Handle(cls.super_type()); | 957 Type& super_type = Type::Handle(cls.super_type()); |
| 981 if (!super_type.IsNull()) { | 958 if (!super_type.IsNull()) { |
| 982 const Class& super_class = Class::Handle(super_type.type_class()); | 959 const Class& super_class = Class::Handle(super_type.type_class()); |
| 983 // Finalize super class and super type. | 960 // Finalize super class and super type. |
| 984 FinalizeClass(super_class, generating_snapshot); | 961 FinalizeClass(super_class, generating_snapshot); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 CheckForLegalConstClass(cls); | 993 CheckForLegalConstClass(cls); |
| 1017 } | 994 } |
| 1018 // Check to ensure we don't have classes with native fields in libraries | 995 // Check to ensure we don't have classes with native fields in libraries |
| 1019 // which do not have a native resolver. | 996 // which do not have a native resolver. |
| 1020 if (!generating_snapshot && cls.num_native_fields() != 0) { | 997 if (!generating_snapshot && cls.num_native_fields() != 0) { |
| 1021 const Library& lib = Library::Handle(cls.library()); | 998 const Library& lib = Library::Handle(cls.library()); |
| 1022 if (lib.native_entry_resolver() == NULL) { | 999 if (lib.native_entry_resolver() == NULL) { |
| 1023 const String& cls_name = String::Handle(cls.Name()); | 1000 const String& cls_name = String::Handle(cls.Name()); |
| 1024 const String& lib_name = String::Handle(lib.url()); | 1001 const String& lib_name = String::Handle(lib.url()); |
| 1025 const Script& script = Script::Handle(cls.script()); | 1002 const Script& script = Script::Handle(cls.script()); |
| 1026 ReportError(script, -1, | 1003 ReportError(script, cls.token_index(), |
| 1027 "class '%s' is trying to extend a native fields class, " | 1004 "class '%s' is trying to extend a native fields class, " |
| 1028 "but library '%s' has no native resolvers", | 1005 "but library '%s' has no native resolvers", |
| 1029 cls_name.ToCString(), lib_name.ToCString()); | 1006 cls_name.ToCString(), lib_name.ToCString()); |
| 1030 } | 1007 } |
| 1031 } | 1008 } |
| 1032 } | 1009 } |
| 1033 | 1010 |
| 1034 | 1011 |
| 1035 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 1012 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| 1036 Class& test1 = Class::Handle(cls.raw()); | 1013 Class& test1 = Class::Handle(cls.raw()); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 // graph. If we visit an interface a second time on a given path, | 1076 // graph. If we visit an interface a second time on a given path, |
| 1100 // we found a loop. | 1077 // we found a loop. |
| 1101 void ClassFinalizer::ResolveInterfaces(const Class& cls, | 1078 void ClassFinalizer::ResolveInterfaces(const Class& cls, |
| 1102 GrowableArray<const Class*>* visited) { | 1079 GrowableArray<const Class*>* visited) { |
| 1103 ASSERT(visited != NULL); | 1080 ASSERT(visited != NULL); |
| 1104 for (int i = 0; i < visited->length(); i++) { | 1081 for (int i = 0; i < visited->length(); i++) { |
| 1105 if ((*visited)[i]->raw() == cls.raw()) { | 1082 if ((*visited)[i]->raw() == cls.raw()) { |
| 1106 // We have already visited interface class 'cls'. We found a cycle. | 1083 // We have already visited interface class 'cls'. We found a cycle. |
| 1107 const String& interface_name = String::Handle(cls.Name()); | 1084 const String& interface_name = String::Handle(cls.Name()); |
| 1108 const Script& script = Script::Handle(cls.script()); | 1085 const Script& script = Script::Handle(cls.script()); |
| 1109 ReportError(script, -1, | 1086 ReportError(script, cls.token_index(), |
| 1110 "Cyclic reference found for interface '%s'\n", | 1087 "Cyclic reference found for interface '%s'\n", |
| 1111 interface_name.ToCString()); | 1088 interface_name.ToCString()); |
| 1112 } | 1089 } |
| 1113 } | 1090 } |
| 1114 | 1091 |
| 1115 // If the class/interface has no explicit interfaces, we are done. | 1092 // If the class/interface has no explicit interfaces, we are done. |
| 1116 Array& super_interfaces = Array::Handle(cls.interfaces()); | 1093 Array& super_interfaces = Array::Handle(cls.interfaces()); |
| 1117 if (super_interfaces.Length() == 0) { | 1094 if (super_interfaces.Length() == 0) { |
| 1118 return; | 1095 return; |
| 1119 } | 1096 } |
| 1120 | 1097 |
| 1121 // If cls belongs to core lib or to core lib's implementation, restrictions | 1098 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 1122 // about allowed interfaces are lifted. | 1099 // about allowed interfaces are lifted. |
| 1123 const bool cls_belongs_to_core_lib = | 1100 const bool cls_belongs_to_core_lib = |
| 1124 (cls.library() == Library::CoreLibrary()) || | 1101 (cls.library() == Library::CoreLibrary()) || |
| 1125 (cls.library() == Library::CoreImplLibrary()); | 1102 (cls.library() == Library::CoreImplLibrary()); |
| 1126 | 1103 |
| 1127 // Resolve and check the interfaces of cls. | 1104 // Resolve and check the interfaces of cls. |
| 1128 visited->Add(&cls); | 1105 visited->Add(&cls); |
| 1129 AbstractType& interface = AbstractType::Handle(); | 1106 AbstractType& interface = AbstractType::Handle(); |
| 1130 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1107 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 1131 interface ^= super_interfaces.At(i); | 1108 interface ^= super_interfaces.At(i); |
| 1132 ResolveType(cls, interface); | 1109 ResolveType(cls, interface); |
| 1133 if (interface.IsTypeParameter()) { | 1110 if (interface.IsTypeParameter()) { |
| 1134 const Script& script = Script::Handle(cls.script()); | 1111 const Script& script = Script::Handle(cls.script()); |
| 1135 ReportError(script, -1, | 1112 ReportError(script, cls.token_index(), |
| 1136 "Type parameter '%s' cannot be used as interface\n", | 1113 "Type parameter '%s' cannot be used as interface\n", |
| 1137 String::Handle(interface.Name()).ToCString()); | 1114 String::Handle(interface.Name()).ToCString()); |
| 1138 } | 1115 } |
| 1139 const Class& interface_class = Class::Handle(interface.type_class()); | 1116 const Class& interface_class = Class::Handle(interface.type_class()); |
| 1140 if (!interface_class.is_interface()) { | 1117 if (!interface_class.is_interface()) { |
| 1141 const Script& script = Script::Handle(cls.script()); | 1118 const Script& script = Script::Handle(cls.script()); |
| 1142 ReportError(script, -1, | 1119 ReportError(script, cls.token_index(), |
| 1143 "Class '%s' is used where an interface is expected\n", | 1120 "Class '%s' is used where an interface is expected\n", |
| 1144 String::Handle(interface_class.Name()).ToCString()); | 1121 String::Handle(interface_class.Name()).ToCString()); |
| 1145 } | 1122 } |
| 1146 // Verify that unless cls belongs to core lib, it cannot extend or implement | 1123 // Verify that unless cls belongs to core lib, it cannot extend or implement |
| 1147 // any of bool, num, int, double, String, Function, Dynamic. | 1124 // any of bool, num, int, double, String, Function, Dynamic. |
| 1148 // The exception is signature classes, which are compiler generated and | 1125 // The exception is signature classes, which are compiler generated and |
| 1149 // represent a function type, therefore implementing the Function interface. | 1126 // represent a function type, therefore implementing the Function interface. |
| 1150 if (!cls_belongs_to_core_lib) { | 1127 if (!cls_belongs_to_core_lib) { |
| 1151 if (interface.IsBoolInterface() || | 1128 if (interface.IsBoolInterface() || |
| 1152 interface.IsNumberInterface() || | 1129 interface.IsNumberInterface() || |
| 1153 interface.IsIntInterface() || | 1130 interface.IsIntInterface() || |
| 1154 interface.IsDoubleInterface() || | 1131 interface.IsDoubleInterface() || |
| 1155 interface.IsStringInterface() || | 1132 interface.IsStringInterface() || |
| 1156 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || | 1133 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || |
| 1157 interface.IsDynamicType()) { | 1134 interface.IsDynamicType()) { |
| 1158 const Script& script = Script::Handle(cls.script()); | 1135 const Script& script = Script::Handle(cls.script()); |
| 1159 ReportError(script, -1, | 1136 ReportError(script, cls.token_index(), |
| 1160 "'%s' is not allowed to extend or implement '%s'\n", | 1137 "'%s' is not allowed to extend or implement '%s'\n", |
| 1161 String::Handle(cls.Name()).ToCString(), | 1138 String::Handle(cls.Name()).ToCString(), |
| 1162 String::Handle(interface_class.Name()).ToCString()); | 1139 String::Handle(interface_class.Name()).ToCString()); |
| 1163 } | 1140 } |
| 1164 } | 1141 } |
| 1165 // Now resolve the super interfaces. | 1142 // Now resolve the super interfaces. |
| 1166 ResolveInterfaces(interface_class, visited); | 1143 ResolveInterfaces(interface_class, visited); |
| 1167 } | 1144 } |
| 1168 visited->RemoveLast(); | 1145 visited->RemoveLast(); |
| 1169 } | 1146 } |
| 1170 | 1147 |
| 1171 | 1148 |
| 1172 // A class is marked as constant if it has one constant constructor. | 1149 // A class is marked as constant if it has one constant constructor. |
| 1173 // A constant class: | 1150 // A constant class: |
| 1174 // - may extend only const classes. | 1151 // - may extend only const classes. |
| 1175 // - has only const instance fields. | 1152 // - has only const instance fields. |
| 1176 // Note: we must check for cycles before checking for const properties. | 1153 // Note: we must check for cycles before checking for const properties. |
| 1177 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { | 1154 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { |
| 1178 ASSERT(cls.is_const()); | 1155 ASSERT(cls.is_const()); |
| 1179 const Class& super = Class::Handle(cls.SuperClass()); | 1156 const Class& super = Class::Handle(cls.SuperClass()); |
| 1180 if (!super.IsNull() && !super.is_const()) { | 1157 if (!super.IsNull() && !super.is_const()) { |
| 1181 String& name = String::Handle(super.Name()); | 1158 String& name = String::Handle(super.Name()); |
| 1182 const Script& script = Script::Handle(cls.script()); | 1159 const Script& script = Script::Handle(cls.script()); |
| 1183 ReportError(script, -1, | 1160 ReportError(script, cls.token_index(), |
| 1184 "superclass '%s' must be const.\n", name.ToCString()); | 1161 "superclass '%s' must be const.\n", name.ToCString()); |
| 1185 } | 1162 } |
| 1186 const Array& fields_array = Array::Handle(cls.fields()); | 1163 const Array& fields_array = Array::Handle(cls.fields()); |
| 1187 intptr_t len = fields_array.Length(); | 1164 intptr_t len = fields_array.Length(); |
| 1188 Field& field = Field::Handle(); | 1165 Field& field = Field::Handle(); |
| 1189 for (intptr_t i = 0; i < len; i++) { | 1166 for (intptr_t i = 0; i < len; i++) { |
| 1190 field ^= fields_array.At(i); | 1167 field ^= fields_array.At(i); |
| 1191 if (!field.is_static() && !field.is_final()) { | 1168 if (!field.is_static() && !field.is_final()) { |
| 1192 const String& class_name = String::Handle(cls.Name()); | 1169 const String& class_name = String::Handle(cls.Name()); |
| 1193 const String& field_name = String::Handle(field.name()); | 1170 const String& field_name = String::Handle(field.name()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 va_end(args); | 1249 va_end(args); |
| 1273 if (FLAG_warning_as_error) { | 1250 if (FLAG_warning_as_error) { |
| 1274 Isolate::Current()->long_jump_base()->Jump(1, error); | 1251 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1275 UNREACHABLE(); | 1252 UNREACHABLE(); |
| 1276 } else { | 1253 } else { |
| 1277 OS::Print("%s", error.ToErrorCString()); | 1254 OS::Print("%s", error.ToErrorCString()); |
| 1278 } | 1255 } |
| 1279 } | 1256 } |
| 1280 | 1257 |
| 1281 } // namespace dart | 1258 } // namespace dart |
| OLD | NEW |