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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 type = FinalizeType(cls, type, kCanonicalize); | 948 type = FinalizeType(cls, type, kCanonicalize); |
949 // In production mode, a malformed parameter type is mapped to dynamic. | 949 // In production mode, a malformed parameter type is mapped to dynamic. |
950 if (!FLAG_enable_type_checks && type.IsMalformed()) { | 950 if (!FLAG_enable_type_checks && type.IsMalformed()) { |
951 type = Type::DynamicType(); | 951 type = Type::DynamicType(); |
952 } | 952 } |
953 function.SetParameterTypeAt(i, type); | 953 function.SetParameterTypeAt(i, type); |
954 } | 954 } |
955 } | 955 } |
956 | 956 |
957 | 957 |
| 958 // Check if an instance field or method of same name exists |
| 959 // in any super class. |
958 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, | 960 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, |
959 const String& name) { | 961 const String& name) { |
960 Class& super_class = Class::Handle(); | 962 Class& super_class = Class::Handle(); |
961 Function& function = Function::Handle(); | 963 Function& function = Function::Handle(); |
962 Field& field = Field::Handle(); | 964 Field& field = Field::Handle(); |
963 super_class = cls.SuperClass(); | 965 super_class = cls.SuperClass(); |
964 while (!super_class.IsNull()) { | 966 while (!super_class.IsNull()) { |
965 // Check if an instance member of same name exists in any super class. | |
966 function = super_class.LookupFunction(name); | 967 function = super_class.LookupFunction(name); |
967 if (!function.IsNull() && !function.is_static()) { | 968 if (!function.IsNull() && !function.is_static()) { |
968 return super_class.raw(); | 969 return super_class.raw(); |
969 } | 970 } |
970 field = super_class.LookupField(name); | 971 field = super_class.LookupField(name); |
971 if (!field.IsNull() && !field.is_static()) { | 972 if (!field.IsNull() && !field.is_static()) { |
972 return super_class.raw(); | 973 return super_class.raw(); |
973 } | 974 } |
974 super_class = super_class.SuperClass(); | 975 super_class = super_class.SuperClass(); |
975 } | 976 } |
976 return Class::null(); | 977 return Class::null(); |
977 } | 978 } |
978 | 979 |
979 | 980 |
| 981 // Check if an instance method of same name exists in any super class. |
980 static RawClass* FindSuperOwnerOfFunction(const Class& cls, | 982 static RawClass* FindSuperOwnerOfFunction(const Class& cls, |
981 const String& name) { | 983 const String& name) { |
982 Class& super_class = Class::Handle(); | 984 Class& super_class = Class::Handle(); |
983 Function& function = Function::Handle(); | 985 Function& function = Function::Handle(); |
984 super_class = cls.SuperClass(); | 986 super_class = cls.SuperClass(); |
985 while (!super_class.IsNull()) { | 987 while (!super_class.IsNull()) { |
986 // Check if a function of same name exists in any super class. | |
987 function = super_class.LookupFunction(name); | 988 function = super_class.LookupFunction(name); |
988 if (!function.IsNull() && !function.is_static()) { | 989 if (!function.IsNull() && !function.is_static()) { |
989 return super_class.raw(); | 990 return super_class.raw(); |
990 } | 991 } |
991 super_class = super_class.SuperClass(); | 992 super_class = super_class.SuperClass(); |
992 } | 993 } |
993 return Class::null(); | 994 return Class::null(); |
994 } | 995 } |
995 | 996 |
996 | 997 |
(...skipping 19 matching lines...) Expand all Loading... |
1016 } | 1017 } |
1017 | 1018 |
1018 | 1019 |
1019 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 1020 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
1020 // Note that getters and setters are explicitly listed as such in the list of | 1021 // Note that getters and setters are explicitly listed as such in the list of |
1021 // functions of a class, so we do not need to consider fields as implicitly | 1022 // functions of a class, so we do not need to consider fields as implicitly |
1022 // generating getters and setters. | 1023 // generating getters and setters. |
1023 // The only compile errors we report are therefore: | 1024 // The only compile errors we report are therefore: |
1024 // - a getter having the same name as a method (but not a getter) in a super | 1025 // - a getter having the same name as a method (but not a getter) in a super |
1025 // class or in a subclass. | 1026 // class or in a subclass. |
1026 // - a setter having the same name as a method (but not a setter) in a super | |
1027 // class or in a subclass. | |
1028 // - a static field, instance field, or static method (but not an instance | 1027 // - a static field, instance field, or static method (but not an instance |
1029 // method) having the same name as an instance member in a super class. | 1028 // method) having the same name as an instance member in a super class. |
1030 | 1029 |
1031 // Resolve type of fields and check for conflicts in super classes. | 1030 // Resolve type of fields and check for conflicts in super classes. |
1032 Array& array = Array::Handle(cls.fields()); | 1031 Array& array = Array::Handle(cls.fields()); |
1033 Field& field = Field::Handle(); | 1032 Field& field = Field::Handle(); |
1034 AbstractType& type = AbstractType::Handle(); | 1033 AbstractType& type = AbstractType::Handle(); |
1035 String& name = String::Handle(); | 1034 String& name = String::Handle(); |
1036 Class& super_class = Class::Handle(); | 1035 Class& super_class = Class::Handle(); |
1037 intptr_t num_fields = array.Length(); | 1036 intptr_t num_fields = array.Length(); |
1038 for (intptr_t i = 0; i < num_fields; i++) { | 1037 for (intptr_t i = 0; i < num_fields; i++) { |
1039 field ^= array.At(i); | 1038 field ^= array.At(i); |
1040 type = field.type(); | 1039 type = field.type(); |
1041 ResolveType(cls, type, kCanonicalize); | 1040 ResolveType(cls, type, kCanonicalize); |
1042 type = FinalizeType(cls, type, kCanonicalize); | 1041 type = FinalizeType(cls, type, kCanonicalize); |
1043 field.set_type(type); | 1042 field.set_type(type); |
1044 name = field.name(); | 1043 name = field.name(); |
1045 super_class = FindSuperOwnerOfInstanceMember(cls, name); | 1044 if (field.is_static()) { |
1046 if (!super_class.IsNull()) { | 1045 super_class = FindSuperOwnerOfInstanceMember(cls, name); |
1047 const String& class_name = String::Handle(cls.Name()); | 1046 if (!super_class.IsNull()) { |
1048 const String& super_class_name = String::Handle(super_class.Name()); | 1047 const String& class_name = String::Handle(cls.Name()); |
1049 const Script& script = Script::Handle(cls.script()); | 1048 const String& super_class_name = String::Handle(super_class.Name()); |
1050 ReportError(script, field.token_pos(), | 1049 const Script& script = Script::Handle(cls.script()); |
1051 "field '%s' of class '%s' conflicts with instance " | 1050 ReportError(script, field.token_pos(), |
1052 "member '%s' of super class '%s'", | 1051 "static field '%s' of class '%s' conflicts with " |
1053 name.ToCString(), | 1052 "instance member '%s' of super class '%s'", |
1054 class_name.ToCString(), | 1053 name.ToCString(), |
1055 name.ToCString(), | 1054 class_name.ToCString(), |
1056 super_class_name.ToCString()); | 1055 name.ToCString(), |
| 1056 super_class_name.ToCString()); |
| 1057 } |
| 1058 } else { |
| 1059 // Instance field. Check whether the field overrides a method |
| 1060 // (but not getter). |
| 1061 super_class = FindSuperOwnerOfFunction(cls, name); |
| 1062 if (!super_class.IsNull()) { |
| 1063 const String& class_name = String::Handle(cls.Name()); |
| 1064 const String& super_class_name = String::Handle(super_class.Name()); |
| 1065 const Script& script = Script::Handle(cls.script()); |
| 1066 ReportError(script, field.token_pos(), |
| 1067 "field '%s' of class '%s' conflicts with method '%s' " |
| 1068 "of super class '%s'", |
| 1069 name.ToCString(), |
| 1070 class_name.ToCString(), |
| 1071 name.ToCString(), |
| 1072 super_class_name.ToCString()); |
| 1073 } |
1057 } | 1074 } |
1058 } | 1075 } |
1059 // Collect interfaces, super interfaces, and super classes of this class. | 1076 // Collect interfaces, super interfaces, and super classes of this class. |
1060 const GrowableObjectArray& interfaces = | 1077 const GrowableObjectArray& interfaces = |
1061 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1078 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
1062 CollectInterfaces(cls, interfaces); | 1079 CollectInterfaces(cls, interfaces); |
1063 // Include superclasses in list of interfaces and super interfaces. | 1080 // Include superclasses in list of interfaces and super interfaces. |
1064 super_class = cls.SuperClass(); | 1081 super_class = cls.SuperClass(); |
1065 while (!super_class.IsNull()) { | 1082 while (!super_class.IsNull()) { |
1066 interfaces.Add(super_class); | 1083 interfaces.Add(super_class); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 const String& super_class_name = String::Handle(super_class.Name()); | 1141 const String& super_class_name = String::Handle(super_class.Name()); |
1125 const Script& script = Script::Handle(cls.script()); | 1142 const Script& script = Script::Handle(cls.script()); |
1126 ReportError(script, function.token_pos(), | 1143 ReportError(script, function.token_pos(), |
1127 "getter '%s' of class '%s' conflicts with " | 1144 "getter '%s' of class '%s' conflicts with " |
1128 "function '%s' of super class '%s'", | 1145 "function '%s' of super class '%s'", |
1129 name.ToCString(), | 1146 name.ToCString(), |
1130 class_name.ToCString(), | 1147 class_name.ToCString(), |
1131 name.ToCString(), | 1148 name.ToCString(), |
1132 super_class_name.ToCString()); | 1149 super_class_name.ToCString()); |
1133 } | 1150 } |
1134 } else if (function.IsSetterFunction()) { | 1151 } else if (!function.IsSetterFunction()) { |
1135 name = Field::NameFromSetter(function_name); | 1152 // A function cannot conflict with a setter, since they cannot |
1136 super_class = FindSuperOwnerOfFunction(cls, name); | 1153 // have the same name. Thus, we do not need to check setters. |
1137 if (!super_class.IsNull()) { | |
1138 const String& class_name = String::Handle(cls.Name()); | |
1139 const String& super_class_name = String::Handle(super_class.Name()); | |
1140 const Script& script = Script::Handle(cls.script()); | |
1141 ReportError(script, function.token_pos(), | |
1142 "setter '%s' of class '%s' conflicts with " | |
1143 "function '%s' of super class '%s'", | |
1144 name.ToCString(), | |
1145 class_name.ToCString(), | |
1146 name.ToCString(), | |
1147 super_class_name.ToCString()); | |
1148 } | |
1149 } else { | |
1150 name = Field::GetterName(function_name); | 1154 name = Field::GetterName(function_name); |
1151 super_class = FindSuperOwnerOfFunction(cls, name); | 1155 super_class = FindSuperOwnerOfFunction(cls, name); |
1152 if (!super_class.IsNull()) { | 1156 if (!super_class.IsNull()) { |
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(script, function.token_pos(), |
1157 "function '%s' of class '%s' conflicts with " | 1161 "function '%s' of class '%s' conflicts with " |
1158 "getter '%s' of super class '%s'", | 1162 "getter '%s' of super class '%s'", |
1159 function_name.ToCString(), | 1163 function_name.ToCString(), |
1160 class_name.ToCString(), | 1164 class_name.ToCString(), |
1161 function_name.ToCString(), | 1165 function_name.ToCString(), |
1162 super_class_name.ToCString()); | 1166 super_class_name.ToCString()); |
1163 } | 1167 } |
1164 name = Field::SetterName(function_name); | |
1165 super_class = FindSuperOwnerOfFunction(cls, name); | |
1166 if (!super_class.IsNull()) { | |
1167 const String& class_name = String::Handle(cls.Name()); | |
1168 const String& super_class_name = String::Handle(super_class.Name()); | |
1169 const Script& script = Script::Handle(cls.script()); | |
1170 ReportError(script, function.token_pos(), | |
1171 "function '%s' of class '%s' conflicts with " | |
1172 "setter '%s' of super class '%s'", | |
1173 function_name.ToCString(), | |
1174 class_name.ToCString(), | |
1175 function_name.ToCString(), | |
1176 super_class_name.ToCString()); | |
1177 } | |
1178 } | 1168 } |
1179 } | 1169 } |
1180 } | 1170 } |
1181 | 1171 |
1182 | 1172 |
1183 void ClassFinalizer::FinalizeClass(const Class& cls) { | 1173 void ClassFinalizer::FinalizeClass(const Class& cls) { |
1184 if (cls.is_finalized()) { | 1174 if (cls.is_finalized()) { |
1185 return; | 1175 return; |
1186 } | 1176 } |
1187 if (FLAG_trace_class_finalization) { | 1177 if (FLAG_trace_class_finalization) { |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 void ClassFinalizer::ReportError(const char* format, ...) { | 1588 void ClassFinalizer::ReportError(const char* format, ...) { |
1599 va_list args; | 1589 va_list args; |
1600 va_start(args, format); | 1590 va_start(args, format); |
1601 const Error& error = Error::Handle( | 1591 const Error& error = Error::Handle( |
1602 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1592 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
1603 va_end(args); | 1593 va_end(args); |
1604 ReportError(error); | 1594 ReportError(error); |
1605 } | 1595 } |
1606 | 1596 |
1607 } // namespace dart | 1597 } // namespace dart |
OLD | NEW |