| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 ReportError(Error::Handle(), // No previous error. | 1065 ReportError(Error::Handle(), // No previous error. |
| 1066 script, field.token_pos(), | 1066 script, field.token_pos(), |
| 1067 "field '%s' of class '%s' conflicts with method '%s' " | 1067 "field '%s' of class '%s' conflicts with method '%s' " |
| 1068 "of super class '%s'", | 1068 "of super class '%s'", |
| 1069 name.ToCString(), | 1069 name.ToCString(), |
| 1070 class_name.ToCString(), | 1070 class_name.ToCString(), |
| 1071 name.ToCString(), | 1071 name.ToCString(), |
| 1072 super_class_name.ToCString()); | 1072 super_class_name.ToCString()); |
| 1073 } | 1073 } |
| 1074 } | 1074 } |
| 1075 if ((FLAG_enable_type_checks || FLAG_error_on_malformed_type) && | 1075 if (field.is_static() && (field.is_const() || field.is_final()) && |
| 1076 field.is_static() && field.is_const() && | |
| 1077 (field.value() != Object::null()) && | 1076 (field.value() != Object::null()) && |
| 1078 (field.value() != Object::sentinel().raw())) { | 1077 (field.value() != Object::sentinel().raw())) { |
| 1079 // The parser does not preset the value if the type is a type parameter or | 1078 // The parser does not preset the value if the type is a type parameter or |
| 1080 // is parameterized unless the value is null. | 1079 // is parameterized unless the value is null. |
| 1081 Error& malformed_error = Error::Handle(); | 1080 Error& malformed_error = Error::Handle(); |
| 1082 if (type.IsMalformed()) { | 1081 if (type.IsMalformed()) { |
| 1083 malformed_error = type.malformed_error(); | 1082 malformed_error = type.malformed_error(); |
| 1084 } else { | 1083 } else { |
| 1085 ASSERT(type.IsInstantiated()); | 1084 ASSERT(type.IsInstantiated()); |
| 1086 } | 1085 } |
| 1087 const Instance& const_value = Instance::Handle(field.value()); | 1086 const Instance& const_value = Instance::Handle(field.value()); |
| 1088 if (!malformed_error.IsNull() || | 1087 if (!malformed_error.IsNull() || |
| 1089 (!type.IsDynamicType() && | 1088 (!type.IsDynamicType() && |
| 1090 !const_value.IsInstanceOf(type, | 1089 !const_value.IsInstanceOf(type, |
| 1091 AbstractTypeArguments::Handle(), | 1090 AbstractTypeArguments::Handle(), |
| 1092 &malformed_error))) { | 1091 &malformed_error))) { |
| 1093 const AbstractType& const_value_type = AbstractType::Handle( | 1092 if (FLAG_error_on_malformed_type) { |
| 1094 const_value.GetType()); | 1093 const AbstractType& const_value_type = AbstractType::Handle( |
| 1095 const String& const_value_type_name = String::Handle( | 1094 const_value.GetType()); |
| 1096 const_value_type.UserVisibleName()); | 1095 const String& const_value_type_name = String::Handle( |
| 1097 const String& type_name = String::Handle(type.UserVisibleName()); | 1096 const_value_type.UserVisibleName()); |
| 1098 const Script& script = Script::Handle(cls.script()); | 1097 const String& type_name = String::Handle(type.UserVisibleName()); |
| 1099 ReportError(malformed_error, script, field.token_pos(), | 1098 const Script& script = Script::Handle(cls.script()); |
| 1100 "error initializing const field '%s': type '%s' is not a " | 1099 ReportError(malformed_error, script, field.token_pos(), |
| 1101 "subtype of type '%s'", | 1100 "error initializing static %s field '%s': " |
| 1102 name.ToCString(), | 1101 "type '%s' is not a subtype of type '%s'", |
| 1103 const_value_type_name.ToCString(), | 1102 field.is_const() ? "const" : "final", |
| 1104 type_name.ToCString()); | 1103 name.ToCString(), |
| 1104 const_value_type_name.ToCString(), |
| 1105 type_name.ToCString()); |
| 1106 } else { |
| 1107 // Do not report an error yet, even in checked mode, since the field |
| 1108 // may not actually be used. |
| 1109 // Also, we may be generating a snapshot in production mode that will |
| 1110 // later be executed in checked mode, in which case an error needs to |
| 1111 // be reported, should the field be accessed. |
| 1112 // Therefore, we undo the optimization performed by the parser, i.e. |
| 1113 // we create an implicit static final getter and reset the field value |
| 1114 // to the sentinel value. |
| 1115 const String& getter_name = String::Handle(Field::GetterSymbol(name)); |
| 1116 const Function& getter = Function::Handle( |
| 1117 Function::New(getter_name, |
| 1118 RawFunction::kImplicitStaticFinalGetter, |
| 1119 /* is_static = */ true, |
| 1120 /* is_const = */ field.is_const(), |
| 1121 /* is_abstract = */ false, |
| 1122 /* is_external = */ false, |
| 1123 cls, |
| 1124 field.token_pos())); |
| 1125 getter.set_result_type(type); |
| 1126 cls.AddFunction(getter); |
| 1127 field.set_value(Instance::Handle(Object::sentinel().raw())); |
| 1128 } |
| 1105 } | 1129 } |
| 1106 } | 1130 } |
| 1107 } | 1131 } |
| 1108 // Collect interfaces, super interfaces, and super classes of this class. | 1132 // Collect interfaces, super interfaces, and super classes of this class. |
| 1109 const GrowableObjectArray& interfaces = | 1133 const GrowableObjectArray& interfaces = |
| 1110 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1134 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1111 CollectInterfaces(cls, interfaces); | 1135 CollectInterfaces(cls, interfaces); |
| 1112 // Include superclasses in list of interfaces and super interfaces. | 1136 // Include superclasses in list of interfaces and super interfaces. |
| 1113 super_class = cls.SuperClass(); | 1137 super_class = cls.SuperClass(); |
| 1114 while (!super_class.IsNull()) { | 1138 while (!super_class.IsNull()) { |
| (...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2219 expected_name ^= String::New("_offset"); | 2243 expected_name ^= String::New("_offset"); |
| 2220 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2244 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2221 field ^= fields_array.At(2); | 2245 field ^= fields_array.At(2); |
| 2222 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2246 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2223 name ^= field.name(); | 2247 name ^= field.name(); |
| 2224 ASSERT(name.Equals("length")); | 2248 ASSERT(name.Equals("length")); |
| 2225 #endif | 2249 #endif |
| 2226 } | 2250 } |
| 2227 | 2251 |
| 2228 } // namespace dart | 2252 } // namespace dart |
| OLD | NEW |