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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return CreateFunctionTypeMirror(cls, type); | 294 return CreateFunctionTypeMirror(cls, type); |
295 } else { | 295 } else { |
296 // We represent typedefs as non-canonical signature classes. | 296 // We represent typedefs as non-canonical signature classes. |
297 return CreateTypedefMirror(cls, owner_mirror); | 297 return CreateTypedefMirror(cls, owner_mirror); |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0); | 301 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0); |
302 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef()); | 302 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef()); |
303 | 303 |
| 304 // If the class is not generic, the mirror must have a non-null runtime type. |
| 305 // If the class is generic, the mirror will have a null runtime type if it |
| 306 // represents the declaration or a non-null runtime type if it represents an |
| 307 // instantiation. |
| 308 ASSERT(!(cls.NumTypeParameters() == 0) || !type.IsNull()); |
| 309 |
304 const Array& args = Array::Handle(Array::New(5)); | 310 const Array& args = Array::Handle(Array::New(5)); |
305 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); | 311 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
306 args.SetAt(1, type); | 312 args.SetAt(1, type); |
307 // We do not set the names of anonymous mixin applications because the mirrors | 313 // We do not set the names of anonymous mixin applications because the mirrors |
308 // use a different naming convention than the VM (lib.S with lib.M and S&M | 314 // use a different naming convention than the VM (lib.S with lib.M and S&M |
309 // respectively). | 315 // respectively). |
310 if ((cls.mixin() == Type::null()) || cls.is_mixin_typedef()) { | 316 if ((cls.mixin() == Type::null()) || cls.is_mixin_typedef()) { |
311 args.SetAt(2, String::Handle(cls.UserVisibleName())); | 317 args.SetAt(2, String::Handle(cls.UserVisibleName())); |
312 } | 318 } |
313 args.SetAt(3, is_generic); | 319 args.SetAt(3, is_generic); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 518 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
513 const Class& klass = Class::Handle(ref.GetClassReferent()); | 519 const Class& klass = Class::Handle(ref.GetClassReferent()); |
514 return klass.UserVisibleName(); | 520 return klass.UserVisibleName(); |
515 } | 521 } |
516 | 522 |
517 | 523 |
518 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) { | 524 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) { |
519 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 525 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
520 const Class& klass = Class::Handle(ref.GetClassReferent()); | 526 const Class& klass = Class::Handle(ref.GetClassReferent()); |
521 const Library& library = Library::Handle(klass.library()); | 527 const Library& library = Library::Handle(klass.library()); |
522 // TODO(rmacnak): Revisit when we decide what to do about | 528 ASSERT(!library.IsNull()); |
523 // reflectClass(dynamic). | |
524 if (library.IsNull()) { | |
525 return Instance::null(); | |
526 } | |
527 return CreateLibraryMirror(library); | 529 return CreateLibraryMirror(library); |
528 } | 530 } |
529 | 531 |
530 | 532 |
531 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { | 533 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { |
532 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 534 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
533 const Class& klass = Class::Handle(ref.GetClassReferent()); | 535 const Class& klass = Class::Handle(ref.GetClassReferent()); |
534 return klass.super_type(); | 536 return klass.super_type(); |
535 } | 537 } |
536 | 538 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 641 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
640 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 642 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
641 | 643 |
642 Instance& member_mirror = Instance::Handle(); | 644 Instance& member_mirror = Instance::Handle(); |
643 const GrowableObjectArray& member_mirrors = | 645 const GrowableObjectArray& member_mirrors = |
644 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 646 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
645 | 647 |
646 Object& entry = Object::Handle(); | 648 Object& entry = Object::Handle(); |
647 DictionaryIterator entries(library); | 649 DictionaryIterator entries(library); |
648 | 650 |
| 651 AbstractType& type = AbstractType::Handle(); |
| 652 |
649 while (entries.HasNext()) { | 653 while (entries.HasNext()) { |
650 entry = entries.GetNext(); | 654 entry = entries.GetNext(); |
651 if (entry.IsClass()) { | 655 if (entry.IsClass()) { |
652 const Class& klass = Class::Cast(entry); | 656 const Class& klass = Class::Cast(entry); |
653 // We filter out implementation classes like Smi, Mint, Bignum, | 657 // We filter out implementation classes like Smi, Mint, Bignum, |
654 // OneByteString; function signature classes; and dynamic. | 658 // OneByteString; function signature classes; and dynamic. |
655 if (!klass.IsCanonicalSignatureClass() && | 659 if (!klass.IsCanonicalSignatureClass() && |
656 !klass.IsDynamicClass() && | 660 !klass.IsDynamicClass() && |
657 !RawObject::IsImplementationClassId(klass.id())) { | 661 !RawObject::IsImplementationClassId(klass.id())) { |
658 member_mirror = CreateClassMirror(klass, | 662 if (klass.NumTypeParameters() == 0) { |
659 AbstractType::Handle(), | 663 // Include runtime type for non-generics only. |
660 owner_mirror); | 664 type = RawTypeOfClass(klass); |
| 665 } else { |
| 666 type = AbstractType::null(); |
| 667 } |
| 668 member_mirror = CreateClassMirror(klass, type, owner_mirror); |
661 member_mirrors.Add(member_mirror); | 669 member_mirrors.Add(member_mirror); |
662 } | 670 } |
663 } else if (entry.IsField()) { | 671 } else if (entry.IsField()) { |
664 const Field& field = Field::Cast(entry); | 672 const Field& field = Field::Cast(entry); |
665 member_mirror = CreateVariableMirror(field, owner_mirror); | 673 member_mirror = CreateVariableMirror(field, owner_mirror); |
666 member_mirrors.Add(member_mirror); | 674 member_mirrors.Add(member_mirror); |
667 } else if (entry.IsFunction()) { | 675 } else if (entry.IsFunction()) { |
668 const Function& func = Function::Cast(entry); | 676 const Function& func = Function::Cast(entry); |
669 if (func.kind() == RawFunction::kRegularFunction || | 677 if (func.kind() == RawFunction::kRegularFunction || |
670 func.kind() == RawFunction::kGetterFunction || | 678 func.kind() == RawFunction::kGetterFunction || |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 arg_type ^= args.TypeAt(i + num_inherited_args); | 728 arg_type ^= args.TypeAt(i + num_inherited_args); |
721 type_mirror = CreateTypeMirror(arg_type); | 729 type_mirror = CreateTypeMirror(arg_type); |
722 result.SetAt(i, type_mirror); | 730 result.SetAt(i, type_mirror); |
723 } | 731 } |
724 return result.raw(); | 732 return result.raw(); |
725 } | 733 } |
726 | 734 |
727 | 735 |
728 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) { | 736 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) { |
729 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); | 737 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); |
730 return CreateClassMirror(Class::Handle(param.parameterized_class()), | 738 const Class& owner = Class::Handle(param.parameterized_class()); |
| 739 // The owner of a type variable must be a generic class: pass a null runtime |
| 740 // type to get a mirror on the declaration. |
| 741 ASSERT(owner.NumTypeParameters() != 0); |
| 742 return CreateClassMirror(owner, |
731 AbstractType::Handle(), | 743 AbstractType::Handle(), |
732 Instance::null_instance()); | 744 Instance::null_instance()); |
733 } | 745 } |
734 | 746 |
735 | 747 |
736 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { | 748 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { |
737 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); | 749 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); |
738 return param.bound(); | 750 return param.bound(); |
739 } | 751 } |
740 | 752 |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1297 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
1286 const Function& func = Function::Handle(ref.GetFunctionReferent()); | 1298 const Function& func = Function::Handle(ref.GetFunctionReferent()); |
1287 if (func.IsNonImplicitClosureFunction()) { | 1299 if (func.IsNonImplicitClosureFunction()) { |
1288 return CreateMethodMirror(Function::Handle( | 1300 return CreateMethodMirror(Function::Handle( |
1289 func.parent_function()), Object::null_instance()); | 1301 func.parent_function()), Object::null_instance()); |
1290 } | 1302 } |
1291 const Class& owner = Class::Handle(func.Owner()); | 1303 const Class& owner = Class::Handle(func.Owner()); |
1292 if (owner.IsTopLevel()) { | 1304 if (owner.IsTopLevel()) { |
1293 return CreateLibraryMirror(Library::Handle(owner.library())); | 1305 return CreateLibraryMirror(Library::Handle(owner.library())); |
1294 } | 1306 } |
1295 return CreateClassMirror(owner, | 1307 |
1296 AbstractType::Handle(), | 1308 AbstractType& type = AbstractType::Handle(); |
1297 Object::null_instance()); | 1309 if (owner.NumTypeParameters() == 0) { |
| 1310 // Include runtime type for non-generics only. |
| 1311 type = RawTypeOfClass(owner); |
| 1312 } |
| 1313 return CreateClassMirror(owner, type, Object::null_instance()); |
1298 } | 1314 } |
1299 | 1315 |
1300 | 1316 |
1301 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { | 1317 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { |
1302 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); | 1318 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); |
1303 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1319 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
1304 const Function& func = Function::Handle(ref.GetFunctionReferent()); | 1320 const Function& func = Function::Handle(ref.GetFunctionReferent()); |
1305 return CreateParameterMirrorList(func, owner); | 1321 return CreateParameterMirrorList(func, owner); |
1306 } | 1322 } |
1307 | 1323 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 } | 1377 } |
1362 | 1378 |
1363 | 1379 |
1364 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1380 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
1365 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1381 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
1366 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1382 const Field& field = Field::Handle(ref.GetFieldReferent()); |
1367 return field.type(); | 1383 return field.type(); |
1368 } | 1384 } |
1369 | 1385 |
1370 } // namespace dart | 1386 } // namespace dart |
OLD | NEW |