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

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

Issue 11364134: Merge libv1. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Reupload due to error 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 | « runtime/vm/ast.h ('k') | runtime/vm/dart_api_impl.h » ('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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 ASSERT(!parameterized_class.IsNull()); 704 ASSERT(!parameterized_class.IsNull());
705 // The index must reflect the position of this type parameter in the type 705 // The index must reflect the position of this type parameter in the type
706 // arguments vector of its parameterized class. The offset to add is the 706 // arguments vector of its parameterized class. The offset to add is the
707 // number of type arguments in the super type, which is equal to the 707 // number of type arguments in the super type, which is equal to the
708 // difference in number of type arguments and type parameters of the 708 // difference in number of type arguments and type parameters of the
709 // parameterized class. 709 // parameterized class.
710 const intptr_t offset = parameterized_class.NumTypeArguments() - 710 const intptr_t offset = parameterized_class.NumTypeArguments() -
711 parameterized_class.NumTypeParameters(); 711 parameterized_class.NumTypeParameters();
712 type_parameter.set_index(type_parameter.index() + offset); 712 type_parameter.set_index(type_parameter.index() + offset);
713 type_parameter.set_is_finalized(); 713 type_parameter.set_is_finalized();
714 // TODO(regis): We are not able to finalize the bound here without getting
715 // into cycles. Revisit.
714 // We do not canonicalize type parameters. 716 // We do not canonicalize type parameters.
715 return type_parameter.raw(); 717 return type_parameter.raw();
716 } 718 }
717 719
718 // At this point, we can only have a parameterized_type. 720 // At this point, we can only have a parameterized_type.
719 const Type& parameterized_type = Type::Cast(type); 721 const Type& parameterized_type = Type::Cast(type);
720 722
721 if (parameterized_type.IsBeingFinalized()) { 723 if (parameterized_type.IsBeingFinalized()) {
722 // Self reference detected. The type is malformed. 724 // Self reference detected. The type is malformed.
723 FinalizeMalformedType( 725 FinalizeMalformedType(
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 type = FinalizeType(cls, type, kCanonicalize); 948 type = FinalizeType(cls, type, kCanonicalize);
947 // In production mode, a malformed parameter type is mapped to dynamic. 949 // In production mode, a malformed parameter type is mapped to dynamic.
948 if (!FLAG_enable_type_checks && type.IsMalformed()) { 950 if (!FLAG_enable_type_checks && type.IsMalformed()) {
949 type = Type::DynamicType(); 951 type = Type::DynamicType();
950 } 952 }
951 function.SetParameterTypeAt(i, type); 953 function.SetParameterTypeAt(i, type);
952 } 954 }
953 } 955 }
954 956
955 957
958 // Check if an instance field or method of same name exists
959 // in any super class.
956 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, 960 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
957 const String& name) { 961 const String& name) {
958 Class& super_class = Class::Handle(); 962 Class& super_class = Class::Handle();
959 Function& function = Function::Handle(); 963 Function& function = Function::Handle();
960 Field& field = Field::Handle(); 964 Field& field = Field::Handle();
961 super_class = cls.SuperClass(); 965 super_class = cls.SuperClass();
962 while (!super_class.IsNull()) { 966 while (!super_class.IsNull()) {
963 // Check if an instance member of same name exists in any super class.
964 function = super_class.LookupFunction(name); 967 function = super_class.LookupFunction(name);
965 if (!function.IsNull() && !function.is_static()) { 968 if (!function.IsNull() && !function.is_static()) {
966 return super_class.raw(); 969 return super_class.raw();
967 } 970 }
968 field = super_class.LookupField(name); 971 field = super_class.LookupField(name);
969 if (!field.IsNull() && !field.is_static()) { 972 if (!field.IsNull() && !field.is_static()) {
970 return super_class.raw(); 973 return super_class.raw();
971 } 974 }
972 super_class = super_class.SuperClass(); 975 super_class = super_class.SuperClass();
973 } 976 }
974 return Class::null(); 977 return Class::null();
975 } 978 }
976 979
977 980
981 // Check if an instance method of same name exists in any super class.
978 static RawClass* FindSuperOwnerOfFunction(const Class& cls, 982 static RawClass* FindSuperOwnerOfFunction(const Class& cls,
979 const String& name) { 983 const String& name) {
980 Class& super_class = Class::Handle(); 984 Class& super_class = Class::Handle();
981 Function& function = Function::Handle(); 985 Function& function = Function::Handle();
982 super_class = cls.SuperClass(); 986 super_class = cls.SuperClass();
983 while (!super_class.IsNull()) { 987 while (!super_class.IsNull()) {
984 // Check if a function of same name exists in any super class.
985 function = super_class.LookupFunction(name); 988 function = super_class.LookupFunction(name);
986 if (!function.IsNull() && !function.is_static()) { 989 if (!function.IsNull() && !function.is_static()) {
987 return super_class.raw(); 990 return super_class.raw();
988 } 991 }
989 super_class = super_class.SuperClass(); 992 super_class = super_class.SuperClass();
990 } 993 }
991 return Class::null(); 994 return Class::null();
992 } 995 }
993 996
994 997
(...skipping 19 matching lines...) Expand all
1014 } 1017 }
1015 1018
1016 1019
1017 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 1020 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
1018 // 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
1019 // 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
1020 // generating getters and setters. 1023 // generating getters and setters.
1021 // The only compile errors we report are therefore: 1024 // The only compile errors we report are therefore:
1022 // - 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
1023 // class or in a subclass. 1026 // class or in a subclass.
1024 // - a setter having the same name as a method (but not a setter) in a super
1025 // class or in a subclass.
1026 // - 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
1027 // 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.
1028 1029
1029 // Resolve type of fields and check for conflicts in super classes. 1030 // Resolve type of fields and check for conflicts in super classes.
1030 Array& array = Array::Handle(cls.fields()); 1031 Array& array = Array::Handle(cls.fields());
1031 Field& field = Field::Handle(); 1032 Field& field = Field::Handle();
1032 AbstractType& type = AbstractType::Handle(); 1033 AbstractType& type = AbstractType::Handle();
1033 String& name = String::Handle(); 1034 String& name = String::Handle();
1034 Class& super_class = Class::Handle(); 1035 Class& super_class = Class::Handle();
1035 intptr_t num_fields = array.Length(); 1036 intptr_t num_fields = array.Length();
1036 for (intptr_t i = 0; i < num_fields; i++) { 1037 for (intptr_t i = 0; i < num_fields; i++) {
1037 field ^= array.At(i); 1038 field ^= array.At(i);
1038 type = field.type(); 1039 type = field.type();
1039 ResolveType(cls, type, kCanonicalize); 1040 ResolveType(cls, type, kCanonicalize);
1040 type = FinalizeType(cls, type, kCanonicalize); 1041 type = FinalizeType(cls, type, kCanonicalize);
1041 field.set_type(type); 1042 field.set_type(type);
1042 name = field.name(); 1043 name = field.name();
1043 super_class = FindSuperOwnerOfInstanceMember(cls, name); 1044 if (field.is_static()) {
1044 if (!super_class.IsNull()) { 1045 super_class = FindSuperOwnerOfInstanceMember(cls, name);
1045 const String& class_name = String::Handle(cls.Name()); 1046 if (!super_class.IsNull()) {
1046 const String& super_class_name = String::Handle(super_class.Name()); 1047 const String& class_name = String::Handle(cls.Name());
1047 const Script& script = Script::Handle(cls.script()); 1048 const String& super_class_name = String::Handle(super_class.Name());
1048 ReportError(script, field.token_pos(), 1049 const Script& script = Script::Handle(cls.script());
1049 "field '%s' of class '%s' conflicts with instance " 1050 ReportError(script, field.token_pos(),
1050 "member '%s' of super class '%s'", 1051 "static field '%s' of class '%s' conflicts with "
1051 name.ToCString(), 1052 "instance member '%s' of super class '%s'",
1052 class_name.ToCString(), 1053 name.ToCString(),
1053 name.ToCString(), 1054 class_name.ToCString(),
1054 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 }
1055 } 1074 }
1056 } 1075 }
1057 // Collect interfaces, super interfaces, and super classes of this class. 1076 // Collect interfaces, super interfaces, and super classes of this class.
1058 const GrowableObjectArray& interfaces = 1077 const GrowableObjectArray& interfaces =
1059 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1078 GrowableObjectArray::Handle(GrowableObjectArray::New());
1060 CollectInterfaces(cls, interfaces); 1079 CollectInterfaces(cls, interfaces);
1061 // Include superclasses in list of interfaces and super interfaces. 1080 // Include superclasses in list of interfaces and super interfaces.
1062 super_class = cls.SuperClass(); 1081 super_class = cls.SuperClass();
1063 while (!super_class.IsNull()) { 1082 while (!super_class.IsNull()) {
1064 interfaces.Add(super_class); 1083 interfaces.Add(super_class);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 const String& super_class_name = String::Handle(super_class.Name()); 1141 const String& super_class_name = String::Handle(super_class.Name());
1123 const Script& script = Script::Handle(cls.script()); 1142 const Script& script = Script::Handle(cls.script());
1124 ReportError(script, function.token_pos(), 1143 ReportError(script, function.token_pos(),
1125 "getter '%s' of class '%s' conflicts with " 1144 "getter '%s' of class '%s' conflicts with "
1126 "function '%s' of super class '%s'", 1145 "function '%s' of super class '%s'",
1127 name.ToCString(), 1146 name.ToCString(),
1128 class_name.ToCString(), 1147 class_name.ToCString(),
1129 name.ToCString(), 1148 name.ToCString(),
1130 super_class_name.ToCString()); 1149 super_class_name.ToCString());
1131 } 1150 }
1132 } else if (function.IsSetterFunction()) { 1151 } else if (!function.IsSetterFunction()) {
1133 name = Field::NameFromSetter(function_name); 1152 // A function cannot conflict with a setter, since they cannot
1134 super_class = FindSuperOwnerOfFunction(cls, name); 1153 // have the same name. Thus, we do not need to check setters.
1135 if (!super_class.IsNull()) {
1136 const String& class_name = String::Handle(cls.Name());
1137 const String& super_class_name = String::Handle(super_class.Name());
1138 const Script& script = Script::Handle(cls.script());
1139 ReportError(script, function.token_pos(),
1140 "setter '%s' of class '%s' conflicts with "
1141 "function '%s' of super class '%s'",
1142 name.ToCString(),
1143 class_name.ToCString(),
1144 name.ToCString(),
1145 super_class_name.ToCString());
1146 }
1147 } else {
1148 name = Field::GetterName(function_name); 1154 name = Field::GetterName(function_name);
1149 super_class = FindSuperOwnerOfFunction(cls, name); 1155 super_class = FindSuperOwnerOfFunction(cls, name);
1150 if (!super_class.IsNull()) { 1156 if (!super_class.IsNull()) {
1151 const String& class_name = String::Handle(cls.Name()); 1157 const String& class_name = String::Handle(cls.Name());
1152 const String& super_class_name = String::Handle(super_class.Name()); 1158 const String& super_class_name = String::Handle(super_class.Name());
1153 const Script& script = Script::Handle(cls.script()); 1159 const Script& script = Script::Handle(cls.script());
1154 ReportError(script, function.token_pos(), 1160 ReportError(script, function.token_pos(),
1155 "function '%s' of class '%s' conflicts with " 1161 "function '%s' of class '%s' conflicts with "
1156 "getter '%s' of super class '%s'", 1162 "getter '%s' of super class '%s'",
1157 function_name.ToCString(), 1163 function_name.ToCString(),
1158 class_name.ToCString(), 1164 class_name.ToCString(),
1159 function_name.ToCString(), 1165 function_name.ToCString(),
1160 super_class_name.ToCString()); 1166 super_class_name.ToCString());
1161 } 1167 }
1162 name = Field::SetterName(function_name);
1163 super_class = FindSuperOwnerOfFunction(cls, name);
1164 if (!super_class.IsNull()) {
1165 const String& class_name = String::Handle(cls.Name());
1166 const String& super_class_name = String::Handle(super_class.Name());
1167 const Script& script = Script::Handle(cls.script());
1168 ReportError(script, function.token_pos(),
1169 "function '%s' of class '%s' conflicts with "
1170 "setter '%s' of super class '%s'",
1171 function_name.ToCString(),
1172 class_name.ToCString(),
1173 function_name.ToCString(),
1174 super_class_name.ToCString());
1175 }
1176 } 1168 }
1177 } 1169 }
1178 } 1170 }
1179 1171
1180 1172
1181 void ClassFinalizer::FinalizeClass(const Class& cls) { 1173 void ClassFinalizer::FinalizeClass(const Class& cls) {
1182 if (cls.is_finalized()) { 1174 if (cls.is_finalized()) {
1183 return; 1175 return;
1184 } 1176 }
1185 if (FLAG_trace_class_finalization) { 1177 if (FLAG_trace_class_finalization) {
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 void ClassFinalizer::ReportError(const char* format, ...) { 1588 void ClassFinalizer::ReportError(const char* format, ...) {
1597 va_list args; 1589 va_list args;
1598 va_start(args, format); 1590 va_start(args, format);
1599 const Error& error = Error::Handle( 1591 const Error& error = Error::Handle(
1600 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1592 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1601 va_end(args); 1593 va_end(args);
1602 ReportError(error); 1594 ReportError(error);
1603 } 1595 }
1604 1596
1605 } // namespace dart 1597 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/dart_api_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698