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

Unified Diff: runtime/lib/mirrors.cc

Issue 22292002: Reflection on generics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | tests/lib/mirrors/generics_test.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | tests/lib/mirrors/generics_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698