| Index: runtime/lib/mirrors.cc
|
| diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
|
| index 874915f014d0e29471272f1eac0dc59dd4f5c090..437beb0f7bbc4e515a16157c42c26fa6f3aa5f33 100644
|
| --- a/runtime/lib/mirrors.cc
|
| +++ b/runtime/lib/mirrors.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "lib/invocation_mirror.h"
|
| #include "vm/bootstrap_natives.h"
|
| +#include "vm/class_finalizer.h"
|
| #include "vm/dart_entry.h"
|
| #include "vm/exceptions.h"
|
| #include "vm/object_store.h"
|
| @@ -98,19 +99,20 @@ static RawInstance* CreateTypeVariableList(const Class& cls) {
|
| }
|
|
|
|
|
| -static RawInstance* CreateTypedefMirror(const Class& cls,
|
| +static RawInstance* CreateTypedefMirror(const AbstractType& type,
|
| const Instance& owner_mirror) {
|
| + const Class& cls = Class::Handle(type.type_class());
|
| const Array& args = Array::Handle(Array::New(3));
|
| - args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
|
| + args.SetAt(0, MirrorReference::Handle(MirrorReference::New(type)));
|
| args.SetAt(1, String::Handle(cls.UserVisibleName()));
|
| args.SetAt(2, owner_mirror);
|
| return CreateMirror(Symbols::_LocalTypedefMirrorImpl(), args);
|
| }
|
|
|
|
|
| -static RawInstance* CreateFunctionTypeMirror(const Class& cls) {
|
| +static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
|
| const Array& args = Array::Handle(Array::New(1));
|
| - args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
|
| + args.SetAt(0, MirrorReference::Handle(MirrorReference::New(type)));
|
| return CreateMirror(Symbols::_LocalFunctionTypeMirrorImpl(), args);
|
| }
|
|
|
| @@ -154,24 +156,41 @@ static RawInstance* CreateVariableMirror(const Field& field,
|
| }
|
|
|
|
|
| -static RawInstance* CreateClassMirror(const Class& cls,
|
| +static RawInstance* CreateClassMirror(const AbstractType& type,
|
| const Instance& owner_mirror) {
|
| + const Class& cls = Class::Handle(type.type_class());
|
| if (cls.IsSignatureClass()) {
|
| if (cls.IsCanonicalSignatureClass()) {
|
| // We represent function types as canonical signature classes.
|
| - return CreateFunctionTypeMirror(cls);
|
| + return CreateFunctionTypeMirror(type);
|
| } else {
|
| // We represent typedefs as non-canonical signature classes.
|
| - return CreateTypedefMirror(cls, owner_mirror);
|
| + return CreateTypedefMirror(type, owner_mirror);
|
| }
|
| }
|
|
|
| const Array& args = Array::Handle(Array::New(2));
|
| - args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
|
| + args.SetAt(0, MirrorReference::Handle(MirrorReference::New(type)));
|
| args.SetAt(1, String::Handle(cls.UserVisibleName()));
|
| return CreateMirror(Symbols::_LocalClassMirrorImpl(), args);
|
| }
|
|
|
| +// Note a "raw type" is not the same as a RawType.
|
| +static RawAbstractType* RawTypeOfClass(const Class& klass) {
|
| + AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
|
| + Type& type =
|
| + Type::Handle(Type::New(klass, type_arguments, Scanner::kDummyTokenIndex));
|
| + return ClassFinalizer::FinalizeType(klass,
|
| + type,
|
| + ClassFinalizer::kCanonicalize);
|
| +}
|
| +
|
| +static RawInstance* CreateGenericClassMirror(const Class& klass,
|
| + const Instance& owner_mirror) {
|
| + return CreateClassMirror(AbstractType::Handle(RawTypeOfClass(klass)),
|
| + owner_mirror);
|
| +}
|
| +
|
|
|
| static RawInstance* CreateLibraryMirror(const Library& lib) {
|
| const Array& args = Array::Handle(Array::New(3));
|
| @@ -201,7 +220,7 @@ static RawInstance* CreateTypeMirror(const AbstractType& type) {
|
| // TODO(mlippautz): Create once in the VM isolate and retrieve from there.
|
| return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args);
|
| }
|
| - return CreateClassMirror(cls, Object::null_instance());
|
| + return CreateClassMirror(type, Object::null_instance());
|
| } else if (type.IsTypeParameter()) {
|
| return CreateTypeVariableMirror(TypeParameter::Cast(type),
|
| Object::null_instance());
|
| @@ -258,8 +277,7 @@ DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) {
|
|
|
| DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
|
| - const Class& cls = Class::Handle(type.type_class());
|
| - return CreateClassMirror(cls, Object::null_instance());
|
| + return CreateClassMirror(type, Object::null_instance());
|
| }
|
|
|
|
|
| @@ -295,14 +313,15 @@ DEFINE_NATIVE_ENTRY(MirrorReference_equals, 2) {
|
| DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) {
|
| const MirrorReference& decl_ref =
|
| MirrorReference::CheckedHandle(arguments->NativeArgAt(0));
|
| - const Object& decl = Object::Handle(decl_ref.referent());
|
| + Object& decl = Object::Handle(decl_ref.referent());
|
|
|
| Class& klass = Class::Handle();
|
| Library& library = Library::Handle();
|
|
|
| - if (decl.IsClass()) {
|
| - klass ^= decl.raw();
|
| + if (decl.IsAbstractType() || decl.IsType()) {
|
| + klass = AbstractType::Cast(decl).type_class();
|
| library = klass.library();
|
| + decl = klass.raw();
|
| } else if (decl.IsFunction()) {
|
| klass = Function::Cast(decl).origin();
|
| library = klass.library();
|
| @@ -325,16 +344,20 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) {
|
|
|
| DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& cls = Class::Handle(ref.GetClassReferent());
|
| - const Function& func = Function::Handle(cls.signature_function());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| + const Function& func = Function::Handle(klass.signature_function());
|
| return CreateParameterMirrorList(func);
|
| }
|
|
|
|
|
| DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& cls = Class::Handle(ref.GetClassReferent());
|
| - const Function& func = Function::Handle(cls.signature_function());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| + const Function& func = Function::Handle(klass.signature_function());
|
| const AbstractType& return_type = AbstractType::Handle(func.result_type());
|
| return CreateTypeMirror(return_type);
|
| }
|
| @@ -354,14 +377,18 @@ static bool FieldIsUninitialized(const Field& field) {
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| return klass.UserVisibleName();
|
| }
|
|
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| const Library& library = Library::Handle(klass.library());
|
| // TODO(rmacnak): Revisit when we decide what to do about
|
| // reflectClass(dynamic).
|
| @@ -374,14 +401,18 @@ DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) {
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| return klass.super_type();
|
| }
|
|
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
|
|
| const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
|
| if (!error.IsNull()) {
|
| @@ -397,7 +428,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_members, 2) {
|
| owner_mirror,
|
| arguments->NativeArgAt(0));
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
|
|
| const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
|
| if (!error.IsNull()) {
|
| @@ -447,7 +480,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_constructors, 2) {
|
| owner_mirror,
|
| arguments->NativeArgAt(0));
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
|
|
| const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
|
| if (!error.IsNull()) {
|
| @@ -499,7 +534,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
|
| // The various implementations of public classes don't always have the
|
| // expected superinterfaces or other properties, so we filter them out.
|
| if (!RawObject::IsImplementationClassId(klass.id())) {
|
| - member_mirror = CreateClassMirror(klass, owner_mirror);
|
| + member_mirror = CreateGenericClassMirror(klass, owner_mirror);
|
| member_mirrors.Add(member_mirror);
|
| }
|
| }
|
| @@ -524,14 +559,37 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| return CreateTypeVariableList(klass);
|
| }
|
|
|
|
|
| +DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 1) {
|
| + GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| + AbstractType& type = AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| +
|
| + const AbstractTypeArguments& args =
|
| + AbstractTypeArguments::Handle(type.arguments());
|
| + if (args.IsNull()) {
|
| + return Object::empty_array().raw();
|
| + }
|
| +
|
| + const Array& result = Array::Handle(Array::New(args.Length()));
|
| + Instance& type_mirror = Instance::Handle();
|
| + for (intptr_t i = 0; i < args.Length(); i++) {
|
| + type ^= args.TypeAt(i);
|
| + type_mirror = CreateTypeMirror(type);
|
| + result.SetAt(i, type_mirror);
|
| + }
|
| + return result.raw();
|
| +}
|
| +
|
| +
|
| DEFINE_NATIVE_ENTRY(LocalTypeVariableMirror_owner, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
|
| - return CreateClassMirror(Class::Handle(param.parameterized_class()),
|
| + return CreateGenericClassMirror(Class::Handle(param.parameterized_class()),
|
| Instance::null_instance());
|
| }
|
|
|
| @@ -763,11 +821,7 @@ static void ThrowNoSuchMethod(const Class& klass,
|
| const Function& function,
|
| const InvocationMirror::Call call,
|
| const InvocationMirror::Type type) {
|
| - AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
|
| - Type& pre_type = Type::Handle(
|
| - Type::New(klass, type_arguments, Scanner::kDummyTokenIndex));
|
| - pre_type.SetIsFinalized();
|
| - AbstractType& runtime_type = AbstractType::Handle(pre_type.Canonicalize());
|
| + AbstractType& runtime_type = AbstractType::Handle(RawTypeOfClass(klass));
|
|
|
| ThrowNoSuchMethod(runtime_type,
|
| function_name,
|
| @@ -797,7 +851,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) {
|
| // because this native is an instance method in order to be polymorphic
|
| // with its cousins.
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| GET_NON_NULL_NATIVE_ARGUMENT(
|
| String, function_name, arguments->NativeArgAt(2));
|
| GET_NON_NULL_NATIVE_ARGUMENT(
|
| @@ -835,7 +891,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) {
|
| // because this native is an instance method in order to be polymorphic
|
| // with its cousins.
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
|
|
|
| // Note static fields do not have implicit getters.
|
| @@ -873,7 +931,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
|
| // because this native is an instance method in order to be polymorphic
|
| // with its cousins.
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
|
| GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
|
|
|
| @@ -924,7 +984,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
|
|
|
| DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 3) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& klass = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& klass = Class::Handle(type.type_class());
|
| GET_NON_NULL_NATIVE_ARGUMENT(
|
| String, constructor_name, arguments->NativeArgAt(1));
|
| GET_NON_NULL_NATIVE_ARGUMENT(
|
| @@ -1140,6 +1202,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
|
| }
|
|
|
|
|
| +
|
| DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| const Function& func = Function::Handle(ref.GetFunctionReferent());
|
| @@ -1151,7 +1214,7 @@ DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) {
|
| if (owner.IsTopLevel()) {
|
| return CreateLibraryMirror(Library::Handle(owner.library()));
|
| }
|
| - return CreateClassMirror(owner, Object::null_instance());
|
| + return CreateGenericClassMirror(owner, Object::null_instance());
|
| }
|
|
|
|
|
| @@ -1174,10 +1237,16 @@ DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 1) {
|
|
|
| DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
|
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
|
| - const Class& cls = Class::Handle(ref.GetClassReferent());
|
| + const AbstractType& type =
|
| + AbstractType::Handle(ref.GetAbstractTypeReferent());
|
| + const Class& cls = Class::Handle(type.type_class());
|
| const Function& sig_func = Function::Handle(cls.signature_function());
|
| const Class& sig_cls = Class::Handle(sig_func.signature_class());
|
| - return MirrorReference::New(sig_cls);
|
| +
|
| + // Possibly losing information here....
|
| + AbstractType& runtime_type = AbstractType::Handle(RawTypeOfClass(sig_cls));
|
| +
|
| + return MirrorReference::New(runtime_type);
|
| }
|
|
|
|
|
|
|