| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 ReportError("Duplicate definition : %s\n", str.ToCString()); | 90 ReportError("Duplicate definition : %s\n", str.ToCString()); |
| 91 } | 91 } |
| 92 } else { | 92 } else { |
| 93 retval = false; | 93 retval = false; |
| 94 } | 94 } |
| 95 isolate->set_long_jump_base(base); | 95 isolate->set_long_jump_base(base); |
| 96 return retval; | 96 return retval; |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 #if defined (DEBUG) | |
| 101 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 100 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
| 102 // No cycles are allowed. | 101 // No cycles are allowed. |
| 103 void ClassFinalizer::CollectInterfaces(const Class& cls, | 102 void ClassFinalizer::CollectInterfaces(const Class& cls, |
| 104 const GrowableObjectArray& collected) { | 103 const GrowableObjectArray& collected) { |
| 105 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); | 104 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); |
| 106 AbstractType& interface = AbstractType::Handle(); | 105 AbstractType& interface = AbstractType::Handle(); |
| 107 Class& interface_class = Class::Handle(); | 106 Class& interface_class = Class::Handle(); |
| 108 for (intptr_t i = 0; i < interface_array.Length(); i++) { | 107 for (intptr_t i = 0; i < interface_array.Length(); i++) { |
| 109 interface ^= interface_array.At(i); | 108 interface ^= interface_array.At(i); |
| 110 interface_class = interface.type_class(); | 109 interface_class = interface.type_class(); |
| 111 collected.Add(interface_class); | 110 collected.Add(interface_class); |
| 112 CollectInterfaces(interface_class, collected); | 111 CollectInterfaces(interface_class, collected); |
| 113 } | 112 } |
| 114 } | 113 } |
| 115 | 114 |
| 116 | 115 |
| 116 #if defined (DEBUG) |
| 117 // Collect all interfaces of the class 'cls' and check that every function | 117 // Collect all interfaces of the class 'cls' and check that every function |
| 118 // defined in each interface can be found in the class. | 118 // defined in each interface can be found in the class. |
| 119 // No need to check instance fields since they have been turned into | 119 // No need to check instance fields since they have been turned into |
| 120 // getters/setters. | 120 // getters/setters. |
| 121 void ClassFinalizer::VerifyClassImplements(const Class& cls) { | 121 void ClassFinalizer::VerifyClassImplements(const Class& cls) { |
| 122 ASSERT(!cls.is_interface()); | 122 ASSERT(!cls.is_interface()); |
| 123 const GrowableObjectArray& interfaces = | 123 const GrowableObjectArray& interfaces = |
| 124 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 124 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 125 CollectInterfaces(cls, interfaces); | 125 CollectInterfaces(cls, interfaces); |
| 126 const String& class_name = String::Handle(cls.Name()); | 126 const String& class_name = String::Handle(cls.Name()); |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 const Script& script = Script::Handle(cls.script()); | 944 const Script& script = Script::Handle(cls.script()); |
| 945 ReportError(script, field.token_index(), | 945 ReportError(script, field.token_index(), |
| 946 "field '%s' of class '%s' conflicts with instance " | 946 "field '%s' of class '%s' conflicts with instance " |
| 947 "member '%s' of super class '%s'", | 947 "member '%s' of super class '%s'", |
| 948 name.ToCString(), | 948 name.ToCString(), |
| 949 class_name.ToCString(), | 949 class_name.ToCString(), |
| 950 name.ToCString(), | 950 name.ToCString(), |
| 951 super_class_name.ToCString()); | 951 super_class_name.ToCString()); |
| 952 } | 952 } |
| 953 } | 953 } |
| 954 // Resolve function signatures and check for conflicts in super classes. | 954 // Collect interfaces, super interfaces, and super classes of this class. |
| 955 const GrowableObjectArray& interfaces = |
| 956 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 957 CollectInterfaces(cls, interfaces); |
| 958 // Include superclasses in list of interfaces and super interfaces. |
| 959 super_class = cls.SuperClass(); |
| 960 while (!super_class.IsNull()) { |
| 961 interfaces.Add(super_class); |
| 962 super_class = super_class.SuperClass(); |
| 963 } |
| 964 // Resolve function signatures and check for conflicts in super classes and |
| 965 // interfaces. |
| 955 array = cls.functions(); | 966 array = cls.functions(); |
| 956 Function& function = Function::Handle(); | 967 Function& function = Function::Handle(); |
| 957 Function& overridden_function = Function::Handle(); | 968 Function& overridden_function = Function::Handle(); |
| 958 intptr_t num_functions = array.Length(); | 969 intptr_t num_functions = array.Length(); |
| 959 String& function_name = String::Handle(); | 970 String& function_name = String::Handle(); |
| 960 for (intptr_t i = 0; i < num_functions; i++) { | 971 for (intptr_t i = 0; i < num_functions; i++) { |
| 961 function ^= array.At(i); | 972 function ^= array.At(i); |
| 962 ResolveAndFinalizeSignature(cls, function); | 973 ResolveAndFinalizeSignature(cls, function); |
| 963 function_name = function.name(); | 974 function_name = function.name(); |
| 964 if (function.is_static()) { | 975 if (function.is_static()) { |
| 965 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); | 976 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); |
| 966 if (!super_class.IsNull()) { | 977 if (!super_class.IsNull()) { |
| 967 const String& class_name = String::Handle(cls.Name()); | 978 const String& class_name = String::Handle(cls.Name()); |
| 968 const String& super_class_name = String::Handle(super_class.Name()); | 979 const String& super_class_name = String::Handle(super_class.Name()); |
| 969 const Script& script = Script::Handle(cls.script()); | 980 const Script& script = Script::Handle(cls.script()); |
| 970 ReportError(script, function.token_index(), | 981 ReportError(script, function.token_index(), |
| 971 "static function '%s' of class '%s' conflicts with " | 982 "static function '%s' of class '%s' conflicts with " |
| 972 "instance member '%s' of super class '%s'", | 983 "instance member '%s' of super class '%s'", |
| 973 function_name.ToCString(), | 984 function_name.ToCString(), |
| 974 class_name.ToCString(), | 985 class_name.ToCString(), |
| 975 function_name.ToCString(), | 986 function_name.ToCString(), |
| 976 super_class_name.ToCString()); | 987 super_class_name.ToCString()); |
| 977 } | 988 } |
| 978 } else { | 989 } else { |
| 979 // TODO(regis): This arity check is still being debated. Revisit. | 990 for (int i = 0; i < interfaces.Length(); i++) { |
| 980 super_class = cls.SuperClass(); | 991 super_class ^= interfaces.At(i); |
| 981 while (!super_class.IsNull()) { | |
| 982 overridden_function = super_class.LookupDynamicFunction(function_name); | 992 overridden_function = super_class.LookupDynamicFunction(function_name); |
| 983 if (!overridden_function.IsNull() && | 993 if (!overridden_function.IsNull() && |
| 984 !function.HasCompatibleParametersWith(overridden_function)) { | 994 !function.HasCompatibleParametersWith(overridden_function)) { |
| 985 // Function types are purposely not checked for subtyping. | 995 // Function types are purposely not checked for subtyping. |
| 986 const String& class_name = String::Handle(cls.Name()); | 996 const String& class_name = String::Handle(cls.Name()); |
| 987 const String& super_class_name = String::Handle(super_class.Name()); | 997 const String& super_class_name = String::Handle(super_class.Name()); |
| 988 const Script& script = Script::Handle(cls.script()); | 998 const Script& script = Script::Handle(cls.script()); |
| 989 ReportError(script, function.token_index(), | 999 ReportError(script, function.token_index(), |
| 990 "class '%s' overrides function '%s' of super class '%s' " | 1000 "class '%s' overrides function '%s' of %s '%s' " |
| 991 "with incompatible parameters", | 1001 "with incompatible parameters", |
| 992 class_name.ToCString(), | 1002 class_name.ToCString(), |
| 993 function_name.ToCString(), | 1003 function_name.ToCString(), |
| 1004 super_class.is_interface() ? "interface" : "super class", |
| 994 super_class_name.ToCString()); | 1005 super_class_name.ToCString()); |
| 995 } | 1006 } |
| 996 super_class = super_class.SuperClass(); | |
| 997 } | 1007 } |
| 998 } | 1008 } |
| 999 if (function.kind() == RawFunction::kGetterFunction) { | 1009 if (function.kind() == RawFunction::kGetterFunction) { |
| 1000 name = Field::NameFromGetter(function_name); | 1010 name = Field::NameFromGetter(function_name); |
| 1001 super_class = FindSuperOwnerOfFunction(cls, name); | 1011 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1002 if (!super_class.IsNull()) { | 1012 if (!super_class.IsNull()) { |
| 1003 const String& class_name = String::Handle(cls.Name()); | 1013 const String& class_name = String::Handle(cls.Name()); |
| 1004 const String& super_class_name = String::Handle(super_class.Name()); | 1014 const String& super_class_name = String::Handle(super_class.Name()); |
| 1005 const Script& script = Script::Handle(cls.script()); | 1015 const Script& script = Script::Handle(cls.script()); |
| 1006 ReportError(script, function.token_index(), | 1016 ReportError(script, function.token_index(), |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 void ClassFinalizer::ReportError(const char* format, ...) { | 1493 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1484 va_list args; | 1494 va_list args; |
| 1485 va_start(args, format); | 1495 va_start(args, format); |
| 1486 const Error& error = Error::Handle( | 1496 const Error& error = Error::Handle( |
| 1487 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1497 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1488 va_end(args); | 1498 va_end(args); |
| 1489 ReportError(error); | 1499 ReportError(error); |
| 1490 } | 1500 } |
| 1491 | 1501 |
| 1492 } // namespace dart | 1502 } // namespace dart |
| OLD | NEW |