| 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 |