Chromium Code Reviews| 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 "lib/invocation_mirror.h" | 5 #include "lib/invocation_mirror.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 const Object& result = Object::Handle( | 22 const Object& result = Object::Handle( |
| 23 DartLibraryCalls::InstanceCreate(mirrors_lib, | 23 DartLibraryCalls::InstanceCreate(mirrors_lib, |
| 24 mirror_class_name, | 24 mirror_class_name, |
| 25 constructor_name, | 25 constructor_name, |
| 26 constructor_arguments)); | 26 constructor_arguments)); |
| 27 ASSERT(!result.IsError()); | 27 ASSERT(!result.IsError()); |
| 28 return Instance::Cast(result).raw(); | 28 return Instance::Cast(result).raw(); |
| 29 } | 29 } |
| 30 | 30 |
| 31 | 31 |
| 32 // Note a "raw type" is not the same as a RawType. | |
| 33 static RawAbstractType* RawTypeOfClass(const Class& cls) { | |
|
rmacnak
2013/09/11 21:10:21
Moved to a method on Class because it is also need
| |
| 34 Type& type = Type::Handle(Type::New(cls, | |
| 35 Object::null_abstract_type_arguments(), | |
| 36 Scanner::kDummyTokenIndex)); | |
| 37 return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize); | |
| 38 } | |
| 39 | |
| 40 | |
| 41 static void ThrowMirroredCompilationError(const String& message) { | 32 static void ThrowMirroredCompilationError(const String& message) { |
| 42 Array& args = Array::Handle(Array::New(1)); | 33 Array& args = Array::Handle(Array::New(1)); |
| 43 args.SetAt(0, message); | 34 args.SetAt(0, message); |
| 44 | 35 |
| 45 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); | 36 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); |
| 46 UNREACHABLE(); | 37 UNREACHABLE(); |
| 47 } | 38 } |
| 48 | 39 |
| 49 | 40 |
| 50 static void ThrowInvokeError(const Error& error) { | 41 static void ThrowInvokeError(const Error& error) { |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 entry = entries.GetNext(); | 647 entry = entries.GetNext(); |
| 657 if (entry.IsClass()) { | 648 if (entry.IsClass()) { |
| 658 const Class& klass = Class::Cast(entry); | 649 const Class& klass = Class::Cast(entry); |
| 659 // We filter out implementation classes like Smi, Mint, Bignum, | 650 // We filter out implementation classes like Smi, Mint, Bignum, |
| 660 // OneByteString; function signature classes; and dynamic. | 651 // OneByteString; function signature classes; and dynamic. |
| 661 if (!klass.IsCanonicalSignatureClass() && | 652 if (!klass.IsCanonicalSignatureClass() && |
| 662 !klass.IsDynamicClass() && | 653 !klass.IsDynamicClass() && |
| 663 !RawObject::IsImplementationClassId(klass.id())) { | 654 !RawObject::IsImplementationClassId(klass.id())) { |
| 664 if (klass.NumTypeParameters() == 0) { | 655 if (klass.NumTypeParameters() == 0) { |
| 665 // Include runtime type for non-generics only. | 656 // Include runtime type for non-generics only. |
| 666 type = RawTypeOfClass(klass); | 657 type = klass.BasicType(); |
| 667 } else { | 658 } else { |
| 668 type = AbstractType::null(); | 659 type = AbstractType::null(); |
| 669 } | 660 } |
| 670 member_mirror = CreateClassMirror(klass, type, owner_mirror); | 661 member_mirror = CreateClassMirror(klass, type, owner_mirror); |
| 671 member_mirrors.Add(member_mirror); | 662 member_mirrors.Add(member_mirror); |
| 672 } | 663 } |
| 673 } else if (entry.IsField()) { | 664 } else if (entry.IsField()) { |
| 674 const Field& field = Field::Cast(entry); | 665 const Field& field = Field::Cast(entry); |
| 675 member_mirror = CreateVariableMirror(field, owner_mirror); | 666 member_mirror = CreateVariableMirror(field, owner_mirror); |
| 676 member_mirrors.Add(member_mirror); | 667 member_mirrors.Add(member_mirror); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 951 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 961 | 952 |
| 962 const Function& function = Function::Handle( | 953 const Function& function = Function::Handle( |
| 963 klass.LookupStaticFunctionAllowPrivate(function_name)); | 954 klass.LookupStaticFunctionAllowPrivate(function_name)); |
| 964 | 955 |
| 965 | 956 |
| 966 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 957 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 967 if (function.IsNull() || | 958 if (function.IsNull() || |
| 968 !function.AreValidArguments(args_descriptor, NULL) || | 959 !function.AreValidArguments(args_descriptor, NULL) || |
| 969 !function.is_visible()) { | 960 !function.is_visible()) { |
| 970 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 961 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()), |
| 971 function_name, | 962 function_name, |
| 972 function, | 963 function, |
| 973 InvocationMirror::kStatic, | 964 InvocationMirror::kStatic, |
| 974 InvocationMirror::kMethod); | 965 InvocationMirror::kMethod); |
| 975 UNREACHABLE(); | 966 UNREACHABLE(); |
| 976 } | 967 } |
| 977 | 968 |
| 978 Object& result = Object::Handle( | 969 Object& result = Object::Handle( |
| 979 DartEntry::InvokeFunction(function, args, args_descriptor_array)); | 970 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 980 if (result.IsError()) { | 971 if (result.IsError()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 995 | 986 |
| 996 // Note static fields do not have implicit getters. | 987 // Note static fields do not have implicit getters. |
| 997 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | 988 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); |
| 998 if (field.IsNull() || FieldIsUninitialized(field)) { | 989 if (field.IsNull() || FieldIsUninitialized(field)) { |
| 999 const String& internal_getter_name = String::Handle( | 990 const String& internal_getter_name = String::Handle( |
| 1000 Field::GetterName(getter_name)); | 991 Field::GetterName(getter_name)); |
| 1001 const Function& getter = Function::Handle( | 992 const Function& getter = Function::Handle( |
| 1002 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | 993 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); |
| 1003 | 994 |
| 1004 if (getter.IsNull() || !getter.is_visible()) { | 995 if (getter.IsNull() || !getter.is_visible()) { |
| 1005 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 996 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()), |
| 1006 getter_name, | 997 getter_name, |
| 1007 getter, | 998 getter, |
| 1008 InvocationMirror::kStatic, | 999 InvocationMirror::kStatic, |
| 1009 InvocationMirror::kGetter); | 1000 InvocationMirror::kGetter); |
| 1010 UNREACHABLE(); | 1001 UNREACHABLE(); |
| 1011 } | 1002 } |
| 1012 | 1003 |
| 1013 // Invoke the getter and return the result. | 1004 // Invoke the getter and return the result. |
| 1014 Object& result = Object::Handle( | 1005 Object& result = Object::Handle( |
| 1015 DartEntry::InvokeFunction(getter, Object::empty_array())); | 1006 DartEntry::InvokeFunction(getter, Object::empty_array())); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1034 | 1025 |
| 1035 // Check for real fields and user-defined setters. | 1026 // Check for real fields and user-defined setters. |
| 1036 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1027 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1037 if (field.IsNull()) { | 1028 if (field.IsNull()) { |
| 1038 const String& internal_setter_name = String::Handle( | 1029 const String& internal_setter_name = String::Handle( |
| 1039 Field::SetterName(setter_name)); | 1030 Field::SetterName(setter_name)); |
| 1040 const Function& setter = Function::Handle( | 1031 const Function& setter = Function::Handle( |
| 1041 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | 1032 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); |
| 1042 | 1033 |
| 1043 if (setter.IsNull() || !setter.is_visible()) { | 1034 if (setter.IsNull() || !setter.is_visible()) { |
| 1044 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1035 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()), |
| 1045 setter_name, | 1036 setter_name, |
| 1046 setter, | 1037 setter, |
| 1047 InvocationMirror::kStatic, | 1038 InvocationMirror::kStatic, |
| 1048 InvocationMirror::kSetter); | 1039 InvocationMirror::kSetter); |
| 1049 UNREACHABLE(); | 1040 UNREACHABLE(); |
| 1050 } | 1041 } |
| 1051 | 1042 |
| 1052 // Invoke the setter and return the result. | 1043 // Invoke the setter and return the result. |
| 1053 const int kNumArgs = 1; | 1044 const int kNumArgs = 1; |
| 1054 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1045 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1070 setter_name.ToCString())); | 1061 setter_name.ToCString())); |
| 1071 ThrowMirroredCompilationError(message); | 1062 ThrowMirroredCompilationError(message); |
| 1072 UNREACHABLE(); | 1063 UNREACHABLE(); |
| 1073 } | 1064 } |
| 1074 | 1065 |
| 1075 field.set_value(value); | 1066 field.set_value(value); |
| 1076 return value.raw(); | 1067 return value.raw(); |
| 1077 } | 1068 } |
| 1078 | 1069 |
| 1079 | 1070 |
| 1080 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) { | 1071 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
| 1081 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1072 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1082 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1073 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1074 GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1)); | |
| 1083 GET_NON_NULL_NATIVE_ARGUMENT( | 1075 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1084 String, constructor_name, arguments->NativeArgAt(1)); | 1076 String, constructor_name, arguments->NativeArgAt(2)); |
| 1085 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2)); | 1077 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(3)); |
| 1086 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3)); | 1078 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
| 1087 | 1079 |
| 1088 // By convention, the static function implementing a named constructor 'C' | 1080 // By convention, the static function implementing a named constructor 'C' |
| 1089 // for class 'A' is labeled 'A.C', and the static function implementing the | 1081 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 1090 // unnamed constructor for class 'A' is labeled 'A.'. | 1082 // unnamed constructor for class 'A' is labeled 'A.'. |
| 1091 // This convention prevents users from explicitly calling constructors. | 1083 // This convention prevents users from explicitly calling constructors. |
| 1092 const String& klass_name = String::Handle(klass.Name()); | 1084 const String& klass_name = String::Handle(klass.Name()); |
| 1093 String& internal_constructor_name = | 1085 String& internal_constructor_name = |
| 1094 String::Handle(String::Concat(klass_name, Symbols::Dot())); | 1086 String::Handle(String::Concat(klass_name, Symbols::Dot())); |
| 1095 if (!constructor_name.IsNull()) { | 1087 if (!constructor_name.IsNull()) { |
| 1096 internal_constructor_name = | 1088 internal_constructor_name = |
| 1097 String::Concat(internal_constructor_name, constructor_name); | 1089 String::Concat(internal_constructor_name, constructor_name); |
| 1098 } | 1090 } |
| 1099 | 1091 |
| 1100 Function& lookup_constructor = Function::Handle( | 1092 Function& lookup_constructor = Function::Handle( |
| 1101 klass.LookupFunctionAllowPrivate(internal_constructor_name)); | 1093 klass.LookupFunctionAllowPrivate(internal_constructor_name)); |
| 1102 | 1094 |
| 1103 if (lookup_constructor.IsNull() || | 1095 if (lookup_constructor.IsNull() || |
| 1104 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || | 1096 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || |
| 1105 !lookup_constructor.is_visible()) { | 1097 !lookup_constructor.is_visible()) { |
| 1106 // Pretend we didn't find the constructor at all when the arity is wrong | 1098 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1107 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1099 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1108 lookup_constructor = Function::null(); | 1100 lookup_constructor = Function::null(); |
| 1109 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1101 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()), |
| 1110 internal_constructor_name, | 1102 internal_constructor_name, |
| 1111 lookup_constructor, | 1103 lookup_constructor, |
| 1112 InvocationMirror::kConstructor, | 1104 InvocationMirror::kConstructor, |
| 1113 InvocationMirror::kMethod); | 1105 InvocationMirror::kMethod); |
| 1114 UNREACHABLE(); | 1106 UNREACHABLE(); |
| 1115 } | 1107 } |
| 1116 | 1108 |
| 1117 Class& redirected_klass = Class::Handle(klass.raw()); | 1109 Class& redirected_klass = Class::Handle(klass.raw()); |
| 1118 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); | 1110 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); |
| 1119 if (lookup_constructor.IsRedirectingFactory()) { | 1111 if (lookup_constructor.IsRedirectingFactory()) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1140 const Array& args_descriptor_array = | 1132 const Array& args_descriptor_array = |
| 1141 Array::Handle(ArgumentsDescriptor::New(args.Length(), | 1133 Array::Handle(ArgumentsDescriptor::New(args.Length(), |
| 1142 arg_names)); | 1134 arg_names)); |
| 1143 | 1135 |
| 1144 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1136 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1145 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || | 1137 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || |
| 1146 !redirected_constructor.is_visible()) { | 1138 !redirected_constructor.is_visible()) { |
| 1147 // Pretend we didn't find the constructor at all when the arity is wrong | 1139 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1148 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1140 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1149 redirected_constructor = Function::null(); | 1141 redirected_constructor = Function::null(); |
| 1150 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1142 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()), |
| 1151 internal_constructor_name, | 1143 internal_constructor_name, |
| 1152 redirected_constructor, | 1144 redirected_constructor, |
| 1153 InvocationMirror::kConstructor, | 1145 InvocationMirror::kConstructor, |
| 1154 InvocationMirror::kMethod); | 1146 InvocationMirror::kMethod); |
| 1155 UNREACHABLE(); | 1147 UNREACHABLE(); |
| 1156 } | 1148 } |
| 1157 | 1149 |
| 1150 if (type.IsNull()) { | |
| 1151 // If the ClassMirror is on the declaration of a generic class. | |
| 1152 type ^= klass.BasicType(); | |
| 1153 } | |
| 1154 const AbstractTypeArguments& type_arguments = | |
| 1155 AbstractTypeArguments::Handle(type.arguments()); | |
| 1156 | |
| 1158 Instance& new_object = Instance::Handle(); | 1157 Instance& new_object = Instance::Handle(); |
| 1159 if (redirected_constructor.IsConstructor()) { | 1158 if (redirected_constructor.IsConstructor()) { |
| 1160 // Constructors get the uninitialized object and a constructor phase. Note | 1159 // Constructors get the uninitialized object and a constructor phase. Note |
| 1161 // we have delayed allocation until after the function type and argument | 1160 // we have delayed allocation until after the function type and argument |
| 1162 // matching checks. | 1161 // matching checks. |
| 1163 new_object = Instance::New(redirected_klass); | 1162 new_object = Instance::New(redirected_klass); |
| 1163 if (!type_arguments.IsNull()) { | |
| 1164 // The type arguments will be null if the class has no type parameters, in | |
| 1165 // which case the following call would fail because there is no slot | |
| 1166 // reserved in the object for the type vector. | |
| 1167 new_object.SetTypeArguments(type_arguments); | |
|
regis
2013/09/11 21:37:40
Who is checking that this type_argument vector has
| |
| 1168 } | |
| 1164 args.SetAt(0, new_object); | 1169 args.SetAt(0, new_object); |
| 1165 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 1170 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 1166 } else { | 1171 } else { |
| 1167 // Factories get type arguments. | 1172 // Factories get type arguments. |
| 1168 // TODO(12921): Should we allow the user to specify type arguments? Use type | 1173 args.SetAt(0, type_arguments); |
| 1169 // arguments from the mirror? | |
| 1170 args.SetAt(0, Object::null_abstract_type_arguments()); | |
| 1171 } | 1174 } |
| 1172 | 1175 |
| 1173 // Invoke the constructor and return the new object. | 1176 // Invoke the constructor and return the new object. |
| 1174 const Object& result = | 1177 const Object& result = |
| 1175 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, | 1178 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, |
| 1176 args, | 1179 args, |
| 1177 args_descriptor_array)); | 1180 args_descriptor_array)); |
| 1178 if (result.IsError()) { | 1181 if (result.IsError()) { |
| 1179 return result.raw(); | 1182 return result.raw(); |
| 1180 } | 1183 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 func.parent_function()), Object::null_instance()); | 1346 func.parent_function()), Object::null_instance()); |
| 1344 } | 1347 } |
| 1345 const Class& owner = Class::Handle(func.Owner()); | 1348 const Class& owner = Class::Handle(func.Owner()); |
| 1346 if (owner.IsTopLevel()) { | 1349 if (owner.IsTopLevel()) { |
| 1347 return CreateLibraryMirror(Library::Handle(owner.library())); | 1350 return CreateLibraryMirror(Library::Handle(owner.library())); |
| 1348 } | 1351 } |
| 1349 | 1352 |
| 1350 AbstractType& type = AbstractType::Handle(); | 1353 AbstractType& type = AbstractType::Handle(); |
| 1351 if (owner.NumTypeParameters() == 0) { | 1354 if (owner.NumTypeParameters() == 0) { |
| 1352 // Include runtime type for non-generics only. | 1355 // Include runtime type for non-generics only. |
| 1353 type = RawTypeOfClass(owner); | 1356 type = owner.BasicType(); |
| 1354 } | 1357 } |
| 1355 return CreateClassMirror(owner, type, Object::null_instance()); | 1358 return CreateClassMirror(owner, type, Object::null_instance()); |
| 1356 } | 1359 } |
| 1357 | 1360 |
| 1358 | 1361 |
| 1359 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { | 1362 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { |
| 1360 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); | 1363 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); |
| 1361 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1364 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1362 const Function& func = Function::Handle(ref.GetFunctionReferent()); | 1365 const Function& func = Function::Handle(ref.GetFunctionReferent()); |
| 1363 return CreateParameterMirrorList(func, owner); | 1366 return CreateParameterMirrorList(func, owner); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 } | 1422 } |
| 1420 | 1423 |
| 1421 | 1424 |
| 1422 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1425 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1423 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1426 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1424 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1427 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1425 return field.type(); | 1428 return field.type(); |
| 1426 } | 1429 } |
| 1427 | 1430 |
| 1428 } // namespace dart | 1431 } // namespace dart |
| OLD | NEW |