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

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

Issue 11312095: Fix various inheritance bugs (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698